clearRect() 参数必须用 canvas.width 和 canvas.height 而非 style.width,且清除前需重置 transform 和 clip 状态,否则清除区域错位或无效;清除非矩形区域应使用 clip 或 destination-out 模式。

clearRect() 参数必须用 canvas.width 而不是 style.width
清除失效最常见的原因是把 CSS 缩放尺寸当成了绘图尺寸。canvas.style.width 可能是 400px,但 canvas.width 默认仍是 300——clearRect(0, 0, canvas.style.width, canvas.style.height) 会传入字符串或 undefined,导致清除区域错位或为空。
正确做法只认 canvas 元素自身的 width 和 height 属性:
- 初始化时显式设置:
<canvas width="800" height="600"></canvas> - JS 中始终用
canvas.width和canvas.height作为clearRect()的后两个参数 - 若需响应式,用 JS 动态同步:
canvas.width = canvas.clientWidth; canvas.height = canvas.clientHeight;(注意:这会重置状态)
清空前不重置 transform 或 clip 会导致清除偏移
如果你调过 ctx.translate(100, 50) 或 ctx.clip(),再执行 clearRect(0, 0, canvas.width, canvas.height),清除区域会跟着被平移或裁剪——看起来像“清不干净”。
安全做法是在 clearRect() 前主动恢复上下文状态:
立即学习“前端免费学习笔记(深入)”;
- 重置变换:
ctx.setTransform(1, 0, 0, 1, 0, 0) - 清除裁剪:
ctx.restore()(前提是之前save()过),或现代浏览器可用ctx.resetClip() - 更稳妥的顺序:
ctx.setTransform(...); ctx.clearRect(...);,再开始新绘制
重设 canvas.width 是清空,但会丢掉所有绘图状态
canvas.width = canvas.width 确实能清空,但它会重建整个位图缓冲区,连带重置 fillStyle、strokeStyle、font、lineWidth、当前 transform 等全部状态。
除非你明确需要“硬重启”,否则不推荐:
- 高频绘制中反复重设宽高,性能比
clearRect()差一个数量级 - 后续绘制必须重新设置所有样式,容易漏配导致颜色/粗细异常
- 如果只清局部区域,这种做法完全偏离目标
清除非矩形区域要用 clip 或 destination-out
clearRect() 只能清矩形。要擦除圆形、多边形或手绘路径区域,得借助其他机制:
- 用
clip()配合全量clearRect():ctx.save(); ctx.beginPath(); ctx.arc(x,y,r,0,PI*2); ctx.clip(); ctx.clearRect(0,0,canvas.width,canvas.height); ctx.restore(); - 用
globalCompositeOperation = "destination-out"绘制透明形状,直接“挖掉”像素(注意:它会影响后续绘制,记得切回"source-over") - 避免用
fillRect()填"rgba(0,0,0,0)"模拟清除——它本质是绘制,不是擦除,叠加多次可能有渲染偏差
transform 和 clip 状态的检查。哪怕你没主动调用过,第三方库或之前逻辑可能已修改过上下文,直接 clearRect() 就会出人意料。



















