Canvas动画中矩形“越移越宽”是因为未清除上一帧画面;只需在每次重绘前调用 clearRect() 清空画布,即可实现位置更新而非叠加绘制。
Canvas动画中矩形“越移越宽”是因为未清除上一帧画面;只需在每次重绘前调用 `clearRect()` 清空画布,即可实现位置更新而非叠加绘制。
在使用 HTML5 `
` 进行图形动画时,一个常见误区是:仅调用 `fillRect()` 绘制新位置,却忽略了 Canvas 是**位图绘图环境**——它不会自动擦除历史内容,所有绘制操作都在同一像素层上累积。因此,当 `px` 增加而旧矩形未被清除时,视觉上就表现为“左侧固定、右侧不断延伸”的伪膨胀效果。
要实现真正意义上的平滑移动,必须遵循标准动画循环三步法:清空 → 更新 → 重绘。核心修复在于 move() 函数开头添加:
context.clearRect(0, 0, canvas.width, canvas.height);
该方法以指定矩形区域(此处覆盖整个画布)填充透明色,确保每一帧都从干净画布开始。完整修正后的代码如下:
let canvas = document.getElementById("canvas");let width = window.innerWidth;let height = window.innerHeight;let context = canvas.getContext("2d");let px = 0;let directx = { right: false, left: false };let speed = 6;// 设置画布尺寸与背景色canvas.style.backgroundColor = "red";canvas.width = width;canvas.height = height;document.addEventListener("keydown", startmove);function startmove(event) { if (event.key === "d") { directx.right = true; directx.left = false; } else if (event.key === "a") { directx.right = false; directx.left = true; }}function move() { // ✅ 关键步骤:清除整帧画布 context.clearRect(0, 0, canvas.width, canvas.height); // 绘制当前帧的正方形(位置由 px 控制) context.fillRect(px, 0, 100, 100); // 更新横坐标 if (directx.right) { px += speed; } else if (directx.left) { px -= speed; } requestAnimationFrame(move);}move();
⚠️ 注意事项:
掌握“清空-更新-重绘”这一范式,是构建任意 Canvas 动画(如角色移动、粒子系统、图表过渡)的基础前提。