js实现刮刮卡效果

记得小时候曾一度痴迷于刮刮卡,一有点钱就想去买刮刮卡,当中奖的时候,那心情甭提多激动了。不知道从什么时候开始哪个组织率先在网站上退出刮刮卡抽奖后,这个功能开始在互联网上弥漫开来。究其实现,方法不少。下面我们用canvas来实现这个效果。

实现要点:

1、在抽奖结果元素上盖上一个canvas元素,并将canvas的位置和高宽设置为和结果层一样,使其在视觉上重合。

2、在canvas上画上颜色或者图片,使其作为涂刮的遮罩层。

3、利用canvas图层叠加来实现刮开的效果。

4、读取canvas的像素,根据像素值来判断当前刮去了多少。

实现代码:

var eraser = (function(window,document,undefined){
    	var canvas = document.createElement("canvas"),ctx = canvas.getContext("2d"),start = 'mousedown',move = 'mousemove',end = 'mouseup',param,x,y,oLeft,oTop,oWidth,oHeight,
        defaults = {
            maskImg : '', 
            maskColor : '#bbb', 
            limit : 80, 
            size : 25, 
            once : 1, 
            callback : function(){} 
        };
        document.createTouch && (function(){start = 'touchstart';move = 'touchmove';end = 'touchend';})()
    	return function(maskId,params){
    		param = extend({},params,defaults),target = document.getElementById(maskId);
            oLeft = target.offsetLeft;oTop = target.offsetTop;oWidth = target.offsetWidth;oHeight = target.offsetHeight;
            setStyle(canvas,{
                position : "absolute",
                top : oTop + 'px',
                left : oLeft + 'px'
            });
            canvas.width = oWidth;canvas.height = oHeight;
            generateMask();
            target.parentNode.appendChild(canvas);
            addListeners();
    	}

        function generateMask(){
            if(param.maskImg){
                var im = new Image();
                im.src = param.maskImg;
                im.onload = function(){
                    console.log(im);
                    ctx.drawImage(im,0,0,canvas.width,canvas.height);
                    ctx.globalCompositeOperation = 'destination-out';
                }
            }else{
                ctx.fillStyle = param.maskColor;
                ctx.fillRect(0,0,canvas.width,canvas.height);
                ctx.globalCompositeOperation = 'destination-out';
            }
            ctx.lineJoin = 'round';
            ctx.lineWidth = param.size;
            ctx.strokeStyle = param.maskColor;
        }

        function onStart(e){
            e.preventDefault();
            x = e.pageX - oLeft;
            y = e.pageY - oTop;
            ctx.beginPath();
            ctx.arc(x,y,param.size/2,0,2*Math.PI,true);
            ctx.closePath();
            ctx.fill();
            canvas.addEventListener(move,onMove,false);
        }

        function onMove(e){
            ctx.beginPath();
            ctx.moveTo(x,y);
            ctx.lineTo(e.pageX - oLeft,e.pageY - oTop);
            x = e.pageX - oLeft;y = e.pageY - oTop;
            ctx.closePath();
            ctx.stroke();
            check();
        }

        function onEnd(){
            canvas.removeEventListener(move,onMove);
        }

        function check(){
            var data = ctx.getImageData(0,0,canvas.width,canvas.height).data,k=0;
            for(var i=0,len=data.length;i<len;i+=4){ data[i]===0 && data[i+1]===0 && data[i+2]===0 && data[i+3]===0 && k++; } var f = 100*k/(canvas.width*canvas.height); if(f>=param.limit){
                param.callback && (function(){param.callback();onEnd();})();
                param.callback = param.once && null;
            }
        }

        function addListeners(){
            canvas.addEventListener(start,onStart,false);
            canvas.addEventListener(end,onEnd,false);
        }

        function extend(res,ex,orig){
            for(var key in orig){
                res[key] = ex[key] ? ex[key] : orig[key];
            }
            return res;
        }

        function setStyle(target,setting){
            for(var key in setting){
                target.style[key] = setting[key];
            }
        }
    })(window,document);

在线demo:http://demo.deanhan.cn/eraser

  • 支付宝二维码 支付宝
  • 微信二维码 微信
相关文章