可用选项
对于不规则形状,您可以使用两种技术:
- 复合模式
- 剪辑
在我看来,更好的选择是使用实际的剪辑模式或复合模式 destination-out
。
正如markE在他的答案中所说,xor
也是可用的,但是xor仅反转alpha像素,而不删除RGB像素。这适用于没有透明度的实心图像,但是如果您有现有的带有透明度的像素,则可能会产生相反的效果(变得可见),或者如果您稍后使用xor模式与其他内容一起绘制,则“剪辑”区域将再次显示。
剪辑
通过使用剪辑,您可以简单地使用clearRect
来清除路径定义的区域。
示例:
ctx.save();
ctx.beginPath();
ctx.arc(x, y, radius, 0, 2 * Math.PI);
ctx.closePath();
ctx.clip();
ctx.clearRect(0, 0, offset, offset);
ctx.restore();
剪辑在线演示
源图像:一张具有部分半透明像素和完全透明的图像,其中白色背景透过来 -
![Source image](https://istack.dev59.com/EiuHB.webp)
结果:
我们在其中打了一个洞,背景透过来显示出来:
![clipping](https://istack.dev59.com/06qss.webp)
复合模式:目标-出
使用复合模式目标-出
将像剪辑一样清除像素:
ctx.beginPath();
ctx.arc(offset * 0.5, offset * 0.5, offset * 0.3, 0, 2 * Math.PI);
ctx.closePath();
ctx.globalCompositeOperation = 'destination-out';
ctx.fill();
ctx.globalCompositeOperation = 'source-over';
复合模式在线演示:
结果:
![destination out](https://istack.dev59.com/06qss.webp)
与剪切相同,destination-out
会移除像素。
复合模式:异或
在存在透明像素的情况下使用xor
(在此在线示例中查看):
![xor mode](https://istack.dev59.com/k8LZf.webp)
只有 alpha 值被反转了。由于我们没有实心像素,alpha 不会从 255 变为 0 (255 - 255
),而是 255 - 实际值
,这将导致使用此模式时背景未被清除。
(如果您使用相同的模式再次绘制,则“删除”的像素将被恢复,因此可以以其他方式利用它们)。