Maison  >  Article  >  interface Web  >  Vous faire comprendre l'attribut globalCompositeOperation dans Canvas

Vous faire comprendre l'attribut globalCompositeOperation dans Canvas

青灯夜游
青灯夜游avant
2021-04-25 11:57:524560parcourir

Cet article vous donnera une compréhension détaillée de l'attribut globalCompositeOperation dans Canvas et verra les effets magiques de cet attribut à travers des exemples de code. Il a une certaine valeur de référence. Les amis dans le besoin peuvent s'y référer. J'espère qu'il sera utile à tout le monde.

Vous faire comprendre l'attribut globalCompositeOperation dans Canvas

Explication

La première fois que nous connaissons l'attribut globalCompositeOperation de Canvas, c'est quand nécessaire Lors de la mise en œuvre d'un effet de carte à gratter, je viens de trouver l'effet de carte à gratter en ligne et j'ai rapidement terminé la tâche. Cette fois, je l'ai étudié à nouveau, dans l'espoir d'approfondir ma compréhension.

Jetons d’abord un coup d’œil à l’attribut globalCompositeOperation de Canvas et à ce qu’il fait spécifiquement.

Définition

la propriété globalCompositeOperation définit ou renvoie comment dessiner une image source (nouvelle) vers la cible (existante) sur le image.
Image source = le dessin que vous avez l'intention de placer sur la toile.
image cible = le dessin que vous avez placé sur la toile.

Cet attribut permet de définir le type d'opération de composition à appliquer lors du dessin d'une nouvelle forme. Par exemple, si vous dessinez un cercle rouge sur un rectangle bleu, si le rouge sera affiché dessus. ou du bleu sera affiché dessus. La couleur est affichée en haut, si les parties qui se chevauchent sont affichées ou non, comment afficher les parties qui ne se chevauchent pas et d'autres situations. Face à ces situations, il est temps pour le attribut pour prendre effet. globalCompositeOperation Avec la valeur par défaut, ils sont tous affichés et les graphiques nouvellement dessinés écraseront les graphiques d'origine.

Utilisation

Par défaut :

source-over Syntaxe :
context.globalCompositeOperation="source-in";

Bleu dans le tableau Le rectangle est l'image cible et le cercle rouge est l'image source.

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

D'accord, réalisons l'effet de diffusion des gouttelettes d'eau :

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

Rendu

Idée de mise en œuvre

Dessinez d'abord une image en noir et blanc sur une toile, puis définissez l'arrière-plan sur Pour la couleur images, lorsque vous cliquez sur la souris, définissez la valeur de l'attribut globalCompositeOperation du canevas sur destination-out. Selon les coordonnées de la souris dans le canevas, utilisez une forme irrégulière pour augmenter progressivement la taille afin d'effacer les images en noir et blanc. . L'arrière-plan coloré s'affiche lentement.

C'est-à-dire qu'il nous faut trois images

Images en noir et blanc

Vous faire comprendre lattribut globalCompositeOperation dans Canvas

Colorées images

Vous faire comprendre lattribut globalCompositeOperation dans Canvas

Images de forme irrégulière

Vous faire comprendre lattribut globalCompositeOperation dans Canvas

Code

<!doctype html>
<html>

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

<body>
    <canvas id="canvas" width="400px" height="250px"></canvas>

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

        // 保存图片路径的数组
        var urlArr = ["https://www.kkkk1000.com/images/globalCompositeOperation/bg2.png", "https://www.kkkk1000.com/images/globalCompositeOperation/clear.png"];
        // imgArr 保存加载后的图片的数组,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[++index])
                }
            }
            // 最后返回保存所有真实图片的数组
            return res;
        }

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

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

        // 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.requestAnimationFrame(draw);
                }
            }
        }
    </script>
</body>

</html>

Continuons à réaliser l'effet d'une carte à gratter

Rendu

Vous faire comprendre lattribut globalCompositeOperation dans Canvas

L'idée de​​implémenter l'effet de carte à gratter :

Dessinez d'abord une couche de gris sur une toile, puis définissez l'image d'arrière-plan de la toile, définissez la valeur de l'attribut globalCompositeOperation de la toile sur destination-out, et cliquez et déplacez, selon les coordonnées du point mobile, le gris est effacé Lorsqu'une partie est effacée, tout le gris est automatiquement effacé et le fond est affiché.

L'effet de carte à gratter et l'effet de diffusion de gouttelettes d'eau sont presque les mêmes au début, mais l'effet de diffusion de gouttelettes d'eau utilise une image de forme irrégulière pour effacer les images en noir et blanc, tandis que l'effet de carte à gratter L'effet est pour effacer le gris du dessus en traçant des lignes plus épaisses.
La principale différence est que l'effet de la carte à gratter doit automatiquement effacer tout le gris à la fin. Il existe deux manières.

La première méthode

utilise la méthode getImageData du canevas pour obtenir les informations de pixel sur le canevas L'attribut data de l'objet renvoyé par. cette méthode est un tableau unidimensionnel qui contient des données dans l'ordre RGBA. Les données sont représentées par des nombres entiers de 0 à 255 (inclus). Pour plus de détails, veuillez consulter l'opération de pixel du canevas.
Utilisez cette méthode pour déterminer la quantité qui a été effacée, c'est-à-dire utilisez une variable pour enregistrer le nombre de pixels dont la valeur RGBA est 0. Lorsque la valeur de la variable dépasse une certaine valeur, tous les gris sont effacés.

Le code est ici :

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

Deuxième type

Regardez simplement à quel point elle a bougé. Lorsque la souris bouge, une variable sera incrémentée. Lorsque cette variable dépasse une certaine valeur, tous les gris seront effacés.

Codez ici

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

Remarque :
La première façon d'utiliser getImageData présente des problèmes inter-domaines, mais comme dans cet effet, l'image n'est pas dessinée sur le canevas, mais le background du canevas est défini sur une image, donc cela n'a aucun impact Mais si d’autres images sont dessinées sur la toile, il faudra peut-être résoudre des problèmes inter-domaines.
Utilisez getImageData pour obtenir les informations sur les pixels sur le canevas, et vous pouvez décider du moment où tous les gris seront effacés en fonction de la zone grise de la carte à gratter, qui est plus flexible.

La deuxième méthode, bien qu'il n'y ait pas de problème inter-domaines, est incapable de contrôler le moment final d'effacement de tout le gris en fonction de la zone grise de la carte à gratter.

Résumé

Les effets de l'article utilisent principalement l'attribut globalCompositeOperation dont la valeur est destination-out Lorsque la valeur est d'autres valeurs, divers effets peuvent également être produits. votre imagination pour essayer d'autres valeurs et vous pourrez faire de nouvelles découvertes.

Pour plus de connaissances sur la programmation, veuillez visiter : Introduction à la programmation ! !

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer
Article précédent:Qu'est-ce que HTML5Article suivant:Qu'est-ce que HTML5