You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Canvas动画路径代码报错:fill方法传入无效CanvasFillRule值

问题原因及修复方案

核心问题:变量名冲突 + fill方法参数错误

报错的直接原因是变量名重复导致参数传错:

  • 你定义了全局的Path2D对象const r = new Path2D(),同时在color函数里把第三个参数命名为r,这个参数实际接收的是R(x,y,time)返回的RGB数值(比如256)
  • Canvas的context.fill()方法只接受两种参数:Path2D对象,或者填充规则字符串("nonzero"/"evenodd"),传入数字自然会触发枚举值无效的错误

另外代码还有两个逻辑问题:

  1. 定义的Path2D路径尺寸(800x400)远大于canvas的实际尺寸(32x32),完全无法显示
  2. 原动画循环遍历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();

关键修复点说明

  1. 变量名重命名:把全局Path2D对象从r改为shapePath,避免和RGB参数冲突
  2. Canvas尺寸同步:设置canvas的width和height等于其CSS显示尺寸,解决图形拉伸模糊问题
  3. 明确绘制逻辑:提供两种绘制方案,分别对应「自定义路径填充」和「像素块渐变动画」场景
  4. 清空画布:每一帧动画开始前用clearRect清空画布,避免帧叠加导致的画面混乱

内容的提问来源于stack exchange,提问作者DbSchema

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 15:18:14