Canvas 合成与透明度:globalAlpha 与 globalCompositeOperation 常见用法

在很多稍微复杂一点的 Canvas 场景里,单纯的画图已经不够用了:需要半透明叠加、擦除效果、剪切蒙版、光影叠加等。
这一篇聚焦两块核心能力:全局透明度 globalAlpha 和合成操作 globalCompositeOperation,以及它们在实际项目中的典型用法与注意事项。

globalAlpha 是 Canvas 上下文的一个状态属性,用于控制后续所有绘制的透明度:

  • 范围为 0.0(完全透明)到 1.0(完全不透明);
  • 会叠加在已有的颜色透明度上。

示例:

1ctx.globalAlpha = 0.5;
2ctx.fillStyle = "#ff0000";
3ctx.fillRect(10, 10, 100, 100);

常见用法包括:

  • 渐隐/渐现动画(通过逐帧调整 globalAlpha);
  • 整体降低某一层绘制的存在感(比如背景层、禁用态)。

需要注意:

  • globalAlpha 会影响后续所有绘制,使用完记得恢复(配合 save / restore);
  • 和单个颜色的 alpha 通道叠加后效果有乘积关系。

globalCompositeOperation 决定了新绘制内容与画布上已有内容的合成方式。
可以把它理解为「源(source)」与「目标(destination)」之间的合成规则。

常见值可以分为几类:

  • 覆盖/覆盖相关
    • "source-over"(默认):新内容覆盖在旧内容上;
    • "destination-over":旧内容覆盖在新内容上。
  • 保留交集/差集
    • "source-in":仅保留新内容与旧内容相交部分,新内容之外都透明;
    • "source-out":仅保留新内容中与旧内容不相交部分;
    • "destination-in" / "destination-out":以旧内容为主体的类似操作。
  • 加减混合(如光效)
    • "lighter":颜色值相加,适合做发光叠加效果;
    • 其他如 "multiply""screen" 等在部分环境中也可用。

在工程实践中,常见用法集中在几类场景。

一个经典例子是实现「橡皮擦」效果:

  • 在已有图像上,用某种路径「擦除」一部分内容。

可以通过设置:

1ctx.save();
2ctx.globalCompositeOperation = "destination-out";
3
4// 在这里绘制擦除路径,例如一条线或一个圆形
5ctx.beginPath();
6ctx.arc(x, y, radius, 0, Math.PI * 2);
7ctx.fill();
8
9ctx.restore();

含义是:

  • 以现有画布内容为「目标」;
  • 把新绘制的区域从目标中「挖掉」。

这一招在:

  • 刮刮乐效果;
  • 局部清除遮罩层;
  • 实现简单的图像抠图交互中非常常见。

蒙版(mask)效果的目标是:

  • 只在某个特定形状区域内显示内容,其余部分透明。

一种实现方式是:

  1. 先绘制遮罩形状(比如一个圆或复杂路径);
  2. 设置合成模式;
  3. 再绘制实际内容。

例如:

 1// 1. 绘制遮罩形状
 2ctx.save();
 3ctx.beginPath();
 4ctx.arc(cx, cy, r, 0, Math.PI * 2);
 5ctx.fill();
 6
 7// 2. 设置 source-in,让后续绘制只保留在已有形状区域内
 8ctx.globalCompositeOperation = "source-in";
 9
10// 3. 绘制内容(图片/图案)
11ctx.drawImage(image, x, y, w, h);
12
13ctx.restore();

效果是:

  • 图片只会出现在圆形区域内,其他部分透明;
  • 可以用来做圆形头像、图标裁剪、局部高亮等。

在需要模拟简单光效(例如粒子发光、光晕叠加)时,可以用:

1ctx.globalCompositeOperation = "lighter";

在这种模式下:

  • 每次绘制的颜色会与目标颜色相加;
  • 叠加多次会越来越亮,接近「发光」效果。

配合:

  • 半透明渐变圆形;
  • 多个粒子在同一区域重叠;

可以快速实现还不错的视觉效果。

需要注意:

  • 使用 lighter 时要小心整体亮度过高;
  • 在性能敏感场景中,适当控制粒子数量和绘制频率。

在实际项目中,使用 globalAlphaglobalCompositeOperation 时需要注意:

  • 始终配合 save / restore 使用:
    • 这样局部调整不会影响全局绘制;
    • 可以避免忘记重置导致后续绘制行为异常。
  • 把常用效果封装为函数:
    • eraseCircle(ctx, x, y, radius)drawMaskedImage(ctx, maskFn, drawFn)
    • 内部负责设置合成模式和恢复状态,对调用方暴露更直观的接口。
  • 尽量在离屏 Canvas 中做复杂合成:
    • 可以减少主画布重绘开销;
    • 也在逻辑结构上把「图层」和「效果」分离开。

可以把这一篇的要点压缩为:

  • globalAlpha 提供了对整体透明度的统一控制,是渐隐、淡出和层次弱化的基础手段;
  • globalCompositeOperation 决定了新旧内容如何混合,擦除(destination-out)、蒙版(source-in)和光效叠加(lighter)是几个最实用的模式;
  • 在工程实践中,通过状态栈和离屏 Canvas,把这些效果封装成可复用函数,可以在不增加太多复杂度的前提下,大幅提升 Canvas 表达力。

掌握这些合成技巧之后,Canvas 不再只是「画在白纸上的图形」,而是可以像图像编辑软件那样,对不同层的内容做巧妙的混合与遮罩。