題目在此
http://www.cnblogs.com/arfeizhang/p/turntable.html
這幾天一直在忙,終於找到時間把參考代碼放出來了。大家參考一下。
參考代碼考慮到讓入行不久的前端也看得懂,沒有進行封裝。變量名也沒有進行簡寫,盡量一看就明白。
圖片隨手在網上截的,也許沒有對准圓心。這段代碼只考慮了webkit內核的瀏覽器,沒做兼容。重在讓大家弄懂原理。 :P
如果感到有些卡幀,可能是轉盤圖片帶來的效果。在調試器上試過,能維持50-60幀,流暢度還是讓人滿意的。在LG G2和IPHONE 5上感覺很流暢,低配置手機上還沒試過。
建議在手機上轉着試下(PC上可以使用調試工具來模擬觸摸屏進行測試)。
示例鏈接:http://codepen.io/arfeizhang/full/qdxEe/
手機掃二維碼訪問:
代碼如下:
1 <!DOCTYPE HTML>
2 <html manifest="" lang="en-US">
3 <head>
4 <meta charset="UTF-8">
5 <!-- 用戶兩指操作時,防止放大 -->
6 <meta name="viewport" content="width=device-width,initial-scale=1, minimum-scale=1, maximum-scale=1, user-scalable=no,minimal-ui">
7 <title>Turnable</title>
8 <style>
9 #centerCircle{
10 border-radius: 125px;
11 background: url('https://images0.cnblogs.com/i/636015/201406/151737329993303.jpg') no-repeat;
12 background-size: 270px 260px;
13 background-position:-10px -4px;
14 width: 250px;
15 height: 250px;
16 position: absolute;
17 top: 126px;
18 left: 36px;
19 color: white;
20 z-index: 11;
21 -webkit-transform: rotateZ(0deg);
22 border: 1px solid #f60;
23 }
24 </style>
25 </head>
26 <body>
27 <div id="centerCircle">
28
29 </div>
30
31 Rotate me on mobile device! 32 <script type="text/javascript">
33 //先把DOM存起來,以后就不用再重新請求了,節省資源。
34 var eleCircle = document.querySelector("#centerCircle"); 35 //獲取圓心。注意,這里讀的是CSS樣式表中定義的樣式
36 var centerX = GetCircleStyle("left") + GetCircleStyle("width") / 2; 37 var centerY = GetCircleStyle("top") + GetCircleStyle("height") / 2; 38 //觸摸事件,有些人會用鼠標事件,但鼠標事件比觸摸事件慢,大概是300毫秒。300毫秒的延遲的原因,是因為瀏覽器需要判斷你是否需要雙擊縮放網頁。在后期的chrome版本中,如果在META信息中規定網頁滿屏展示(如viewport的寬度小於或等於物理設備的寬度),並不允許放大,可以消除鼠標300毫秒的延時,這點我沒驗證過。
39 eleCircle.addEventListener('touchstart', Start, false); 40 eleCircle.addEventListener('touchmove', Move, false); 41 eleCircle.addEventListener('touchend', End, false); 42
43 var touchStartX = touchStartY = 0, 44 touchMoveX = touchMoveY = 0; 45 // 這里定義兩個向量,用於計算角度和順逆時針
46 var vectorStart = { 47 x: 0, 48 y: 0
49 }, vectorEnd = { 50 x: 0, 51 y: 0
52 }; 53
54 function Start(e) { 55 e.preventDefault(); 56 touchStartX = e.touches[0].pageX; 57 touchStartY = e.touches[0].pageY; 58 vectorStart.x = touchStartX - centerX; 59 vectorStart.y = touchStartY - centerY; 60 } 61 var rotateDeg = 0; 62 var startDeg = 0; 63
64 function Move(e) { 65 // 阻止瀏覽器默認行為。不然在滾動轉盤時,會讓整個頁面滾動。
66 e.preventDefault(); 67 touchMoveX = e.touches[0].pageX; 68 touchMoveY = e.touches[0].pageY; 69 vectorEnd.x = touchMoveX - centerX; 70 vectorEnd.y = touchMoveY - centerY; 71 //旋轉角度=(開始向量和當前向量的夾角)*(是否是順時針轉)
72 rotateDeg = (RadianToDeg(CalcDeg(vectorStart, vectorEnd))) * (((vectorStart.x * vectorEnd.y - vectorStart.y * vectorEnd.x) < 0) ? -1 : 1); 73 //使用CSS3來進行旋轉
74 eleCircle.style.webkitTransform = "rotateZ(" + (startDeg + rotateDeg) + "deg)"; 75 } 76
77 function End(e) { 78 // 存入當前角度
79 startDeg = startDeg + rotateDeg; 80 rotateDeg = 0; 81 } 82 // 依據向量計算弧度
83 function CalcDeg(vectorStart, vectorEnd) { 84 var cosDeg = (vectorStart.x * vectorEnd.x + vectorStart.y * vectorEnd.y) / (Math.sqrt(Math.pow(vectorStart.x, 2) + Math.pow(vectorStart.y, 2)) * Math.sqrt(Math.pow(vectorEnd.x, 2) + Math.pow(vectorEnd.y, 2))); 85 return Math.acos(cosDeg); 86 } 87
88 function GetCircleStyle(attr) { 89 return GetNum(GetStyle(eleCircle, attr)) 90 } 91 // 取得對象的最終CSS屬性,這個最終是指瀏覽器自動計算的結果。
92 function GetStyle(obj, prop) { 93 if (obj.currentStyle) //IE
94 { 95 return obj.currentStyle[prop]; 96 } else if (window.getComputedStyle) //非IE
97 { 98 propprop = prop.replace(/([A-Z])/g, "-$1"); 99 propprop = prop.toLowerCase(); 100 return document.defaultView.getComputedStyle(obj, null)[propprop]; 101 } 102 return null; 103 } 104 // 從CSS屬性值(如10px)中取到數值(如10),以便計算
105 function GetNum(str) { 106 return parseInt(str.replace("px", "")); 107 } 108 // 弧度轉換為角度。因為Math.acos得到的是弧度,但CSS3 rotate需要角度
109 function RadianToDeg(radian) { 110
111 return 180 / Math.PI * radian; 112 } 113 </script>
114
115 </body>
116 </html>
本文是博主Arfei Zhang原創,歡迎轉載。轉載請注明轉自博客園,並附上本文鏈接http://www.cnblogs.com/arfeizhang/p/turntable_demo.html ,謝謝!