最近又被支付寶的集福字刷屏了
我到底還是沒看到敬業福ค(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%時
清除整個灰色圖層