可用选项
对于不规则形状,您可以使用两种技术:
- 复合模式
- 剪裁
恕我直言,更好的选择是使用实际剪辑模式或复合模式destination-out
。
正如 markE 在他的回答xor
中所说的那样,也可以使用,但 xor 只会反转 alpha 像素并且不会删除 RGB 像素。这适用于没有透明度的实心图像,但是如果您有具有透明度的现有像素,这些可能会给您带来相反的效果(变得可见),或者如果您稍后使用 xor 模式并在顶部绘制其他东西,“剪辑”区域将再次显示。
剪裁
通过使用裁剪,您可以简单地使用clearRect
清除路径定义的区域。
例子:
/// save context for clipping
ctx.save();
/// create path
ctx.beginPath();
ctx.arc(x, y, radius, 0, 2 * Math.PI);
ctx.closePath();
/// set clipping mask based on shape
ctx.clip();
/// clear anything inside it
ctx.clearRect(0, 0, offset, offset);
/// remove clipping mask
ctx.restore();
剪裁在线演示
源图像:具有部分半透明像素和完全透明的图像,背景中的白色通过 -
结果:
我们在上面打了一个洞,背景显示出来:
复合模式:destination-out
使用复合模式destination-out
将像剪切一样清除像素:
ctx.beginPath();
ctx.arc(offset * 0.5, offset * 0.5, offset * 0.3, 0, 2 * Math.PI);
ctx.closePath();
/// set composite mode
ctx.globalCompositeOperation = 'destination-out';
ctx.fill();
/// reset composite mode to default
ctx.globalCompositeOperation = 'source-over';
复合模式在线演示:
结果:
与剪裁相同,因为destination-out
删除像素。
复合模式:异或
xor
在存在透明像素的情况下使用(请参见此处的在线示例):
只有 alpha 值被反转。由于我们没有实心像素,因此 alpha 不会从 255 变为 0 ( 255 - 255
),但255 - actual value
使用此模式会导致背景不清晰。
(如果您以相同的模式第二次绘制,“删除”的像素将被恢复,因此可以以其他方式使用)。