canvas 高级功能(中)

canvas 高级功能(中)

在本文中,你将学习到 Canvas 提供的一些更高级的功能。本文将讲述如何合成、创建阴影使图形看起来更真实有趣。本文内容非常精彩,我希望这些内容能够拓宽你的眼界,帮助你学会画布的高级功能。

1. 合成

canvas 高级功能(中)确实包括许多内容,祝贺你学完了这些知识。在这一节中,我们将学习一些较为轻松的内容——合成,它们不复杂,而且还很有趣。简而言之,组合就是将多个可视化元素组合成为一个可视化元素。
在画布中绘制的所有东西都是已经合成的,这意味着绘制的所有内容都会与已经绘制的现有元素合并在一起。这实际上都是基本合成,只是将一些内容叠加到另一些内容之上。我马上要介绍这些方面的合成,但是现在我们先了解一下画布中最简单的合成方法,即globalAlpha属性。

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

1.1 全局阿尔法值

在画布上进行绘图之前,它会应用一个与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属性的,所以只有粉红色正方形才会受到阿尔法值的影响。结果是后面蓝色正方形的一小块稍稍透过前面的粉红色正方形显示出来。
image.png
现在,通过给fillStyle设置一个包含小于1的阿尔法值的rgba值,也可以得到相同的效果。不同之处是,globalAlpha设置的是全局阿尔法值,这个值会在后续应用rgba颜色值等阿尔法值时被参照。例如,如果globalAlpha0.5,你又应用了一次fillstyle(它带有一个阿尔法值为0.5rgba),那么结果的阿尔法值实际上就是0.25。2D渲染上下文的全局阿尔法值(0.5)充当了计算其他阿尔法值的基数(0.5*0.5=0.25)。

1.2 合成操作

正如本节开头介绍的,即使全新的2D谊染上下文也会在一开始就使用合成。你可能没有注意到这一点,因为此时使用的合成方法能得到你预期的结果:一个图形叠加到另一图形之上。这种合成称为源覆盖于目标之上,源是绘制的新图形,而目标则是可能已经绘制了图形的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

这是默认值,它表示绘制的图形(源)将画在现有画布(目标)之上:

context.globalCompositeOperation = "source-over";

效果与目前学习到的绘图效果是完全相同的。
image.png

  1. destination-over

这个操作的值与前一个值相反,所以现在目标绘制在源之上:

context.globalCompositeOperation = "destination-over";

效果与前一个操作恰好相反。
image.png

  1. source-atop

这个操作会将源绘制在目标之上,但是在重叠区域上两者都是不透明的。绘制在其他位置的目标是不透明的,但源是透明的。
image.png

  1. destination-atop

这个操作与source-atop相反,目标绘制在源之上,其中在重叠区域上两者都是不透明的,但绘制在其他位置的源是不透明的,而目标变成透明的。
image.png

  1. source-in

在源与目标重叠的区域只绘制源。而不重叠的部分都变成透明的。
image.png

  1. destination-in

这个操作与source-in相反,在源与目标重叠的区域保留目标。而不重叠的部分都变成透明的。
image.png

  1. source-out

在与目标不重叠的区域上绘制源。其他部分都变成透明的。
image.png

  1. destination-out

在与源不重叠的区域上保留目标。其他部分都变成透明的。
image.png

  1. lighter

这个值与顺序无关,如果源与目标重叠,就将两者的颜色值相加。得到的颜色值的最大取值为255,结果就是白色。
image.png

  1. copy

这个值与顺序无关,只绘制源,覆盖掉目标。
image.png

  1. xor(异或)

这个值与顺序无关,只绘制出不重叠的源与目标区域。所有重叠的部分都变成透明的。
image.png
总之,这些合成操作使你能够在需要绘制一些复杂图形的情况下实现一些有趣的效果。有一些操作(如 destination-out )在擦除画布上一些非矩形区域时是很有用的:例如,使用圆作为源。

2. 阴影

所有人都喜欢好看的阴影效果,它们可能是Adobe Photoshop中使用最广泛的效果了,并且也经常在Web和图形设计中使用。如果操作正确,它们实际上确实能够增加图像真实感。然而,如果操作不当,它们也可能完全毁掉一个图像。

在画布中创建阴影效果是相对较简单的,它可以通过4个全局属性进行控制。这些属性是shadowBlurshadowOffsetXshadowOffsetYshadowColor。我们马上开始逐一讲解这些属性。默认情况下,2D渲染上下文是不会绘制阴影效果的,因为shadowBlurshadowOffsetXshadowOffsetY都设置为0,而shadowColor则设置为透明黑色。创建阴影效果的唯一方法是将shadowColor修改为不透明值,同时将shadowBlurshadowOffsetXshadowOffsetY都设置为非 0 值:

context.shadowBlur = 20;
context.shadowColor = "rgb(0 ,0, 0)";
context.fillRect(50, 50, 100, 100);

在这个例子中,给阴影设置了20像素的模糊值,并将它的颜色设置为完全不透明的黑色。阴影的偏移值在 x 轴和 y 轴方向仍然保持为默认值0。需要特别指出的是,即使使用了不透明的黑色,但由于采用了模糊效果,这个阴影在边界上仍然有些透明效果。
image.png
修改shadowBlurshadowOffsetXshadowOffsetY属性,就能够创建不同的阴影效果:

context.shadowBlur = 0;
context.shadowOffsetX = 10;
context.shadowOffsetY = 10;
context.shadowColor = "rgba(100, 100, 100, 0.5)"; // 透明灰色
context.fillRect(200, 50, 100, 100);

将模糊修改为0,创建清晰的阴影效果,而稍微向右下偏移,就得到一个不同的阴影效果。使用上节中提到过的rgba颜色值将shadowColor设置为透明浅灰色,就能够实现更炫的效果。
image.png
画布的阴影支持所有图形,所以完全可以在所绘制的圆形或其他图形上创建阴影效果。甚至可以将颜色修改为任意奇特的值:

context.shadowColor = "rgb(255,0,0)"; // 红色
context.shadowBlur = 50;
context.shadowOffsetX = 0;
context.shadowOffsetY = 0;
context.beginPath();
context.arc(400, 100, 50, 0, Math.PI * 2, false);
context.closePath();
context.fill();

这段代码会得到一个圆形,它后面有一个鲜红色阴影效果。
image.png
通过组合使用各种模糊和颜色值,我们就能够实现一些与阴影完全无关的效果。例如,使用模糊黄色阴影在一个对象周围创建出光照效果,如太阳或发光体。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

夏安   

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值