簡單入門canvas - 經過刮獎效果來學習

一 、前言css

一直在作PC端的前端開發,從互聯網到行業軟件。最近發現移動端已經成爲前端必備技能了,真是不能中止學習。HTML5新增的一些東西,canvas是用的比較多也比較複雜的一個,簡單的入門了一下,經過一個刮獎效果來學習。html

 

2、canvas基礎前端

本文的目標是作一個刮獎效果,可是若是都不知道canvas是怎麼回事,那麼確定也沒法進行下去,因此先講講canvas基礎吧。android

首先,該怎麼理解canvas,思來想去,最好的理解辦法應該就是把canvas理解爲一個空白的畫紙,一張你能夠在上面畫畫的紙。web

而後,你經過HTML標籤訂義canvas,例如:canvas

<canvas id="canvas" width="200" height="200">你的瀏覽器不支持canvas</canvas>

這樣,你就設置好了一張200×200的畫紙了。瀏覽器

這裏要注意的是,canvas元素的寬高須要直接寫在標籤上或者經過js來設置。若是用css設置,那麼瀏覽器會理解爲把這張紙縮放成你設置的寬高。跟預期仍是不同的。iphone

 

而後,有了紙第二步就是畫東西了,畫東西須要的就是筆了。獲得畫筆:學習

var ctx = document.getElementById("canvas").getContext("2d");

這樣,就有了這隻筆了,叫ctx。ui

 

而後就是繪畫,這裏要重點說明的是,canvas畫東西須要兩步

  • 第一步:告訴系統你要畫的東西的路徑
  • 第二步:告訴系統你須要用哪一種方式填充路徑

簡單來講,你畫一條直線,那麼代碼應該是告訴系統我要從0,0點到100,100點設置一條路徑,而後用黑色描邊這條路徑。

用代碼來描述我上面的那句話:

ctx.beginPath();    // 開始畫路徑
ctx.moveTo(0, 0);    // 移動到0,0點
ctx.lineTo(100, 100);    // 畫條直線到100,100點
ctx.closePath();    // 閉合路徑
ctx.lineWidth = "5";    // 設置線寬5px
// 至此路徑描述已經結束
ctx.strokeStyle = "#000";    // 設置描邊顏色爲黑色
ctx.stroke();    // 執行描邊

上面代碼就能夠畫一條直線了。固然,canvas能作的遠遠不止這些。

由於是基礎嘛,因此canvas就講到這裏啦。關於canvas的東西太多,但原理基本都是這樣,固然除了描邊,還有填充(fill),填充各類形狀(fillRect),畫圖形(drawImage)等。系統學習canvas確實須要一本書或者一系列教程,由於我也是剛學,就不誤人子弟啦。這些基礎其實也夠理解下面的例子啦。

 

3、刮獎效果 

最簡單的一個刮獎效果原理大概就是這樣,放一張底圖(或者是文字,例如謝謝惠顧呀),而後再它之上覆蓋一個canvas,遮住這張圖,接着綁定touchstart(mousedown),touchmove(mousemove),touchend事件。而後移動的時候用「透明」填充canvas,那麼被canvas遮住的部分就會呈現出來了。

