Canvas遮罩靠globalCompositeOperation顺序控制,SVG用语义化实现,CSS用clip-path轻量动态处理,WebGL需Shader或贴图替代;选错技术层级则无效。

HTML5 Canvas 中用 globalCompositeOperation 做遮罩
Canvas 本身不提供“遮罩层”概念,但可以通过 globalCompositeOperation 控制绘制顺序与混合模式,模拟遮罩效果。关键不是“加一层”,而是“让后续绘制只在指定形状内生效”。
常见错误是直接用两个 drawImage 叠加,结果发现第二张图铺满全画布——没设置合成模式就等于没遮罩。
-
ctx.globalCompositeOperation = 'destination-in':只保留目标(已有内容)与新绘制图形重叠的部分,其余透明化(最常用) -
'source-atop':只在已有非透明区域上绘制新内容(适合文字遮罩图片) - 必须先绘制“遮罩形状”(如圆形、路径),再绘制“被遮内容”,顺序反了就失效
- 操作完记得重置:
ctx.globalCompositeOperation = 'source-over',否则影响后续绘制
ctx.beginPath(); ctx.arc(100, 100, 50, 0, Math.PI * 2); ctx.fill(); // 遮罩形状(实心圆)ctx.globalCompositeOperation = 'destination-in'; ctx.drawImage(img, 0, 0); // 图片只显示在圆内
ctx.globalCompositeOperation = 'source-over';
SVG 中用 实现真正语义化遮罩
SVG 的 是原生支持的遮罩机制,比 Canvas 更直观、可缩放、支持 CSS 动画,且对高 DPI 屏幕友好。
立即学习“前端免费学习笔记(深入)”;
容易踩的坑是忽略 maskUnits="userSpaceOnUse" 和坐标系匹配问题——遮罩区域默认以“对象边界盒”为单位,若没显式设宽高或坐标偏移,遮罩可能错位或只盖住左上角一小块。
- 黑色像素 = 完全透明,白色 = 完全不透明,灰色 = 半透明(Alpha 映射)
-
必须定义在内,通过mask="url(#myMask)"引用 - 动画遮罩时,直接对
内的元素(如)加transform或animate即可,无需重绘
CSS + HTML 元素实现轻量级动态遮罩(无 Canvas/SVG)
如果只是做页面局部淡入、滑动遮罩、焦点高亮等效果,纯 CSS 就够用,性能更好、更易维护。核心是利用 clip-path 或 overflow + transform 组合控制可见区域。
注意:旧版 Safari 对 clip-path 的 inset() 和复杂路径支持不稳定,移动端务必测试;overflow: hidden 配合 transform 虽兼容性好,但无法实现圆角/渐变边缘。
-
clip-path: inset(0 0 0 50%)可实现从右向左的滑入遮罩 - 配合
transition: clip-path 0.4s ease实现平滑变化 - 用
background-clip: text+-webkit-text-fill-color: transparent可做文字遮罩图片(需 -webkit 前缀)
.masked {
background: url(photo.jpg);
clip-path: polygon(0 0, 100% 0, 100% 100%, 0 100%);
transition: clip-path 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
}
.masked.active {
clip-path: polygon(0 0, 100% 0, 100% 100%, 0 100%);
}WebGL(Three.js)中遮罩的绕行方案
Three.js 没有内置遮罩 API,强行用 StencilBuffer 实现门槛高、易出错。实际项目中更推荐“视觉替代”:用带 Alpha 通道的贴图控制材质透明度,或用自定义 Shader 读取遮罩纹理的 R/G/B/A 值作为 opacity 输入。
最容易被忽略的是纹理采样坐标(UV)对齐问题——遮罩图和主图 UV 不一致会导致遮罩漂移。建议统一用同一组 UV,并在 Shader 中用 vUv 同步采样。
- 避免在
onBeforeCompile中硬编码遮罩逻辑,优先封装为可复用的ShaderMaterial - 若遮罩需动画,不要每帧重载纹理,改用
uniform传入时间或偏移量,在 Shader 中计算动态 UV - 移动端 WebGL 2.0 支持度仍有限,
stencil方案慎用
遮罩不是特效开关,而是渲染流程中的一个约束条件。Canvas 看顺序,SVG 看定义,CSS 看盒子,WebGL 看数据流——选错层级,再调参数也白搭。











