在 canvas 上绘制 rgba 颜色而不是透明绘制

Draw rgba colors on canvas instead of drawing transparently

有没有办法在 HTML canvas 上绘图,使生成的图像透明?

我知道您可以设置 globalAlpha,但这只会影响后续绘图操作的工作方式:设置 globalAlpha=.5,然后在红色上绘制黑色会导致深红色,而不是透明的黑色。

我知道你可以 canvas.fillStyle='rgba(0,0,0,0.5)',但同样,这只会影响绘图操作,不会影响绘制的颜色 (see this fiddle)。 我发现这非常违反直觉。

当我在 rgba(0, 0, 0, 0.5) 在 canvas 之前是红色的点绘制时,我希望 canvas 在那个点 是灰色并且透明。我想要这个的原因是我想上传图片并获得部分透明的图像。

有什么办法吗?

这就是 CanvasRenderingContext2Dcompositing operations 可能派上用场的地方。如果您想在纯红色形状上绘制一个透明的黑色形状,并使两个形状重叠的区域透明,'xor' 模式可能是最佳选择。

这是一个例子:

const canvas = document.getElementById('some_canvas');
const ctx = canvas.getContext('2d');
ctx.globalCompositeOperation = 'xor';
ctx.beginPath();
ctx.fillStyle = 'red';
ctx.arc(50, 50, 15, 0, 2 * Math.PI, true);
ctx.fill();
ctx.beginPath();
ctx.fillStyle = 'rgba(0,0,0,0.5)';
ctx.arc(60, 50, 10, 0, 2 * Math.PI, true);
ctx.fill();
<canvas id="some_canvas" width="100" height="100"></canvas>

最简单的可能是分两次绘制半透明部分:

  • 首先作为剪裁,使用不透明的 fillStyle,
  • 然后作为实际的油漆,使用半透明 fillStyle

我们不能做单通道,因为除了 "clear" 所有 composite modes 都考虑了 alpha 通道,所以通过使用半透明涂料应用这种合成,之前的绘图仍将是“半”可见的。

const canvas = document.getElementById('some_canvas');
const ctx = canvas.getContext('2d');

ctx.setTransform( 2, 0, 0, 2, -50, -50 );

ctx.beginPath();
ctx.arc(50,50,15,0, 2*Math.PI, true);
ctx.fillStyle='red';
ctx.fill();

ctx.beginPath();
ctx.arc(50,50,10,0, 2*Math.PI, true);
// first pass to clear behind the to-be-painted shape
// notice we keep the fillStyle opaque (the color doesn't matter)
ctx.globalCompositeOperation = "destination-out";
ctx.fill();
// second pass, the actual painting, with the desired color
ctx.globalCompositeOperation = "source-over";
ctx.fillStyle='rgba(0,0,0,0.5)';
ctx.fill();
/* CSS checkerboard stolen from https://drafts.csswg.org/css-images-4/#example-2de97f53 */
canvas {
    background: repeating-conic-gradient(rgba(0,0,0,0.1) 0deg 25%, white 0deg 50%);
    background-size: 2em 2em;
}
<canvas id="some_canvas" width="100" height="100"></canvas>