HTML5 Canvas 的 globalCompositeOperation 是像素级裁剪+覆盖逻辑,非颜色混合;常用模式如 source-over、destination-in 等跨浏览器稳定,遮罩推荐 destination-in(显形)或 source-in(贴图),clip() 更轻量高效。

HTML5 Canvas 中的 globalCompositeOperation 不是“颜色混合”,而是像素级的**裁剪+覆盖逻辑**:它决定新绘制的内容在哪些位置显示、保留或清除,而不是像 Photoshop 那样计算 RGB 值。用对了,能实现遮罩、擦除、贴图裁剪、加色融合等效果;用错了,图直接消失或反向生效——问题往往出在主语(source vs destination)和绘制顺序上。
常用混合与遮罩模式怎么选
以下值跨浏览器支持稳定(Chrome/Firefox/Safari 均可用),适合生产环境:
- source-over:默认模式,新图形画在旧图形上方,日常绘制就用它
- destination-over:新图形画在旧图形下方,适合做底纹或背景层
- source-in:只在旧图形有不透明像素的区域显示新图形 → “把图装进旧形状里”(如图片扣进圆形路径)
- destination-in:只保留旧图形中与新图形重叠且不透明的部分 → “用新图形当蒙版抠旧图”(如文字形状露出底图)
- destination-out:擦除旧图形中与新图形重叠的不透明像素 → 真·橡皮擦,适合刮刮乐、镂空动画
- lighter:RGB 值相加,实现加色混合(光晕、粒子融合),所有主流浏览器都支持
-
multiply 和 screen:正片叠底、滤色效果可用,但
overlay、hard-light等高级模式在 Safari 中仍不支持
遮罩效果的两种可靠实现方式
遮罩不是靠 DOM 层叠,必须在同一 canvas 上先后绘制,并严格控制顺序:
-
destination-in(推荐用于“显形”类遮罩):先
drawImage(img, 0, 0)绘制原图,再设globalCompositeOperation = 'destination-in',接着绘制遮罩图形(如圆、文字、渐变矩形),最后fill()或stroke()。结果:只有遮罩图形覆盖的区域保留原图像素 -
source-in(推荐用于“贴图”类遮罩):先用
fill()或fillText()绘制一个不透明遮罩形状(比如实心圆),再设globalCompositeOperation = 'source-in',最后drawImage(img)。结果:图像只出现在遮罩形状内部 - 注意:如果遮罩图形本身是半透明(如抗锯齿边缘或低 alpha 填充),
source-in可能漏出边缘;此时建议改用clip()方案,更干净可控
关键操作细节别踩坑
- 该属性只对后续绘制操作生效,先画图再设它,完全没反应
-
clearRect()是画一个全透明黑色矩形,它不参与合成运算,也不会被destination-out擦除 - 路径必须调用
fill()或stroke()才真正成为“已有内容”,仅beginPath()+arc()不会起作用 - 使用
drawImage()时,遮罩图形和图像坐标要对齐,否则裁剪区域偏移 - 图像必须加载完成(监听
img.onload)再绘制,否则 canvas 显示空白 - 高 DPI 屏幕下,记得设置
canvas.width/canvas.height为物理像素尺寸,并用 CSS 缩放显示,避免模糊
比 globalCompositeOperation 更轻量的替代方案:clip()
如果遮罩形状固定(如圆、椭圆、SVG 路径),clip() 更高效、语义更清晰,且不受像素透明度影响:
立即学习“前端免费学习笔记(深入)”;
- 先
beginPath()+ 构建路径(arc()、rect()、lineTo()等) - 立即调用
clip()(此操作不可逆,后续所有绘图自动受限) - 再
drawImage()或fillRect(),图像天然被裁剪 - 如需恢复全画布绘制,用
ctx.save()/ctx.restore()包裹 clip 操作



















