最新下载
热门教程
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
HTML怎么做canvas保存恢复_HTML canvas save restore状态新手必读
时间:2026-06-15 09:33:53 编辑:袖梨 来源:一聚教程网
save()和restore()保存/恢复绘图上下文状态而非像素,包括变换矩阵、裁剪路径、样式属性及合成模式;不保存已绘制图形、canvas尺寸和像素数据;栈空时调用restore()会抛DOMException。
save() 和 restore() 不是“撤销画了什么”,而是“还原怎么画”——它们只管绘图上下文的状态,不管已绘制的像素。用错地方或漏配对,轻则样式/变换错乱,重则抛出 DOMException: The operation is not supported。save() 和 restore() 保存/恢复哪些状态?
每次 save() 把当前所有可变绘图属性压栈,restore() 弹出并全量还原。具体包括:
- 变换矩阵(
translate()、rotate()、scale()、transform()累积效果) - 裁剪路径(
clip()设置的区域) - 样式属性:如
fillStyle、strokeStyle、globalAlpha、lineWidth、lineCap、font、textAlign、textBaseline、shadowOffsetX等 - 合成模式(
globalCompositeOperation)
不保存的内容必须明确记住:
- 已绘制的图形(
fillRect()、stroke()等产生的像素不会回退) -
canvas元素宽高、width/height属性值 - 像素数据(
getImageData()/putImageData()操作不受影响)
为什么 restore() 会报 DOMException?
状态栈为空时调用 restore() 就会触发该错误。常见原因有:
-
save()调用次数少于restore()(比如只调一次save(),却连续restore()三次) - 条件分支中漏写
save()或多写restore()(例如在 if 分支里 save,在 else 里没对应逻辑) - 异步回调中误用(
setTimeout里调restore(),但外层状态早已弹出)
Chrome/Firefox 的 Canvas Inspector 可实时查看当前栈深度,调试时建议打开验证是否匹配。
立即学习“前端免费学习笔记(深入)”;
嵌套 save/restore 的典型使用场景
模块化绘制组件最常用,比如封装一个带旋转和缩放的图标函数,内部自包含状态隔离:
function drawRotatedIcon(ctx, x, y, angle, scale) { ctx.save(); // 保存初始状态 ctx.translate(x, y); // 移动原点到图标中心 ctx.rotate(angle); ctx.scale(scale, scale); ctx.fillStyle = '#333'; ctx.fillRect(-10, -10, 20, 20); // 绘制图标主体 ctx.restore(); // 还原,不影响后续绘制}
这种写法的关键点:
- 每组
save()/restore()必须成对出现在同一作用域内 - 避免包裹单条命令(如
ctx.save(); ctx.fillRect(...); ctx.restore();),无意义且徒增开销 - 若需多次复用某组变换,优先考虑
setTransform(1,0,0,1,0,0)重置,比 restore 更轻量
容易被忽略的裁剪路径陷阱
clip() 是状态的一部分,但它的行为容易引发视觉困惑:
- 调用
clip()后再save(),恢复时裁剪区域也一并还原 - 但
clip()本身依赖当前路径(beginPath()→rect()→clip()),漏掉beginPath()会导致旧路径残留,裁剪范围异常 - 多次
clip()不叠加,而是用最新路径完全替换裁剪区域
安全写法示例:
ctx.save();ctx.beginPath();ctx.rect(50, 50, 100, 100);ctx.clip(); // 此后所有绘制仅在此区域内可见ctx.fillStyle = 'red';ctx.fillRect(0, 0, 200, 200); // 实际只显示右下角 50×50 区域ctx.restore(); // 裁剪失效,后续绘制恢复正常
真正复杂的地方在于:裁剪 + 变换 + 样式混合时,save() 的时机决定你“想固定哪一层”。多数人第一次踩坑,都是在 clip() 前忘了 save(),结果 restore 后裁剪还挂着。
相关文章
- 崩坏星穹铁道垃美西斯二世成就攻略 06-18
- Cursor模型选择要点:任务类型与上下文限制说明 06-18
- Cursor国内使用限制:网络、账号与功能可用性说明 06-18
- Cursor官网访问入口:域名、镜像站与网络环境说明 06-18
- 崩坏星穹铁道星旅寻影第二天拍照攻略 06-18
- Cursor免费替代方案:功能差异与使用限制说明 06-18