首頁 >web前端 >H5教程 >行動端Touch事件與H5-Canvas像素點偵測實現刮刮樂

行動端Touch事件與H5-Canvas像素點偵測實現刮刮樂

黄舟
黄舟原創
2017-02-27 15:28:062274瀏覽


最近又被支付寶的集福字刷屏了
我到底還是沒看到敬業福ค(TㅅT) 心塞
今天給大家帶來行動端的刮刮樂實現
效果就是這樣的

手滑動觸發刮卡

當刮卡面積達到70%以上,自動刮除全部灰色圖層


程式碼不是很多
全部程式碼就這些

<!DOCTYPE html><html lang="en"><head>
    <meta charset="UTF-8">
    <meta content="width=device-width,maximum-scale=1.0,minimum-scale=1.0,initial-scale=1.0,user-scalable=no" name="viewport">
    <title>Scrape</title>
    <style>
        #myCanvas {            
        background-repeat: no-repeat;            
        background-position: center;            
        background-size: 200px 200px;        
        }
    </style></head><body>
    <canvas id="myCanvas" width=300 height=300></canvas>
    <script>
        var canvas = document.getElementById(&#39;myCanvas&#39;),
            ctx = canvas.getContext(&#39;2d&#39;),
            w = canvas.width;
            h = canvas.height;
            area = w * h;
            l = canvas.offsetLeft;
            t = canvas.offsetTop,
            img = new Image();        
            var randomImg = function(){
            var random = Math.random();            
            if(random < 0.4){
                img.src = &#39;./1.png&#39;;
            }else if(random > 0.6){
                img.src = &#39;./2.png&#39;;
            }else{
                img.src = &#39;./award.jpg&#39;;
            }
        };        var bindEvent = function(){
            canvas.addEventListener(&#39;touchmove&#39;, moveFunc, false);
            canvas.addEventListener(&#39;touchend&#39;, endFunc, false);
        };        var moveFunc = function(e){
            var touch = e.touches[0],
                posX = touch.clientX - l,
                posY = touch.clientY - t;
            ctx.beginPath();
            ctx.arc(posX, posY, 15, 0, Math.PI * 2, 0);
            ctx.fill();
        };        var endFunc = function(e){
            var data = ctx.getImageData(0, 0, w, h).data,
                scrapeNum = 0;            
                for(var i = 3, len = data.length; i < len; i += 4){                
                if(data[i] === 0){
                    scrapeNum++;
                }
            }            if(scrapeNum > area * 0.7){
                ctx.clearRect(0, 0, w, h);
                canvas.removeEventListener(&#39;touchmove&#39;, moveFunc, false);
                canvas.removeEventListener(&#39;touchend&#39;, endFunc, false);
            }
        }        var init = (function(){
            ctx.fillStyle = "#ccc";
            ctx.fillRect(0, 0, w, h);
            randomImg();            
            img.addEventListener(&#39;load&#39;, function(){
                canvas.style.backgroundImage = &#39;url(&#39; + img.src +&#39;)&#39;;
                ctx.globalCompositeOperation = &#39;destination-out&#39;;
                bindEvent();
            });
        })();    </script></body></html>

下面我就簡單說明一下
首先在頁面中我們只需要一個canvas元素

<canvas id="myCanvas" width=300 height=300></canvas>

CSS中的我們需要對canvas的背景圖片事先設定好樣式

#myCanvas {    
background-repeat: no-repeat;    
background-position: center;    
background-size: 200px 200px;}

腳本中我們首先要宣告所需變數

var canvas = document.getElementById(&#39;myCanvas&#39;),
    ctx = canvas.getContext(&#39;2d&#39;),
    w = canvas.width;
    h = canvas.height;
    area = w * h;
    l = canvas.offsetLeft;
    t = canvas.offsetTop,
    img = new Image();

取得canvas物件以及它的上下文物件
area變數是為下面的像素點偵測所準備
img用來進行圖片預先載入


最關鍵的函數在於init初始化函數

var init = (function(){
    ctx.fillStyle = "#ccc";
    ctx.fillRect(0, 0, w, h);
    randomImg();            
    img.addEventListener(&#39;load&#39;, function(){
        canvas.style.backgroundImage = &#39;url(&#39; + img.src +&#39;)&#39;;
        ctx.globalCompositeOperation = &#39;destination-out&#39;;
        bindEvent();
    });
})();

流程如下:

  • 將整個canvas覆寫灰色圖層

  • 隨機圖片

  • 圖片預先載入

  • 載入完畢後,設定圖片為canvas背景

  • 刮卡前,設定ctx .globalCompositeOperation = 'destination-out';

  • 為canvas綁定監聽事件,塗卡

這個globalCompositeOperation才是刮刮樂的關鍵
關於這個屬性的用法可以戳這裡


var randomImg = function(){
    var random = Math.random();    if(random < 0.4){
        img.src = &#39;./1.png&#39;;
    }else if(random > 0.6){
        img.src = &#39;./2.png&#39;;
    }else{
        img.src = &#39;./award.jpg&#39;;
    }
};

randomImg函數的功能就是隨機圖片
隨機圖片就需要利用Math.random()隨機數字


#canvas我們需要綁定兩個函數
touchmove和touchend

var moveFunc = function(e){
    var touch = e.touches[0],
        posX = touch.clientX - l,
        posY = touch.clientY - t;
    ctx.beginPath();
    ctx.arc(posX, posY, 15, 0, Math.PI * 2, 0);
    ctx.fill();};

滑動畫面就要畫一個圓
由於設定了destination-out ,所以產生了刮卡的效果
還要注意,每次觸發都要ctx.beginPath();  
否則ctx.fill();會連接之前劃過的圓,大面積刮塗

var endFunc = function(e){
    var data = ctx.getImageData(0, 0, w, h).data,
        scrapeNum = 0;    
        for(var i = 3, len = data.length; i < len; i += 4){        
        if(data[i] === 0){
            scrapeNum++;
        }
    }    if(scrapeNum > area * 0.7){
        ctx.clearRect(0, 0, w, h);
        canvas.removeEventListener(&#39;touchmove&#39;, moveFunc, false);
        canvas.removeEventListener(&#39;touchend&#39;, endFunc, false);
    }
}

手抬起時,就會觸發touchend
在這個函數中,我們利用了ctx.getImageData()取得了canvas的像素資訊
關於這個函數的用法可以戳這裡
當灰色圖層被刮開後,後面就是canvas的背景
所以我們可以透過判斷像素資訊RGBA中的A是否為0來判斷圖層是否被刮開
scrapeNum就代表被刮開的像素點 
所以透過scrapeNum > area * 0.7的判斷
當刮開的範圍大於總範圍的70%時
清除整個灰色圖層

 以上就是行動端Touch事件與H5-Canvas像素點偵測實作刮刮樂的內容,更多相關內容請關注PHP中文網(www.php.cn)!


#
陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn