移動(dòng)端刮刮樂(lè)的實(shí)現(xiàn)方式(js+HTML5)
程序員有一種慣性思維,就是看見(jiàn)一些會(huì)動(dòng)的東西(帶點(diǎn)科技含量的,貓啊,狗啊就算了),總要先想一遍,這玩意用代碼是怎么控制的。比如電梯,路邊的霓虹燈,遙控器,小孩子的玩具等。
有時(shí)候還會(huì)感覺(jué)程序員看世界會(huì)看的透徹一點(diǎn).............
想必大家都玩過(guò)刮刮樂(lè),下面就介紹一種刮刮樂(lè)的移動(dòng)端實(shí)現(xiàn)方式!用到canvas
1、用HTML 5 canvas globalCompositeOperation 屬性實(shí)現(xiàn)刮刮樂(lè)
思路:
(1)首先需要一個(gè)盒子定位,確定刮刮樂(lè)區(qū)域想要放在哪里
(2)定位盒子里有個(gè)放內(nèi)容的盒子,也就是放獎(jiǎng)品的
(3)用一個(gè)畫(huà)布(canvas)把上面的盒子蓋住
(4)當(dāng)手觸摸移動(dòng)的時(shí)候,可以擦除部分畫(huà)布,露出獎(jiǎng)品區(qū)
(5)當(dāng)擦除足夠多(3/4)的時(shí)候,可以選擇讓畫(huà)布自動(dòng)消失,慢慢淡出(這個(gè)效果選做)
主要是第四步,如何擦除?
這里選用 globalCompositeOperation,即Canvas中的合成操作。簡(jiǎn)單來(lái)說(shuō),Composite(組合),就是對(duì)你在繪圖中,后繪制的圖形與先繪制的圖形之間的組合顯示效果,比如在國(guó)畫(huà)中,你先畫(huà)一筆紅色,再來(lái)一筆綠色,相交的部分是一種混色,而在油畫(huà)中,綠色就會(huì)覆蓋掉相交部分的紅色,這在程序繪圖中的處理就是Composite,Canvas API中對(duì)應(yīng)的函數(shù)就是globalCompositeOperation。
globalCompositeOperation中有個(gè)屬性值是“destination-out",也就是當(dāng)繪畫(huà)重疊時(shí)顯示透明。剛好用到這里,我們就可以在畫(huà)布上亂畫(huà),畫(huà)過(guò)的地方就是重疊的地方,就會(huì)變成透明,然后露出畫(huà)布下的東西,也就是我們想要的效果。
html 代碼如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
<title></title>
<link rel="stylesheet" type="text/css" href="css/guaguale.css" rel="external nofollow" />
</head>
<body>
<!-- 大的背景盒子-->
<div id="main">
<!-- 定位的盒子-->
<div class="canvasBox">
<!-- 放內(nèi)容的盒子-->
<span id="prize">
恭喜發(fā)財(cái),紅包拿來(lái)
</span>
<!-- 蒙版畫(huà)布-->
<canvas id="canvas"></canvas>
</div>
</div>
</body>
<script type="text/javascript">
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext('2d');
/* 畫(huà)布偏移量,下面用到的時(shí)候再介紹*/
var arr = getOffset(canvas);
var oLeft = arr[0];
var oTop = arr[1];
/* 初始化畫(huà)布*/
ctx.beginPath();
ctx.fillStyle = '#ccc';
ctx.fillRect(0,0,canvas.width,canvas.height);
ctx.closePath();
/* 增加觸摸*/
document.addEventListener("touchstart",function(){
/* 初始化畫(huà)筆*/
ctx.beginPath();
/* 畫(huà)筆粗細(xì)*/
ctx.lineWidth = 30;
/* 設(shè)置組合效果*/
ctx.globalCompositeOperation = 'destination-out';
/* 移動(dòng)畫(huà)筆原點(diǎn)*/
ctx.moveTo(event.touches[0].pageX-oLeft,event.touches[0].pageY-oTop);
},false)
document.addEventListener("touchmove",function(){
/* 根據(jù)手指移動(dòng)畫(huà)線,使之變透明*/
ctx.lineTo(event.touches[0].pageX-oLeft,event.touches[0].pageY-oTop);
/* 填充*/
ctx.stroke();
})
/* 之所以會(huì)用到下面的那個(gè)函數(shù)getOffset(obj)
* 是因?yàn)閑vent.touches[0].pageX、pageY獲取的是相對(duì)于可視窗口的距離
* 而lineTo畫(huà)筆的定位是根據(jù)畫(huà)布位置定位的
* 所以就要先獲取到畫(huà)布(canvas)相對(duì)于可視窗口的距離,然后計(jì)算得出觸摸點(diǎn)相對(duì)于畫(huà)布的距離
* */
/* 獲取該元素到可視窗口的距離*/
function getOffset(obj){
var valLeft = 0,valTop = 0;
function get(obj){
valLeft += obj.offsetLeft;
valTop += obj.offsetTop;
/* 不到最外層就一直調(diào)用,直到offsetParent為body*/
if (obj.offsetParent.tagName!='BODY') {
get(obj.offsetParent);
}
return [valLeft,valTop];
}
return get(obj);
}
</script>
</html>
css代碼如下:
*{
margin: 0;
padding: 0;
}
#main{
width: 100%;
padding: 20px 0;
background-color: red;
}
.canvasBox{
width: 78%;
height: 160px;
border-radius: 10px;
background-color: #FFF;
margin-left: 11%;
line-height: 160px;
text-align: center;
position: relative;
}
#canvas{
width: 96%;
height: 96%;
position: absolute;
left: 2%;
top: 2%;
background-color: transparent;
}
第五步要用到canvas像素點(diǎn)的獲取(這塊注意,像素級(jí)操作,要在服務(wù)器環(huán)境下打開(kāi))
getImageData(int x,int y,int width,int height):該方法獲取canvas上從(x,y)點(diǎn)開(kāi)始,寬為width、高為height的圖片區(qū)域的數(shù)據(jù),該方法返回的是一個(gè)CanvasPixelArray對(duì)象,該對(duì)象具有width、height、data等屬性。data屬性為一個(gè)數(shù)組,該數(shù)組每4個(gè)元素對(duì)應(yīng)一個(gè)像素點(diǎn)。
(對(duì)圖片的反相操作也可以這樣做,改變r(jià)gba值)
getImageData(int x,int y,int width,int height)返回的對(duì)象,data里面存儲(chǔ)的是像素點(diǎn)信息

