html5 canvas局部擦除与重绘的核心是精准脏区管理:标记变化区域、合并为最小矩形、用clearrect清除、分层绘制+离屏缓存静态背景,并跳过无效操作以提升性能。

HTML5 Canvas 实现局部区域擦除与重绘,核心是“只动该动的像素”——不全清、不重画、不闪屏。关键在于精准定位变化区域(脏区),用最轻量的方式清除它,再仅在该区域更新内容。
精准标记并合并脏区
每次图形状态变化(如移动、缩放、文字更新、橡皮擦经过),不要立刻绘制,而是计算它影响的最小矩形范围:
- 单个元素(如一个圆):根据中心点、半径、变换矩阵算出包围盒,例如圆从 (50,50) 移到 (80,60),半径 10 → 脏区为 (40,40) 到 (90,70)
- 多个变化:维护一个全局 dirtyRect = {x, y, width, height},每次调用 markDirty(x, y, w, h),用 Math.min/max 合并成一个联合矩形
- 坐标统一做 Math.floor() 对齐,避免 sub-pixel 清除导致抗锯齿异常
用 clearRect 精确擦除脏区
这是最高效、最可控的擦除方式,比 fillRect 填白或重绘背景快得多:
- 执行 ctx.clearRect(dirtyRect.x, dirtyRect.y, dirtyRect.width, dirtyRect.height)
- 切忌用
clearRect(0,0,w,h)全清后再重画——纯属浪费 GPU 填充资源 - 若脏区内含阴影、半透明叠加,
clearRect可能破坏混合效果,此时应切换为离屏缓存+合成策略
分层绘制 + 离屏缓存静态背景
把不变内容和动态内容物理隔离,让局部刷新真正“局部”:
- 创建一个离屏 canvas:const offscreen = document.createElement('canvas'),尺寸同主画布
- 首次将网格、底图、UI 边框等静态内容绘入 offscreen
- 每帧重绘前:ctx.drawImage(offscreen, dirtyRect.x, dirtyRect.y, dirtyRect.width, dirtyRect.height, dirtyRect.x, dirtyRect.y, dirtyRect.width, dirtyRect.height) —— 把对应区域背景贴回来
- 再在该区域上绘制最新动态图形(如移动的图标、更新的文字)
跳过无效操作提升响应效率
不是所有“变化”都值得重绘,加一层轻量判断可显著减少冗余操作:
- 脏区完全在画布可视区域外(
x + w = width || y >= height)→ 直接跳过整帧 - 对文本、路径等对象缓存上一帧的结构快照(如
{text, font, x, y, fillStyle}),JSON.stringify 比对无变化则不标记脏区 - 动画中位移增量小于 0.5px 且无旋转/缩放 → 忽略本次更新,防抖式节流
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











