Canvas 的 clip() 方法建立动态遮罩而非擦除内容,需闭合路径、配合 save/restore 管理状态,并支持 nonzero/evenodd 规则实现复合遮罩,适用于头像裁剪、渐变揭示等场景。
Canvas 的 clip() 方法不是“擦掉”画布内容,而是建立一个动态遮罩——后续所有绘图只在路径定义的区域内可见,外部像素完全不受干扰。用好它,关键在于理解路径构建、裁剪锁定与状态管理三者的配合。
调用 clip() 前必须已完成路径定义,且该路径需闭合,否则裁剪无效。浏览器不会报错,但也不会产生遮罩效果。
ctx.beginPath(),再用 rect()、arc()、lineTo() 等方法绘制;closePath() 或确保首尾点重合(如 arc 自带闭合);clip(),例如只画了三条边的矩形却忘了 closePath()。clip 是上下文状态的一部分,一旦设置,会影响之后所有绘制操作,直到显式恢复。不加控制会导致越画越小、内容莫名消失。
ctx.save(),保存当前全部状态(含裁剪路径、颜色、字体等);save() 和 restore() 之间;ctx.restore() 会彻底清空本次裁剪,外部图层保持原样,无残留影响。单次 clip() 可接受 "nonzero"(默认)或 "evenodd" 参数,用于控制复杂路径的填充逻辑,实现“挖空”等效果。
nonzero:按路径方向计算环绕数,适合常规遮罩;evenodd:奇偶判断,常用于镂空设计——比如顺时针画大圆、逆时针画小圆,再用 clip("evenodd"),小圆区域自动被排除;beginPath() 中定义,不能分两次 clip(),否则后一次会覆盖前一次。clip 不是装饰性技巧,而是性能与表现兼顾的底层能力,适用于图像蒙版、局部动画、不规则 UI 元素等真实需求。
drawImage(),自然得到圆形头像,无需额外 canvas 或 CSS;translate() 或 scale()),路径坐标需对应当前上下文。