This article will take you to learn more about the globalCompositeOperation attribute in canvas, and see the magical effect of this attribute through code examples. It has certain reference value. Friends in need can refer to it. I hope it will be helpful to everyone.
Explanation
The first to know the globalCompositeOperation property of canvas is when needed When implementing a scratch card effect, I just found the scratch card effect online and quickly completed the task. This time I studied it again, hoping to deepen my understanding.
Let’s first look at the globalCompositeOperation attribute of canvas and what it does specifically.
Definition
globalCompositeOperation property sets or returns how to draw a source (new) image to the target (existing) on the image.
Source image = the drawing you intend to place on the canvas.
target image = the drawing you have placed on the canvas.
This property is used to set the type of composition operation to be applied when drawing a new shape. For example, if you draw a red circle on a blue rectangle, will red appear on top or blue? The color is displayed on the top, whether the overlapping parts are displayed or not, how to display the non-overlapping parts, and other situations. When facing these situations, it is time for the globalCompositeOperation
attribute to take effect.
Under the default value, they are all displayed, and the newly drawn graphics will overwrite the original graphics.
Usage
Default value: source-over
Syntax: context.globalCompositeOperation=" source-in";
The blue rectangle in the table is the target image, and the red circle is the source image.
Attribute value |
Description |
Effect |
##source-over | default. Display the source image over the destination image. |
|
source-atop | Displays the source image on top of the destination image. The parts of the source image that lie outside the target image are invisible. |
|
source-in | Displays the source image within the target image. Only the portion of the source image within the destination image is displayed; the destination image is transparent. |
|
source-out | Display the source image in addition to the target image. Only the portion of the source image other than the target image will be displayed, and the target image will be transparent. |
|
destination-over | Displays the destination image above the source image. |
|
destination-atop | Displays the destination image on top of the source image. Portions of the target image outside the source image will not be displayed. |
|
destination-in | Displays the destination image within the source image. Only the portion of the target image within the source image will be displayed; the source image is transparent. |
|
destination-out | Displays the destination image outside the source image. Only the portion of the target image outside the source image is displayed; the source image is transparent. |
|
lighter | Display source image target image. |
|
copy | Display source image. Ignore the target image. |
|
xor | Combines the source and destination images using an XOR operation. |
|
Okay, let’s realize the effect of water droplet diffusion:
https://codepen.io/FEWY/pen/oPxbmj
Rendering
Implementation ideas
First draw a black and white picture on a canvas, and then set the background to Colored pictures, when the mouse clicks, set the globalCompositeOperation
attribute value of the canvas to destination-out
, and use an irregular shape to gradually increase according to the coordinates of the mouse in the canvas. Erase the black and white pictures and slowly display the colored background.
That is to say, we need three pictures
Black and white pictures
Colored pictures
Irregular shaped pictures
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>
Copy after login
Let’s continue to realize the effect of a scratch card
Rendering
## The idea of implementing the scratch card effect:
First draw a layer of gray on a canvas, then set the background image of the canvas, and set the globalCompositeOperation attribute value of the canvas to
destination -out, when clicked and moved, the gray will be erased according to the coordinates of the moving point. When a part is erased, all the gray will be automatically erased and the background will be displayed.
The scratch card effect and the water drop diffusion effect are almost the same at the beginning, but the water drop diffusion effect uses an irregularly shaped picture to clear black and white pictures, while the scratch card The effect is to clear the gray above by drawing lines, which are thicker. The main difference is that the scratch card effect needs to automatically erase all the gray at the end. There are two ways.
The first one
Use the getImageData method of canvas to obtain the pixel information on the canvas. The data attribute of the object returned by this method is A one-dimensional array containing data in RGBA order. The data is represented by integers from 0 to 255 (inclusive). For details, please see Pixel Operation of canvas. Use this method to determine how much has been erased, that is, use a variable to record how many pixels the RGBA value is 0. When the value of the variable exceeds a certain value, all grays are cleared.
The code is here:https://codepen.io/FEWY/pen/BOjmyg
Second type
Just look at how much it has moved. When the mouse moves, a variable will be incremented. When this variable exceeds a certain value, all gray will be erased.
Code herehttps://codepen.io/FEWY/pen/eLJeNv
Note: The first way to use
getImageData has cross-domain problems, but because in this effect, the picture is not drawn on the canvas, but the background of the canvas is set to a picture, so this There is no impact yet, but if other pictures are drawn on the canvas, cross-domain issues may need to be dealt with.
Use getImageData to get the pixel information on the canvas, and you can decide the timing of erasing all gray based on the gray area on the scratch card, which is more flexible.
The second method, although there is no cross-domain problem, cannot control the final timing of erasing all gray based on the gray area on the scratch card. SummaryThe effect in the article is mainly to use globalCompositeOperationThe attribute value is
destination-out, and when the value is other values, Various effects can also be produced. You can also use your imagination to try other values, and you may make new discoveries.
For more programming-related knowledge, please visit: Introduction to Programming! !
The above is the detailed content of Take you to understand the globalCompositeOperation attribute in canvas. For more information, please follow other related articles on the PHP Chinese website!