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.
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.
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.
source-over
Syntaxe : context.globalCompositeOperation="source-in";
属性值 | 描述 | 效果 |
---|---|---|
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
Colorées images
Images de forme irrégulière
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('https://www.kkkk1000.com/images/globalCompositeOperation/mouse.png') 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 = 'url(https://www.kkkk1000.com/images/globalCompositeOperation/bg.jpg)'; 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
L'idée deimplé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.
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!