直接看代碼吧,最簡單的實現

 

  1 <!DOCTYPE html>
  2 <!--[if lt IE 7]><html class="no-js lt-ie9 lt-ie8 lt-ie7"><![endif]-->
  3 <!--[if IE 7]><html class="no-js lt-ie9 lt-ie8"><![endif]-->
  4 <!--[if IE 8]><html class="no-js lt-ie9"> <![endif]-->
  5 <!--[if gt IE 8]><!--><html class="no-js"><!--<![endif]-->
  6 
  7 <head>
  8     <meta charset="utf-8">
  9     <meta http-equiv="X-UA-Compatible" content="IE=edge">
 10     <title>刮獎</title>
 11     <meta name="description" content="刮獎">
 12     <meta name="viewport" content="width=device-width, initial-scale=1">
 13     
 14     <style>
 15         body{margin: 0;}
 16         #price{width: 200px; height: 100px; font-size: 40px; color: #f60; line-height: 100px; text-align: center;}
 17         #canvas{position: absolute; top: 0; left: 0;}
 18     </style>
 19 </head>
 20 
 21 <body>
 22 
 23     <div id="price">謝謝惠顧</div>
 24     <canvas id="canvas" width="200" height="100">你的瀏覽器不支持canvas</canvas>
 25 
 26     <script>
 27         
 28         // 獲得畫筆
 29         var cvs = document.getElementById("canvas"),
 30             ctx = cvs.getContext("2d"),
 31             touchRadius = 5;    // 默認手指觸摸半徑,能夠自定義設置
 32         
 33         // 默認填充灰色來遮住文字
 34         ctx.fillStyle = "#ccc";
 35         ctx.fillRect(0, 0, 200, 100);    // fillRect,用矩形填充
 36         
 37         // 畫園的方法
 38         // @param { integer } 圓心的x座標
 39         // @param { integer } 圓心的y座標
 40         // @param { integer } 圓心半徑
 41         // @param { string } 填充的顏色(本例中會經過其他代碼設置爲‘透明’,因此這個設置能夠忽略)
 42         var fillCircle = function (x, y, radius, fillColor) {
 43             this.fillStyle = fillColor || "#eee";
 44             this.beginPath();
 45             this.moveTo(x, y);
 46             this.arc(x, y, radius, 0, Math.PI * 2, false);    // 標準畫圓
 47             this.fill();
 48         };
 49         
 50         // 獲得塗抹的百分比(此處參考了部分他人代碼,出處http://www.cnblogs.com/jscode/p/3580878.html)
 51         var getTransparentPercent = function (ctx, width, height) {
 52             var imgData = ctx.getImageData(0, 0, width, height),    // 獲得canvas的像素信息
 53                 pixles = imgData.data,
 54                 transPixs = [];
 55             for (var i = 0, j = pixles.length; i < j; i += 4) {    // 由於存儲的結構爲[R, G, B, A],因此要每次跳4個長度
 56                 var a = pixles[i + 3];    // 拿到存儲alpha通道的值
 57                 if (a === 0) {    // alpha通道爲0,就表明透明
 58                     transPixs.push(i);
 59                 }
 60             }
 61             return (transPixs.length / (pixles.length / 4) * 100).toFixed(2);
 62         }
 63         
 64         // 綁定事件(此處參考了部分他人代碼,出處http://www.cnblogs.com/jscode/p/3580878.html)
 65         // 須要判斷是PC仍是手機
 66         var device = /android|webos|iphone|ipad|ipod|blackberry|iemobile|opera mini/i.test(navigator.userAgent.toLowerCase()),
 67             clickEvtName = device ? 'touchstart' : 'mousedown',
 68             moveEvtName = device ? 'touchmove' : 'mousemove';
 69         
 70         // 判斷是否是開始觸摸等
 71         if (!device) {
 72             var isMouseDown = false;
 73             document.addEventListener('mouseup', function (e) {
 74                 isMouseDown = false;
 75             }, false);
 76         } else {
 77             document.addEventListener("touchmove", function (e) {
 78                 if (isMouseDown) {
 79                     e.preventDefault();
 80                 }
 81             }, false);
 82             document.addEventListener('touchend', function (e) {
 83                 isMouseDown = false;
 84             }, false);
 85         }
 86         
 87         // 開始移動
 88         cvs.addEventListener(clickEvtName, function (e) {
 89             isMouseDown = true;
 90             var x = (device ? e.touches[0].clientX : e.clientX);
 91             var y = (device ? e.touches[0].clientY : e.clientY);
 92             ctx.globalCompositeOperation = 'destination-out';    // 關鍵部分,描述當在canvas上再次繪畫時候的狀況,這個設置即是以前所說的透明
 93             fillCircle.call(ctx, x, y, touchRadius);
 94             console.log("當前塗抹比例爲:" + getTransparentPercent(ctx, 200, 100));
 95         }, false);
 96         
 97         // 移動中
 98         cvs.addEventListener(moveEvtName, function (e) {
 99             if (!device && !isMouseDown) {
100                 return false;
101             }
102             var x = (device ? e.touches[0].clientX : e.clientX);
103             var y = (device ? e.touches[0].clientY : e.clientY);
104             ctx.globalCompositeOperation = 'destination-out';
105             fillCircle.call(ctx, x, y, touchRadius);
106             console.log("當前塗抹比例爲:" + getTransparentPercent(ctx, 200, 100));
107         }, false);
108     </script>
109 </body>
110 
111 </html>

 

上面的代碼徹底是按照順序來寫的,因此應該很容易看懂的吧。其中關鍵的就是設置透明,還有就是設備的判斷。

Update:增長了一個判斷刮開了多少比例的代碼,由於實際需求極可能是刮開多少就告訴用戶刮獎結束。這裏,由於刮開的部分是「透明的」,在代碼中就是說RGBA顏色值中的A是透明的,經過getImageData方法能夠獲得每一個像素點的RGBA值,而後計算一下比例便可。在控制檯能夠看到刮開的比例數據。

至此,也算是用canva完成了第一個小效果了。

 

 

 

轉載本站文章請註明做者和出處 奇葩一朵朵 – http://www.cnblogs.com/season-huang/ ,請勿用於任何商業用途

相關文章
相關標籤/搜索