本篇文章主要介紹了行動端刮刮樂的實作方法以及實作程式碼。具有很好的參考價值。下面跟著小編一起來看下吧
程式設計師有一種慣性思維,就是看見一些會動的東西(帶點科技含量的,貓啊,狗啊就算了),總要先想一遍,這玩意用程式碼是怎麼控制的。例如電梯,路邊的霓虹燈,遙控器,小孩的玩具等,都統統被程式設計師「意淫」過。
有時候還會覺得程式設計師看世界會看的透徹一點.............
想必大家都玩過刮刮樂,以下就介紹一種刮刮樂的行動端實現方式!用到canvas
1、用HTML 5 canvas globalCompositeOperation 屬性實作刮刮樂
思路:
#(1)首先需要一個盒子定位,確定刮刮樂區域想要放在哪裡
(2)定位盒子裡有個放內容的盒子,也就是放獎品的
(3)用一個畫布(canvas)把上面的盒子蓋住
(4)當手觸摸移動的時候,可以擦除部分畫布,露出獎品區
(5)當擦除夠多(3/4)的時候,可以選擇讓畫布自動消失,慢慢淡出(這個效果選做)
主要是第四步,如何擦除?
這裡選用 globalCompositeOperation,即Canvas中的合成操作。簡單來說,Composite(組合),就是對你在繪圖中,後繪製的圖形與先繪製的圖形之間的組合顯示效果,比如在國畫中,你先畫一筆紅色,再來一筆綠色,相交的部分是一種混色,而在油畫中,綠色就會覆蓋掉相交部分的紅色,這在程式繪圖中的處理就是Composite,Canvas API中對應的函數就是globalCompositeOperation。
globalCompositeOperation中有個屬性值是「destination-out",也就是當繪畫重疊時顯示透明。剛好用到這裡,我們就可以在畫布上亂畫,畫過的地方就是重疊的地方,就會變成透明,然後露出畫布下的東西,也就是我們想要的效果。
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> <!-- 大的背景盒子--> <p id="main"> <!-- 定位的盒子--> <p class="canvasBox"> <!-- 放内容的盒子--> <span id="prize"> 恭喜发财,红包拿来 </span> <!-- 蒙版画布--> <canvas id="canvas"></canvas> </p> </p> </body> <script type="text/javascript"> var canvas = document.getElementById("canvas"); var ctx = canvas.getContext('2d'); /* 画布偏移量,下面用到的时候再介绍*/ var arr = getOffset(canvas); var oLeft = arr[0]; var oTop = arr[1]; /* 初始化画布*/ ctx.beginPath(); ctx.fillStyle = '#ccc'; ctx.fillRect(0,0,canvas.width,canvas.height); ctx.closePath(); /* 增加触摸监听*/ document.addEventListener("touchstart",function(){ /* 初始化画笔*/ ctx.beginPath(); /* 画笔粗细*/ ctx.lineWidth = 30; /* 设置组合效果*/ ctx.globalCompositeOperation = 'destination-out'; /* 移动画笔原点*/ ctx.moveTo(event.touches[0].pageX-oLeft,event.touches[0].pageY-oTop); },false) document.addEventListener("touchmove",function(){ /* 根据手指移动画线,使之变透明*/ ctx.lineTo(event.touches[0].pageX-oLeft,event.touches[0].pageY-oTop); /* 填充*/ ctx.stroke(); }) /* 之所以会用到下面的那个函数getOffset(obj) * 是因为event.touches[0].pageX、pageY获取的是相对于可视窗口的距离 * 而lineTo画笔的定位是根据画布位置定位的 * 所以就要先获取到画布(canvas)相对于可视窗口的距离,然后计算得出触摸点相对于画布的距离 * */ /* 获取该元素到可视窗口的距离*/ function getOffset(obj){ var valLeft = 0,valTop = 0; function get(obj){ valLeft += obj.offsetLeft; valTop += obj.offsetTop; /* 不到最外层就一直调用,直到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像素點的取得(這塊注意,像素級操作,要在伺服器環境下開啟)
getImageData(int x,int y,int width,int height):該方法取得canvas上從(x,y)點開始,寬為width、高為height的圖片區域的數據,該方法傳回的是一個CanvasPixelArray物件,該物件具有width、height、data等屬性。 data屬性為一個數組,該數組每4個元素對應一個像素點。
(對圖片的反相操作也可以這樣做,改變rgba值)
getImageData(int x,int y,int width,int height)傳回的對象,data裡面儲存的是像素點資訊
我們再印出data,data屬性為一個數組,每4個元素對應一個像素點(以rgba的形式保存每一個像素點的資訊)。
所以我們可以根據像素點的opcity值來判斷這個像素點是不是透明,是不是等於0?
透明的像素點數量/總像素點數量= 擦除比例
js程式碼:
document.addEventListener("touchend",function(){ /* 获取imageData对象*/ var imageDate = ctx.getImageData(0,0,canvas.width,canvas.height); /* */ var allPX = imageDate.width * imageDate.height; var iNum = 0;//记录刮开的像素点个数 for(var i=0;i<allPX;i++){ if(imageDate.data[i*4+3] == 0){ iNum++; } } if(iNum >= allPX*3/4){ // disappear里面写了缓慢清除的css3动画效果 canvas.setAttribute('class','disappear'); } },false)
" .disappear " 的css樣式,css3消失動畫
.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;} }
以上是js+HTML5實現行動端刮刮樂的方式詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!