题目在此
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(‘http://images.cnitblog.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 ,谢谢!
大公司移动前端开发面试题——做转盘[参考代码]
时间: 2024-12-13 16:17:37