在canvas绘图的时候,globalCompositeOperation属性是ctx上设置图案叠加时的效果的,它的说明网上有很多资料,摘取其中一个如下:
canvas的globalCompositeOperation属性说明.jpg
第一个坑
比如,destination-out类型的时候,按照说明的理解,那么如果我第二次画的是一个足够大的“遮罩层”,那么canvas上应该什么都看不见。
但是!注意!!!如果这个遮罩层是带透明度的,那么其实是可以看见上一次画的内容的!!!
并且,这个遮罩的透明度假设为a=0.5,destination-out下,效果类似于 “将已经存在的图像透明度削去a”;
而在destination-in下,效果则类似于 “将已经存在的图像透明度削成(变成)a”。如图:
代码:
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
ctx.globalCompositeOperation="lighter";
function draw() {
// 先画一个粉红色框
ctx.fillStyle='rgba(255, 2, 255, 1)';
ctx.fillRect(0,0,100,100);
// 罩上一个同样大小的遮罩
ctx.globalCompositeOperation="destination-out";
ctx.fillStyle="rgba(180, 160, 80, 0.5)";
ctx.fillRect(0,0,100,100);
ctx.globalCompositeOperation="lighter";
// 蓝色
// ctx.fillStyle='rgba(155, 155, 255, 0.1)';
// 透明度0.25的粉红色
// ctx.fillStyle='rgba(255, 2, 255, 0.25)';
// 透明度0.24的粉红色
// ctx.fillStyle='rgba(255, 2, 255, 0.24)';
// ctx.fillRect(0,0,100,100);
// requestAnimationFrame(draw);
}
draw();
第二个坑
当属性设为lighter时,按照资料解释,是将两次绘制图像的颜色值叠加,但是具体是怎么叠加的,没有给出说明。于是,就发现了这么个现象:
1、我准备画一个颜色值为rgba(255, 2, 255, 0.25)
的粉色矩形,注意它的透明度0.25!!
。当我无限循环的时候,它的颜色会逐渐叠加至白色。如图:
代码:
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
ctx.globalCompositeOperation="lighter";
function draw() {
// 先画一个粉红色框
// ctx.fillStyle='rgba(255, 2, 255, 1)';
// ctx.fillRect(0,0,100,100);
// // 罩上一个同样大小的遮罩
// ctx.globalCompositeOperation="destination-out";
// ctx.fillStyle="rgba(180, 160, 80, 0.5)";
// ctx.fillRect(0,0,100,100);
// ctx.globalCompositeOperation="lighter";
// 蓝色
// ctx.fillStyle='rgba(155, 155, 255, 0.1)';
// 透明度0.25的粉红色
ctx.fillStyle='rgba(255, 2, 255, 0.25)';
// 透明度0.24的粉红色
// ctx.fillStyle='rgba(255, 2, 255, 0.24)';
ctx.fillRect(0,0,100,100);
requestAnimationFrame(draw);
}
draw();
2、当我画同样颜色的矩形,但是透明度变为0.24
的时候,它就永远不会叠加成白色。如图:
并且,叠加后的图案,比单独画一次要更深。
代码:
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
ctx.globalCompositeOperation="lighter";
function draw() {
// 先画一个粉红色框
// ctx.fillStyle='rgba(255, 2, 255, 1)';
// ctx.fillRect(0,0,100,100);
// // 罩上一个同样大小的遮罩
// ctx.globalCompositeOperation="destination-out";
// ctx.fillStyle="rgba(180, 160, 80, 0.5)";
// ctx.fillRect(0,0,100,100);
// ctx.globalCompositeOperation="lighter";
// 蓝色
// ctx.fillStyle='rgba(155, 155, 255, 0.1)';
// 透明度0.25的粉红色
// ctx.fillStyle='rgba(255, 2, 255, 0.25)';
// 透明度0.24的粉红色
ctx.fillStyle='rgba(255, 2, 255, 0.24)';
ctx.fillRect(0,0,100,100);
requestAnimationFrame(draw);
}
draw();
3、当我要画一个颜色值为rgba(155, 155, 255, 0.1)
的蓝色矩形,注意透明度为0.1
,发现,它很快就被叠加成了白色,如图:
代码:
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
ctx.globalCompositeOperation="lighter";
function draw() {
// 先画一个粉红色框
// ctx.fillStyle='rgba(255, 2, 255, 1)';
// ctx.fillRect(0,0,100,100);
// // 罩上一个同样大小的遮罩
// ctx.globalCompositeOperation="destination-out";
// ctx.fillStyle="rgba(180, 160, 80, 0.5)";
// ctx.fillRect(0,0,100,100);
// ctx.globalCompositeOperation="lighter";
// 蓝色
ctx.fillStyle='rgba(155, 155, 255, 0.1)';
// 透明度0.25的粉红色
// ctx.fillStyle='rgba(255, 2, 255, 0.25)';
// 透明度0.24的粉红色
// ctx.fillStyle='rgba(255, 2, 255, 0.24)';
ctx.fillRect(0,0,100,100);
requestAnimationFrame(draw);
}
draw();
4、如果,在循环中,先罩上一个带透明度的遮罩,然后再绘制上述矩形,那么神奇的是:蓝色、粉色矩形再也不会被叠加成白色了!!并且,颜色略有加深,仿佛多次绘制矩形叠加一样。如图:
先遮罩透明度罩子再绘制矩形.jpg
代码:
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
ctx.globalCompositeOperation="lighter";
function draw() {
// 先画一个粉红色框
// ctx.fillStyle='rgba(255, 2, 255, 1)';
// ctx.fillRect(0,0,100,100);
// 罩上一个同样大小的遮罩
ctx.globalCompositeOperation="destination-out";
ctx.fillStyle="rgba(180, 160, 80, 0.2)";
ctx.fillRect(0,0,100,100);
ctx.globalCompositeOperation="lighter";
// 蓝色
ctx.fillStyle='rgba(155, 155, 255, 0.1)';
// 透明度0.25的粉红色
// ctx.fillStyle='rgba(255, 2, 255, 0.25)';
// 透明度0.24的粉红色
// ctx.fillStyle='rgba(255, 2, 255, 0.24)';
ctx.fillRect(0,0,100,100);
requestAnimationFrame(draw);
}
draw();
总结
目前还搞不清楚为什么带透明度的遮罩,就罩不住原图像了;同样,也搞不清楚为什么先遮罩、后绘制,就不会使得图案叠加成白色。但是,这种用法在用canvas绘制一些特效的时候,可以用到。具体示例见canvas特效库中的《发光loading特效》。
网友评论