好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

带你了解canvas中的globalCompositeOperation属性

本篇 文章 带大家详细 了解 canvas中的globalCompos IT e opera tion属性,通过代码实例看看该属性 做出 的神奇效果。 有一定的参考价值 , 有需要的朋友可以参考一下 , 希望对大家有所帮助 。

@H_ 304 _6@ 说明

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

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

定义

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

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

用法

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

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

属性值 描述 效果
source-over默认。在目标图像上显示源图像。

source-atop在目标图像顶部显示源图像。源图像位于目标图像之外的部分是不可见的。

source-in在目标图像中显示源图像。只有目标图像内的源图像部分会显示,目标图像是透明的。

source-out在目标图像之外显示源图像。只会显示目标图像之外源图像部分,目标图像是透明的。

destination-over在源图像上方显示目标图像。

destination-atop在源图像顶部显示目标图像。源图像之外的目标图像部分不会被显示。

destination-in在源图像中显示目标图像。只有源图像内的目标图像部分会被显示,源图像是透明的。

destination-out在源图像外显示目标图像。只有源图像外的目标图像部分会被显示,源图像是透明的。

lighter显示源图像 + 目标图像。

copy显示源图像。忽略目标图像。

xor使用异或操作对源图像与目标图像进行组合。

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

https://codepen.io/FEWY/pen/oPxbmj

效果图

实现思路

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

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

黑白的图片

彩色的图片

不规则形状的图片

代码

<!doctype ht ML >
<html>

<head>
    < ;m eta charset="UTF-8">
    <style>
        canvas {
            /* 设置鼠标的 光标 是一张图片, 16和22 分别表示 热点 的X坐标和Y坐标 */
            /* https://developer.mozilla. org /zh-CN/docs/Web/CSS/cursor/url */
            cursor: url(& # 39;https://HdhCmsTestkkkk1000 .COM /images/globalCompositeOperation/mouse.png') 16 22, auto;
        }
    </style>
</head>

<body>
    <canvas id="canvas" width="400px" h ei ght="250px"></canvas>

    <script type="text/javascript"> 
         VAR  canvas = document.getElementById("canvas");
        var context = canvas.getContext("2d");

        // 保存图片路径的数组
        var urlArr = ["https://HdhCmsTestkkkk1000测试数据/images/globalCompositeOperation/bg2.png", "https://HdhCmsTestkkkk1000测试数据/images/globalCompositeOperation/clear.png"];
        //  img Arr 保存加载后的图片的数组,imgArr中保存的是真实的图片
        // loadImg 函数用来加载 urlArr 中所有的图片
        // 并返回一个保存所有图片的数组
        var imgArr = loadImg(urlArr);
        // flag 用来限制  点击事件 ,一张图片只会产生一次效果
        var flag = false;
 

        function loadImg(urlArr) {
            var index = 0;
            var res = [];
            // 每次给 load 函数传入一个图片路径,来加载图片
            load(urlArr[index]);
            function load(url) {
                // 如果 index 等于 urlArr.length,
                // 表示加载完 全部图片了,就结束 load函数
                if (index  ==  urlArr.length) {
                    // 加载完全部图片,调用 init 函数
                    init();
                    return;
                }

                var img = new Image();
                img.src = url;
                // 不管当前图片 是否 加载成功,都要加载下一张图片
                img.onload = next;
                img.onerror = function () {
                    console. LOG (res[index] + "加载失败");
                    next();
                }
                // next 用来加载下一张图片
                function next() {
                    // 把加载后的图片,保存到 res 中
                    res[index] = img;
                    load(urlArr[ ++i ndex])
                }
            }
            // 最后返回保存所有真实图片的数组
            return res;
        }

        function init() {
            // 先在canvas上画黑白的图片,然后再设置背景是彩色的图片
            // 避免先显示出彩色图片,再显示出黑白的图片
            context.globalCompositeOperation = "source-over";
            context.drawImage(imgArr[0], 0, 0, 400, 250);
            canvas.style.background = 'url(https://HdhCmsTestkkkk1000测试数据/images/globalCompositeOperation/bg. jpg )';
            canvas.style.backgroundSize = "100% 100%";

            // flag 是 true 时,鼠标点击才有水滴扩散的效果
            flag = true;
            // canvas 绑定点击事件,点击时产生水滴扩散效果
            canvas.onclick =  dif fusion ;
        }

        // width 表示 不规则形状的图片的 尺寸 
        var width = 0;
        // speed 表示扩散效果的速度
        var speed = 8;
        // diffusion 函数根据鼠标坐标,产 生效 果
        function  diffusion (e) {
            if (flag) {
                flag = false;
                context.globalCompositeOperation = "destination-out";
                window. requestAnimationFrame (draw);
                // 根据鼠标坐标,画扩散效果
                function draw() {
                    // 这里不一定需要是 1800 ,但必须是一个足够大的数,可以扩散出整张背景图
                    if (width > 1800) {
                        flag = true;
                        return;
                    }
                    width += speed;
                    // 获取鼠标相对于 canvas 的坐标
                    var x = e.layerX;
                    var y = e.layerY;

                    // 画不规则形状的图片,逐渐增大 图片尺寸 
                    context.drawImage(imgArr[1], x - (width / 2), y - (width / 2), width, width);
                    window.requestAnimationFr am e(draw);
                }
            }
        }
    </script>
</body>

</html>

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

效果图

刮刮卡效果实现的思路:

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

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

第一种

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

代码在这里:

https://codepen.io/FEWY/pen/BOjmyg

第二种

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

代码在这里

https://codepen.io/FEWY/pen/eLJ env

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

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

总结

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

更多编程相关知识,请访问:编程入门!!

以上就是带你了解canvas中的globalCompositeOperation属性的详细内容,更多请关注其它相关文章!

总结

以上是 为你收集整理的 带你了解canvas中的globalCompositeOperation属性 全部内容,希望文章能够帮你解决 带你了解canvas中的globalCompositeOperation属性 所遇到的问题。

如果觉得 网站内容还不错, 推荐好友。

查看更多关于带你了解canvas中的globalCompositeOperation属性的详细内容...

  阅读:22次

上一篇: html5编码怎么设置

下一篇:html5 能做什么