Canvas动画路径代码报错:fill方法传入无效CanvasFillRule值
问题原因及修复方案
核心问题:变量名冲突 + fill方法参数错误
报错的直接原因是变量名重复导致参数传错:
- 你定义了全局的Path2D对象
const r = new Path2D(),同时在color函数里把第三个参数命名为r,这个参数实际接收的是R(x,y,time)返回的RGB数值(比如256) - Canvas的
context.fill()方法只接受两种参数:Path2D对象,或者填充规则字符串("nonzero"/"evenodd"),传入数字自然会触发枚举值无效的错误
另外代码还有两个逻辑问题:
- 定义的Path2D路径尺寸(800x400)远大于canvas的实际尺寸(32x32),完全无法显示
- 原动画循环遍历x/y,但没有对应到canvas的绘制逻辑,只是传递RGB值,没有实际绘制对应区域
修复后的完整代码
HTML
<canvas id="canvas"></canvas>
CSS
body { height: 400px; width: 500px; margin: 0; } canvas { width: 100%; height: 100%; }
JavaScript
const canvas = document.getElementById('canvas'); // 同步canvas实际宽高和CSS显示尺寸,避免拉伸模糊 canvas.width = canvas.offsetWidth; canvas.height = canvas.offsetHeight; const context = canvas.getContext('2d'); // 重命名Path2D变量,避免和color函数参数冲突 const shapePath = new Path2D(); shapePath.moveTo(0, 0); shapePath.lineTo(canvas.width, 0); shapePath.lineTo(canvas.width, canvas.height/2); shapePath.lineTo(0, canvas.height); shapePath.closePath(); let time = 0; // 填充自定义路径的函数 const fillShapeWithColor = function (path, r, g, b) { context.fillStyle = `rgb(${r}, ${g}, ${b})`; context.fill(path); } // 像素块渐变动画的函数(对应参考的渐变效果) /* const drawPixelBlock = function (x, y, blockSize, r, g, b) { context.fillStyle = `rgb(${r}, ${g}, ${b})`; context.fillRect(x*blockSize, y*blockSize, blockSize, blockSize); } */ const R = function (x, y, time) { return Math.floor(191 + 64 * Math.cos((x * x - y * y) / 300 + time)); } const G = function (x, y, time) { return Math.floor(191 + 64 * Math.sin((x * x * Math.cos(time / 4) + y * y * Math.sin(time / 3)) / 300)); } const B = function (x, y, time) { return Math.floor(191 + 64 * Math.sin(5 * Math.sin(time / 9) + ((x - 100) * (x - 100) + (y - 100) * (y - 100)) / 1100)); } const startAnimation = function () { // 每一帧先清空画布 context.clearRect(0, 0, canvas.width, canvas.height); // 方案1:填充自定义路径,随时间变化颜色 const r = R(canvas.width/2, canvas.height/2, time); const g = G(canvas.width/2, canvas.height/2, time); const b = B(canvas.width/2, canvas.height/2, time); fillShapeWithColor(shapePath, r, g, b); // 方案2:实现像素块渐变动画(取消注释即可使用) /* const blockSize = 10; const cols = Math.floor(canvas.width / blockSize); const rows = Math.floor(canvas.height / blockSize); for (let x = 0; x < cols; x++) { for (let y = 0; y < rows; y++) { const r = R(x, y, time); const g = G(x, y, time); const b = B(x, y, time); drawPixelBlock(x, y, blockSize, r, g, b); } } */ time += 0.03; window.requestAnimationFrame(startAnimation); } startAnimation();
关键修复点说明
- 变量名重命名:把全局Path2D对象从
r改为shapePath,避免和RGB参数冲突 - Canvas尺寸同步:设置canvas的
width和height等于其CSS显示尺寸,解决图形拉伸模糊问题 - 明确绘制逻辑:提供两种绘制方案,分别对应「自定义路径填充」和「像素块渐变动画」场景
- 清空画布:每一帧动画开始前用
clearRect清空画布,避免帧叠加导致的画面混乱
内容的提问来源于stack exchange,提问作者DbSchema
相关产品推荐
相关产品推荐