我們?cè)俅蛴ata,data屬性為一個(gè)數(shù)組,每4個(gè)元素對(duì)應(yīng)一個(gè)像素點(diǎn)(以rgba的形式保存每一個(gè)像素點(diǎn)的信息)。

所以我們就可以根據(jù)像素點(diǎn)的opcity值來(lái)判斷這個(gè)像素點(diǎn)是不是透明,是不是等于0?
透明的像素點(diǎn)數(shù)量/總像素點(diǎn)數(shù)量 = 擦除比例
js代碼:
document.addEventListener("touchend",function(){
/* 獲取imageData對(duì)象*/
var imageDate = ctx.getImageData(0,0,canvas.width,canvas.height);
/* */
var allPX = imageDate.width * imageDate.height;
var iNum = 0;//記錄刮開(kāi)的像素點(diǎn)個(gè)數(shù)
for(var i=0;i<allPX;i++){
if(imageDate.data[i*4+3] == 0){
iNum++;
}
}
if(iNum >= allPX*3/4){
// disappear里面寫(xiě)了緩慢清除的css3動(dòng)畫(huà)效果
canvas.setAttribute('class','disappear');
}
},false)" .disappear " 的css樣式,css3消失動(dòng)畫(huà)
.disappear{
-webkit-animation: disa 2s 1;
animation: disa 2s 1;
-webkit-animation-fill-mode: forwards;
-moz-animation-fill-mode: forwards;
-o-animation-fill-mode: forwards;
animation-fill-mode: forwards;
}
@keyframes disa{
0%{opacity:1;}
100%{opacity: 0;}
}相對(duì)比網(wǎng)上的其他一些實(shí)現(xiàn)方式,這種還是比較簡(jiǎn)單的一種,大家相互學(xué)習(xí)。有什么其他的辦法可以留言相互學(xué)習(xí)
以上就是本文的全部?jī)?nèi)容,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作能帶來(lái)一定的幫助,同時(shí)也希望多多支持腳本之家!
相關(guān)文章
js實(shí)現(xiàn)七夕表白彈幕效果 jQuery實(shí)現(xiàn)彈幕技術(shù)
這篇文章主要介紹了js實(shí)現(xiàn)七夕表白彈幕效果,jQuery實(shí)現(xiàn)彈幕技術(shù),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-08-08
js和jquery實(shí)現(xiàn)tab狀態(tài)欄切換效果
這篇文章主要為大家詳細(xì)介紹了js和jquery實(shí)現(xiàn)tab狀態(tài)欄切換效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-08-08
Ajax實(shí)現(xiàn)郵箱驗(yàn)證實(shí)例代碼
這篇文章介紹了Ajax實(shí)現(xiàn)郵箱驗(yàn)證的方法,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-04-04
js實(shí)現(xiàn)導(dǎo)航欄上下動(dòng)畫(huà)效果
這篇文章主要為大家詳細(xì)介紹了js實(shí)現(xiàn)導(dǎo)航欄上下動(dòng)畫(huà)效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-07-07
?JavaScript?數(shù)據(jù)結(jié)構(gòu)之散列表的創(chuàng)建(1)
這篇文章主要介紹了?JavaScript?數(shù)據(jù)結(jié)構(gòu)之散列表的創(chuàng)建,文章圍繞主題相關(guān)內(nèi)容展開(kāi)詳細(xì)的介紹,需要的小伙伴可以參考一下2022-04-04
js 模擬實(shí)現(xiàn)類(lèi)似c#下的hashtable的簡(jiǎn)單功能代碼
越來(lái)越感覺(jué)js對(duì)集合的處理沒(méi)有c#強(qiáng)大。比如在實(shí)際開(kāi)發(fā)中,經(jīng)常用到在一維數(shù)組或者二維數(shù)組里取某一個(gè)滿足某些條件的項(xiàng),通常的處理方式就是遍歷數(shù)組,對(duì)比條件,匹配就取出,然后結(jié)束循環(huán)。2010-01-01
js實(shí)現(xiàn)的點(diǎn)擊超鏈顯示隱藏層
js實(shí)現(xiàn)的點(diǎn)擊超鏈顯示隱藏層...2007-05-05
javascript使用正則實(shí)現(xiàn)去掉字符串前面的所有0
這篇文章主要介紹了javascript使用正則實(shí)現(xiàn)去掉字符串前面的所有0,需要的朋友可以參考下2018-07-07

