最近又被支付寶的集福字刷屏了
我到底還是沒看到敬業福ค(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('myCanvas'), ctx = canvas.getContext('2d'), 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 = './1.png'; }else if(random > 0.6){ img.src = './2.png'; }else{ img.src = './award.jpg'; } }; var bindEvent = function(){ canvas.addEventListener('touchmove', moveFunc, false); canvas.addEventListener('touchend', 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('touchmove', moveFunc, false); canvas.removeEventListener('touchend', endFunc, false); } } var init = (function(){ ctx.fillStyle = "#ccc"; ctx.fillRect(0, 0, w, h); randomImg(); img.addEventListener('load', function(){ canvas.style.backgroundImage = 'url(' + img.src +')'; ctx.globalCompositeOperation = 'destination-out'; 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('myCanvas'), ctx = canvas.getContext('2d'), 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('load', function(){ canvas.style.backgroundImage = 'url(' + img.src +')'; ctx.globalCompositeOperation = 'destination-out'; bindEvent(); }); })();
流程如下:
將整個canvas覆寫灰色圖層
隨機圖片
圖片預先載入
載入完畢後,設定圖片為canvas背景
刮卡前,設定ctx .globalCompositeOperation = 'destination-out';
為canvas綁定監聽事件,塗卡
這個globalCompositeOperation才是刮刮樂的關鍵
關於這個屬性的用法可以戳這裡
var randomImg = function(){ var random = Math.random(); if(random < 0.4){ img.src = './1.png'; }else if(random > 0.6){ img.src = './2.png'; }else{ img.src = './award.jpg'; } };
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('touchmove', moveFunc, false); canvas.removeEventListener('touchend', endFunc, false); } }
手抬起時,就會觸發touchend
在這個函數中,我們利用了ctx.getImageData()
取得了canvas的像素資訊
關於這個函數的用法可以戳這裡
當灰色圖層被刮開後,後面就是canvas的背景
所以我們可以透過判斷像素資訊RGBA中的A是否為0來判斷圖層是否被刮開
scrapeNum就代表被刮開的像素點
所以透過scrapeNum > area * 0.7
的判斷
當刮開的範圍大於總範圍的70%時
清除整個灰色圖層
以上就是行動端Touch事件與H5-Canvas像素點偵測實作刮刮樂的內容,更多相關內容請關注PHP中文網(m.sbmmt.com)!