网上无意间搜到了一个js刮刮乐效果,觉得很有趣,所以找来分析一下代码和效果,并根据自己理解精简了部分代码,分析不到位之处还请指教
(function(bodyStyle){
bodyStyle.mozUserSelect = 'none'; //这个功能设置为无法选择文本
bodyStyle.webkitUserSelect = 'none';
var img = new Image();
var canvas = document.querySelector('canvas'); //返回第一个canvas
canvas.style.position = 'absolute';
img.addEventListener('load',function(e){ //给img绑定一个加载事件
var ctx;
var w = img.width, h = img.height;
var offsetX = canvas.offsetLeft, offsetY = canvas.offsetTop;
//获取canvas相对于img元素的边距
var mousedown = false;
function layer(ctx){ //构建遮盖层
ctx.fillStyle = 'gray';
ctx.fillRect(0, 0, w, h); //自适应图片宽高
}
function eventDown(e){ //鼠标按下事件
e.preventDefault(); //阻止事件默认动作
mousedown=true;
}
function eventUp(e){ //鼠标抬起事件
e.preventDefault();
mousedown=false;
}
function eventMove(e){ //鼠标移动事件适用于web&wap端
e.preventDefault();
if(mousedown){
if(e.changedTouches){ //记录自移动以来发生改变的对象数组,定位到最后一次改变
e=e.changedTouches[e.changedTouches.length-1];
}
var x = (e.clientX + document.body.scrollLeft || e.pageX) - offsetX || 0,
y = (e.clientY + document.body.scrollTop || e.pageY) - offsetY || 0;
//获取触摸的坐标
with(ctx){ //设定默认对象ctx,相当于圆形画笔
beginPath()
arc(x, y, 5, 0, Math.PI * 2);
fill();
}
}
}
canvas.width=w; //设置画板的长宽,根据图片自适应
canvas.height=h;
canvas.style.backgroundImage='url('+img.src+')'; //获取画板的背景图
ctx=canvas.getContext('2d');
layer(ctx); //调用灰色遮罩层
ctx.globalCompositeOperation = 'destination-out'; //将新图像绘制到已有图像上
canvas.addEventListener('touchstart', eventDown);
canvas.addEventListener('touchend', eventUp);
canvas.addEventListener('touchmove', eventMove);
canvas.addEventListener('mousedown', eventDown);
canvas.addEventListener('mouseup', eventUp);
canvas.addEventListener('mousemove', eventMove);
});
img.src = 'http://www.baidu.com/img/bdlogo.gif';
})(document.body.style);
思路分析:刮刮乐一共有三层,第一层是背景层,随便选一张图片即可;第二层是遮罩层,大小和位置自适应第一层背景图,用canvas画出,也就是globalCompositeOperation的概念里所说的目标图像;第三层是源图像,即canvas绘出的一个个圆。利用globalCompositeOperation中的destination-out属性,在源图像外显示目标图像(只有源图像外的目标图像部分会被显示,源图像是透明的。)目标图像是已经画在画布上的图像,即灰色遮罩,源图像通过鼠标的移动或者手指的触摸来放置到画布上。
废话了这么多其实关于刮刮乐我们需要掌握的知识点主要有两个:
1.js 的touch事件
2.canvas globalCompositeOperation 属性
最后我发现了刮刮乐一个bug。。当你点击鼠标快速移动的时候,放开鼠标之后不用点击都能刮刮乐,很神奇。。但由于技术渣,并不知道解决方法,虽然我觉得不会有人像我这样点击鼠标飞速移动哈哈。