资讯专栏INFORMATION COLUMN

学习 canvas 的 globalCompositeOperation 做出的神奇效果

UnixAgain / 2983人阅读

摘要:主要的不同是,刮刮卡效果最后需要自动擦除掉全部灰色,这里有两种方式。第二种方式,虽然不存在跨域的问题,但是,不能很好的根据刮刮卡上灰色的面积,控制最后擦除全部灰色的时机。

说明

最早知道 canvas 的 globalCompositeOperation 属性,是在需要实现一个刮刮卡效果的时候,当时也就是网上找到刮刮卡的效果赶紧完成任务就完了,这次又学习一次,希望能加深理解吧。

先来看下 canvas 的 globalCompositeOperation属性,具体是干什么的。

定义
globalCompositeOperation 属性设置或返回如何将一个源(新的)图像绘制到目标(已有)的图像上。        
源图像 = 您打算放置到画布上的绘图。
目标图像 = 您已经放置在画布上的绘图。

这个属性用来设置要在绘制新形状时应用的合成操作的类型,比如在一个蓝色的矩形上画一个红色的圆形,是红色在上显示,还是蓝色在上显示,重叠的部分显示还是不显示,不重叠的部分又怎么显示,等一些情况,在面对这些情况的时候,就是 globalCompositeOperation 属性起作用的时候了。
在取默认值的情况下,都是显示的,新画的图形会覆盖原来的图形。

用法

默认值: source-over
语法: context.globalCompositeOperation="source-in";

表格中的蓝色矩形为目标图像,红色圆形为源图像。

属性值 描述 效果
source-over 默认。在目标图像上显示源图像。
source-atop 在目标图像顶部显示源图像。源图像位于目标图像之外的部分是不可见的。
source-in 在目标图像中显示源图像。只有目标图像内的源图像部分会显示,目标图像是透明的。
source-out 在目标图像之外显示源图像。只会显示目标图像之外源图像部分,目标图像是透明的。
destination-over 在源图像上方显示目标图像。
destination-atop 在源图像顶部显示目标图像。源图像之外的目标图像部分不会被显示。
destination-in 在源图像中显示目标图像。只有源图像内的目标图像部分会被显示,源图像是透明的。
destination-out 在源图像外显示目标图像。只有源图像外的目标图像部分会被显示,源图像是透明的。
lighter 显示源图像 + 目标图像。
copy 显示源图像。忽略目标图像。
xor 使用异或操作对源图像与目标图像进行组合。

好的,下来实现一个水滴扩散的效果
效果图

实现思路

在一个 canvas 上先画出黑白色的图片,然后设置背景是一张彩色的图片,鼠标点击时,设置 canvas 的 globalCompositeOperation 属性值为 destination-out,根据鼠标在 canvas 中的 坐标,用一个不规则的图形逐渐增大,来擦除掉黑白色的图片,就可以慢慢显示彩色的背景了。

也就是说我们需要三张图片

黑白的图片

彩色的图片

不规则形状的图片

代码





    
    



    

    


我们继续来实现一个刮刮卡的效果

效果图

刮刮卡效果实现的思路:

一个 canvas 上先画一层灰色,然后设置canvas的背景图,设置 canvas 的 globalCompositeOperation属性值为 destination-out,点击并移动时,根据移动点的坐标,擦除掉灰色,当擦掉一部分时,再自动擦除掉全部灰色,显示出背景来。

刮刮卡的效果和水滴扩散的效果,在开始的时候几乎是一样的,不过水滴扩散效果,用的是一张不规则形状的图片来清除黑白图片,而刮刮卡效果,是通过画线的方式,线比较粗而已,来清除上面的灰色。
主要的不同是,刮刮卡效果最后需要自动擦除掉全部灰色,这里有两种方式。

第一种
使用 canvas 的 getImageData 方法,来获取 canvas 上的像素信息,这个方法返回的对象的 data 属性是一个一维数组,包含以 RGBA 顺序的数据,数据使用 0 至 255(包含)的整数表示,详细的可以看看 canvas 的像素操作。
用这个方法来判断有多少已经擦除掉了,也就是通过一个变量来记录有多少像素的RGBA的值是0,当变量的值超过某一个值时,就清除全部灰色。

代码在这里。

第二种
就直接看移动了多少,鼠标移动时,会有一个变量进行自增运算,当这个变量,超过一定值时,就擦除全部灰色。

代码在这里。

注意:
第一种方式使用 getImageData 存在跨域问题,不过因为这个效果中,没有在canvas上画图片,而是设置canvas的 background 为一张图片,所以这个还没有影响,但是如果canvas上画了其他图片,就可能需要处理跨域的问题了。
使用 getImageData 能获取到 canvas 上的像素信息,就可以根据刮刮卡上灰色的面积,决定擦除全部灰色的时机,更加灵活。

第二种方式,虽然不存在跨域的问题,但是,不能很好的根据刮刮卡上灰色的面积,控制最后擦除全部灰色的时机。

总结

文章中的效果主要是使用 globalCompositeOperation属性取值为 destination-out ,而取值为其他值的时候,同样也是可以制作出各种效果的,大家也可以发挥自己的想象力,去试试其它值,也许有新发现呢。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/110163.html

相关文章

  • 撩妹技能 get,教你用 canvas 画一场流星雨

    摘要:现在就一起来做一场流星雨,用程序员的野路子浪漫一下。要画一场流星雨,首先,自然我们要会画一颗流星。画一颗流星是的,的却是没这个,但是不代表我们画不出来。而我们每一帧要保留的就是,上一帧透明度的流星,覆盖画布黑色矩形我们不能显示。 开始 妹子都喜欢流星,如果她说不喜欢,那她一定是一个假妹子。 现在就一起来做一场流星雨,用程序员的野路子浪漫一下。 要画一场流星雨,首先,自然我们要会画一颗流...

    cc17 评论0 收藏0
  • 简单canvas翻角效果

    摘要:由于工作需求需要写一个翻角效果链接右上角需要从无的状态撕开一个标记且有动画过程上图是实现的效果图不是对这个翻角效果的难点在于没有翻开的时候露出的是下面的内容实现角度来说纯动画的设计方案并没有相出一个好的对策于是捡起了好久之前学的入门级别的下 由于工作需求 , 需要写一个翻角效果;showImg(https://segmentfault.com/img/bVYVm4?w=135&h=12...

    kun_jian 评论0 收藏0
  • 简单canvas翻角效果

    摘要:由于工作需求需要写一个翻角效果链接右上角需要从无的状态撕开一个标记且有动画过程上图是实现的效果图不是对这个翻角效果的难点在于没有翻开的时候露出的是下面的内容实现角度来说纯动画的设计方案并没有相出一个好的对策于是捡起了好久之前学的入门级别的下 由于工作需求 , 需要写一个翻角效果;showImg(https://segmentfault.com/img/bVYVm4?w=135&h=12...

    Magicer 评论0 收藏0

发表评论

0条评论

UnixAgain

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<