clearRect()仅清除指定区域像素为透明黑色,不重置绘图状态;高频动画应清“脏矩形”而非全屏,避免掉帧;需注意坐标系变换、像素尺寸与CSS尺寸区别,及分层优化策略。

直接清整个画布,用 ctx.clearRect(0, 0, canvas.width, canvas.height) 最快最稳;但高频动画里硬清全屏,大概率掉帧。
clearRect() 清的是像素,不是“重置画布”
clearRect() 不会改变 canvas.width 或 canvas.height,也不重置绘图状态(比如 globalAlpha、strokeStyle、当前 transform)。它只把指定矩形区域所有像素设为透明黑色(rgba(0,0,0,0)),相当于“擦掉”那一块——底下页面背景可能就露出来了。
- 如果想彻底清空并重置所有状态(包括缩放、裁剪、样式),得手动调用
ctx.setTransform(1, 0, 0, 1, 0, 0)+ctx.resetTransform()(部分浏览器支持)+ 显式重设 fillStyle/strokeStyle 等 - 传入的
width和height必须是canvas.width/canvas.height像素值,不是 CSS 设置的宽高;否则清除区域错位或不完整 - 若之前用了
ctx.scale(2, 2),再调clearRect(10, 10, 50, 30),实际清除的是变换后坐标系下的区域——容易误判尺寸,建议先ctx.setTransform(1, 0, 0, 1, 0, 0)
动画中别无脑清全屏:只清“脏矩形”
1920×1080 屏幕上调 clearRect(0, 0, canvas.width, canvas.height),每帧要操作两百万像素。高 DPI 设备(如 MacBook Retina)更夸张,极易卡顿。
实现 Markdown↔ HTML 互转,支持导出 PDF,用于用户请求的文档格式转换。
- 记录上一帧动画元素的坐标和尺寸,比如小球旧位置是
{x: 100, y: 80, w: 20, h: 20},新位置是{x: 105, y: 82, w: 20, h: 20},那就清两个矩形,或取并集:clearRect(100, 80, 25, 22) - 静态内容(背景、UI 文字)不要参与清除,提前画到离屏
上,本帧直接drawImage() - 分层绘制时,主体动画层用 dirty rect 清除;UI 层每个组件自己管自己的清除范围;粒子特效层可不用
clearRect(),改用globalCompositeOperation = 'lighter'让旧帧自然叠加淡出
clearRect() vs 重设 width 属性 vs fillRect(rgba(0,0,0,0))
三者都能让画面“看起来空了”,但机制和副作用完全不同:
-
ctx.clearRect(0, 0, canvas.width, canvas.height):最快、最轻量,仅清像素,保留所有上下文状态 -
canvas.width = canvas.width:强制重建缓冲区,清空一切(包括所有绘图状态、路径、图像数据),但会触发 layout,且在某些浏览器中可能造成短暂闪烁 -
ctx.fillStyle = 'rgba(0,0,0,0)'; ctx.fillRect(0, 0, canvas.width, canvas.height):本质是绘制,受当前 globalAlpha、transform 影响,且比clearRect()慢;适合需要保留状态但又想用背景色覆盖的特殊场景
真正难的不是调用 clearRect(),而是判断“该清哪一块”。坐标算错、没重置 transform、把 CSS 宽高当像素用——这些细节一错,清的就不是你想清的地方。动画掉帧往往不是性能差,而是清除逻辑本身出了偏差。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










