12.10 HTML 画布元素合成

将多个可视化元素组合成为一个可视化元素

简单来说,合成就是将多个可视化元素组合成为一个可视化元素。它广泛应用于各行各业,以图形设计到好莱坞电影制作。

在画布中绘制的所有东西都是已经合成的,这意味着绘制的所有内容都会与已经绘制的现有元素合并在一起.这实际上都是基本合成,只是将一些内容叠加到另一些内容之上。现在我们先了解一下画布中最简单的合成方法,即globalAlpha属性。

注意:本节将介绍的两个全局合成属性都会影响到2D渲染上下文的绘图效果,一定要明确一点,那就是修改全局合成属性会影响到修改之后所绘制的全部内容。

全局阿尔法值

在画布上进行绘图之前,它会应用一个与globalAlpha属性相匹配的阿尔法值。赋给globalAlpha的值必须在0.0(全透明)与1.0(不透明)之间,默认值是1.0。简单地说,globalAlpha属性会影响将要绘制的对象的透明度。例如,可以按照以下方式绘制一个半透明的正方形:

context.fillStyle = "rgb(63, 169, 245)"; 
    context.fillRect(50, 50, 100, 100);
    context.globalAlpha = 0.5;
    context.fillStyle = "rgb(255, 123, 172)";
    context.fillRect(100, 100, 100, 100); 

由于我们是在绘制了蓝色正方形后才设置globalAlpha属性的,所以只有粉红色正方形才会受到阿尔法值的影响。结果是后面蓝色正方形的一小块稍稍透过前面的粉红色正方形显示出来(参见例1)。

设置globalAlpha属性

现在,通过给fillStyle设置一个包含小于1的阿尔法值的rgba值,也可以得到相同的效果。不同之处是,globalAlpha设置的是全局阿尔法值,这个值会在后续应用rgba颜色值等阿尔法值时被参照。 例如,如果globalAlpha为0.5,你又应用了一次fillstyle(它带有一个阿尔法值为0.5的rgba),那么结果的阿尔法值实际上就是0.25。2D渲染上下文的全局阿尔法值(0.5)充当了计算其他阿尔法值的基数(0.5*0.5=0.25)。

合成操作

即使全新的2D渲染上下文也会在一开始就使用合成。你可能没有注意到这一点,因为此时使用的合成方法能得到你预期的结果:一个图形叠加到另一图形之上。 这种合成称为源覆盖于目标之上(source over destination),源是绘制的新图形,而目标则是可能已经绘制了图形的2D渲染上下文。我们知道,这是因为2D渲染上下文的globalCompositeOperation属性的默认值是source-over,并且这个属性定义了对2D渲染上下文上所有绘制图形执行的合成类型(11种可选方法之一)。 必须指出的是,根据赋值顺序的不同,globalCompositeOperation的所有值可能会涉及源或目标的其中一个(取决于顺序),而不会同时涉及两者。例如,“source-over”是(源覆盖于目标之上)的简称;目标是隐含的,因为它不需要在值中指定(源必须绘制在某些东西之上)。

让我们先了解一下globalCompositeOperation支持的11种选择。使用下面的代码作为模板,你可以学习每一种合成操作。其中蓝色正方形是目标,而粉红色正方形是源。我们只使用蓝色和粉红色而不使用其他颜色的原因是它们能够更好地显示合成操作的效果:

context.fillStyle = "rgb(63, 169, 245)"; 
context.fillRect(50, 50, 100, 100);
context.globalCompositeOperation = "source-over"; 
context.fillStyle = "rgb(255, 123, 172)"; 
context.fillRect(100, 100, 100, 100); 

我们制作了完整的在线实例,用来演示globalCompositeOperation的各种取值效果,然后我们对照这些例子来逐个说明参数的含义。

1.source-over
这是默认值,它表示绘制的图形(源)将画在现有画布(目标)之上,效果与目前学习到的绘图效果是完全相同的(参见例2)。
2.deatination-over
这个操作的值与前一个值相反,所以现在目标绘制在源之上。 效果与前一个操作恰好相反(参见例3)。
3.source-atop
这个操作会将源绘制在目标之上,但是在重叠区域上两者都是不透明的。绘制在其他位置的目标是不透明的,但源是透明的(参见例4)
4.destination-atop
这个操作与source-atop相反,目标绘制在源之上,其中在重叠区域上两者都是不透明的,但绘制在其他位置的源是不透明的,而目标变成透明的(参见例5)。
5.source-in
在源与目标重叠的区域只绘制源。而不重叠的部分都变成透明的(参见例6)
6.destination-in
这个操作与source-in相反,在源与目标重叠的区域保留目标.而不重叠的部分都变成透明的(参见例7)。
7.source-out
在与目标不重叠的区域上绘制源.其他部分都变成透明的(参见例8)。
8.destination-out
在与源不重叠的区域上保留目标。其他部分都变成透明的(参见例9)。
9.lighter
这个值与顺序无关,如果源与目标重叠,就将两者的颜色值相加。得到的颜色值的最大取值为255,结果就是白色(参见例10)。
10.copy
这个值与顺序无关,只绘制源,覆盖掉目标(参见例11)。
11.xor(异或)
这个值与顺序无关,只绘制出不重叠的源与目标区域。所有重叠的部分都变成透明的(参见例12)。

总之,这些合成操作使你能够在需要绘制一些复杂图形的情况下实现一些有趣的效果。有一些操作(如“destination-out")在擦除画布上一些非矩形区域时是很有用的,例如,使用圆作为源。