前言:最近幾個月來到新公司,主要從事移動端方面的開發,有時候也挺忙挺累的,因而就好一段時間沒寫博客了。其實本身在這幾個月裏,本身對canvas以及createjs和egret都有了必定程度上的認識與掌握了,因此有挺多東西想總結一下的。趁着今天廣州下雪的日子,就寫點東西吧,先從簡單的demo開始吧。由於本身在走HTML5遊戲方向,因此最近都在作小遊戲。後續會再寫關於canvas和createjs的系列文章吧,畢竟國內的資料比較少。一旦愛上了canvas,我便逐漸嫌棄DOM了。css
利用最簡單的多張圖片,讓產品實現360旋轉瀏覽效果。以往用DOM來實現圖片或者背景更換,是挺方便也容易,可是在移動端上面尤爲安卓系統,流暢度真讓人堪憂。並且如今移動端基本上都支持canvas上下文2d,因此能用canvas實現的儘可能避免使用DOM。固然,若是是數量或簡單少的動畫,仍是用CSS3比較好。交互操做類的當下則非canvas莫屬。html
首先是素材問題,圍繞商品的四周各拍幾張圖片,而後讓設計師從新修一下圖,最終分解成多張圖片素材。多則三四十張,小則十幾張,視狀況而定。要說明的是,我這裏用的只是替換圖片的方法實現仿3D旋轉,往後我會再寫一個僅需幾張圖片的3D全景瀏覽效果。前端
如圖所示(是否是不少,哈哈,簡單的方法實現確定要犧牲點什麼的,下次再寫另外的方法吧):web
HTML+CSS:canvas
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="UTF-8"> 5 <meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,minimum-scale=1.0,user-scalable=no" /> 6 <title>360度旋轉瀏覽</title> 7 <style type="text/css"> 8 *{ 9 margin: 0; 10 padding: 0; 11 } 12 body,html{ 13 width: 100%; 14 height: 100%; 15 overflow: hidden; 16 } 17 .loading{ 18 position: absolute; 19 width: 100%; 20 height: 100%; 21 left: 0; 22 top: 0; 23 background-color: #888888; 24 z-index: 10; 25 } 26 .loading img{ 27 position: relative; 28 width: 32px; 29 height: 32px; 30 left: 50%; 31 top: 50%; 32 margin-left: -16px; 33 margin-top: -16px; 34 } 35 canvas{ 36 width: 100%; 37 height: 100%; 38 z-index: 100; 39 } 40 </style> 41 </head> 42 <body> 43 <div class="loading"> 44 <img src="img/loading.gif"/> 45 </div> 46 <canvas id="canvas" width="750" height="1254">你的瀏覽器太老啦,換瀏覽器啦!</canvas> 47 <script src="js/zepto.min.js"></script> 48 </body> 49 </html>
1 var canvas = document.getElementById("canvas"), 2 DPR = window.devicePixelRatio,//獲取設備的物理像素比 3 viewW = window.innerWidth, 4 viewH = window.innerHeight, 5 cansW = viewW*DPR,//放大canvas 6 cansH = viewH*DPR, 7 ctx = canvas.getContext("2d"), 8 imgArr = [],//圖片數組 9 curDeg = 1,//表明當前顯示的圖片下標 10 imgTotal = 51,//圖片總數 11 imgRatio = (447/1000), //圖片高寬比 12 imgW = viewW*1.5,//圖寬 13 imgH = imgW*imgRatio;//圖高 14 15 //重設canvas寬高 16 //顯示的寬高 17 canvas.style.width = cansW + "px"; 18 canvas.style.height = cansH + "px"; 19 //畫布寬高 20 canvas.width = cansW; 21 canvas.height = cansH; 22 //loading 23 $(function(){ 24 var baseURL = "img/", 25 imgURL ="", 26 imgObj = null, 27 imgIndex = 1; 28 //loading 29 for(var i = 1;i <= imgTotal;i++){ 30 imgURL = baseURL + i + ".png"; 31 imgObj = new Image(); 32 imgObj.src = imgURL; 33 //將全部圖片對象壓入一個數組,方便調用 34 imgArr.push(imgObj); 35 imgObj.onload = function(){ 36 imgIndex ++; 37 if(imgIndex > 51){ 38 $(".loading").hide(); 39 //默認圖 40 drawImg(0); 41 } 42 } 43 } 44 //手指觸摸起點 45 var startPoint = 0, 46 //滑動多長距離,這裏取(canvas寬/圖片總數的一半) 47 //數值越大約靈敏 48 distance = cansW/30; 49 //開始 50 $("#canvas").on({ 51 "touchstart":function(e){ 52 //記錄起始觸摸點 53 startPoint = e.touches[0].clientX; 54 //去掉默認事件,iPhone下可去除雙擊頁面默認跳動(翻頁)效果 55 e.preventDefault(); 56 }, 57 "touchmove":function(e){ 58 var tempPoint = e.touches[0].clientX; 59 //向右移動 60 if((tempPoint - startPoint) > distance){ 61 drawImg(curDeg,"right"); 62 //符合距離條件移動後,將記錄點設到手指最新位置 63 startPoint = tempPoint; 64 }else if((tempPoint - startPoint) < -distance){//左 65 drawImg(curDeg,"left"); 66 startPoint = tempPoint; 67 } 68 //禁止移動頁面 69 e.preventDefault(); 70 } 71 }); 72 }); 73 //繪圖 74 //參數:圖片對象下標,移動方向 75 function drawImg(n,type){ 76 if(type == "left"){ 77 if(curDeg > 0){ 78 curDeg--; 79 }else{ 80 curDeg = 50; 81 } 82 }else if(type == "right"){ 83 if(curDeg < 50){ 84 curDeg++; 85 }else{ 86 curDeg = 0; 87 } 88 } 89 ctx.clearRect(0,0,cansW,cansH); 90 //參數:圖片對象,X偏移量,Y偏移量,圖寬,圖高 91 ctx.drawImage(imgArr[n],-(imgW-viewW)*0.5,(viewH-imgH)*0.5,imgW,imgH); 92 }
代碼說明:數組
對於canvas,我還想說明的是,在移動端使用canvas畫布,必定要記得處理DPR,DPR全稱是DevicePixelRatio(設備像素比)。意思是設備上物理像素和設備獨立像素(device-independent pixels (dips))的比例。也就是一個設備獨立像素(能夠理解爲CSS中的1px)至關於多少個物理像素。假如DPR=2,那麼CSS中的1px就至關於設備物理像素的2px。可是在Canvas繪圖中,畫布大小跟可視區域大小是不同的。可視區域大小會根據DPR大小進行調整,可是畫布大小並不會。例如DPR=2,我在retina屏中設置canvas的可視寬高等於畫布寬高,那麼畫布裏的1px會在retina屏上以2px展現,因此會致使模糊現象。瀏覽器
關於DPR和view的參考文章:移動前端開發之viewport的深刻理解ide
因此爲了解決模糊問題,咱們須要根據DPR對畫布寬高進行調整,讓畫布大小等於物理像素大小。也就是把canvas的寬高變成對應的物理像素大小,而後把真正須要顯示的區域畫在屏幕位置,其他的隱藏掉。如圖所示:post
另外,DPR經過window.devicePixelRatio便可獲取,基於webkit的瀏覽器都支持,IE不支持。動畫
再者,這裏的滑動我使用了原生方法touchstart和touchmove觸摸事件,經過記錄手指起點以及終點的X軸座標大小判斷左右滑動。若是加入了zepto的TOUCH組件,則能夠直接使用swipeLeft和swipeRight觸發(拖動使用drag),從而改變相應的圖片。
關於繪圖:
使用drawImage()方法繪圖,還要注意的是,必定要待圖片徹底加載後才能進行繪圖,不然會報錯。
請使用移動設備或者谷歌瀏覽器的手機模式打開。