Canvas 的 clip() 方法是实现复杂图形遮罩最直接、性能最好的方式,它限制绘图区域而不修改像素,需闭合路径、配合 save/restore 隔离作用域,并支持 fillRule 实现镂空等复合效果。

Canvas 的 clip() 方法是实现复杂图形遮罩最直接、性能最好的方式——它不修改像素,只限制绘图区域,且天然支持路径组合与填充规则控制。
必须闭合路径才能生效
clip 不会报错,但路径未闭合就调用,遮罩完全无效。常见错误包括:只画了三条边的矩形、arc 后没 closePath、lineTo 连线首尾不重合。
- 始终以
ctx.beginPath()开头,清空旧路径状态 - 用
rect()或arc()构建形状时,arc()自带闭合,rect()不需要closePath(),但自定义多边形必须显式调用 - 验证是否闭合:在 clip 前加一句
ctx.stroke(),看到完整轮廓才算成功
用 save/restore 隔离裁剪作用域
clip 是上下文状态的一部分,一旦设置,后续所有 drawImage、fillText、fillRect 都被限制——不隔离就会越画越小,甚至内容消失。
- 每次裁剪前必须
ctx.save() - 路径 → clip() → 绘图操作,全部写在 save 和 restore 之间
-
ctx.restore()会彻底清除本次裁剪,外部图层毫发无损
利用 fillRule 实现“挖空”类复合遮罩
单次 clip() 支持 "nonzero"(默认)和 "evenodd" 两种填充规则,后者能轻松做出镂空效果。
立即学习“前端免费学习笔记(深入)”;
- 大圆顺时针 + 小圆逆时针 →
clip("evenodd")→ 小圆区域自动被排除 - 多个子路径必须在同一次
beginPath()中定义,不能分两次 clip() - 例如做“环形头像”:先 arc 绘外圆(顺时针),再 arc 绘内圆(逆时针),最后统一 clip("evenodd")
结合实际场景的典型用法
clip 不是炫技工具,而是解决具体问题的底层能力:
- 不规则头像:圆形路径 + drawImage,一行裁剪,无需额外 canvas 或 CSS
- 渐变揭示动画:用 requestAnimationFrame 动态扩大裁剪圆半径,让内容从中心逐步浮现
- 仪表盘扇形进度:先用 moveTo/lineTo/arc 构建扇形路径并 clip,再 drawImage 或 fillText,确保文字严格落在扇形内
- 滚动列表视口:用矩形 clip 锁定可视区域,滚动时只重绘区域内内容,性能更可控



















