原生JS、CSS实现的转盘效果(目前仅支持webkit)
这是一个原生JS、CSS实现的转盘效果(题目在这:http://www.cnblogs.com/arfeizhang/p/turntable.html),花了半个小时左右,准备睡觉,所以先贴一段代码,预计会抽空优化,让它在手机上也能运行;另外,如果看代码的时候有什么问题,请留言。。。
1 <!DOCTYPE html> 2 <html> 3 4 <head> 5 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 6 <title>转盘</title> 7 <style> 8 .holder { 9 width: 550px; 10 display: block; 11 margin: 10px auto; 12 padding: 20px; 13 border: 3px solid black; 14 border-radius: 10px; 15 position: relative; 16 } 17 .rotate-pointer { 18 display: block; 19 position: absolute; 20 width: 521px; 21 line-height: 10px; 22 top: 270.5px; 23 left: 37px; 24 -webkit-transition:all 4s ease-in-out; 25 } 26 #rules { 27 width: 260.5px; 28 height: 10px; 29 display: inline-block; 30 background-color: black; 31 } 32 </style> 33 </head> 34 35 <body> 36 <div class="holder"> 37 <img src="//images0.cnblogs.com/i/636015/201406/151737329993303.jpg" alt=""> 38 <div id="pointer" class="rotate-pointer"> 39 <div id="rules"></div> 40 </div> 41 </div> 42 <script type="text/javascript"> 43 window.onload = function() { 44 var table = document.getElementsByClassName('holder')[0], 45 tablePointer = document.getElementById('pointer'), 46 getRandom = function(min, max) { 47 max = max || 1000; 48 min = min || 0; 49 return Math.floor(Math.random() * (max - min) + min); 50 }, 51 degree = 0, 52 min_circle_times = 2, 53 max_circle_times = 6, 54 translate = function() { 55 degree += getRandom(min_circle_times * 360, max_circle_times * 360); 56 57 requestAnimationFrame(function() { 58 tablePointer.style.webkitTransform = 'rotate(' + degree + 'deg)'; 59 }); 60 }; 61 table.onclick = translate; 62 63 }; 64 </script> 65 </body> 66 67 </html>
昨天放出上述内容后,收到题目博主的评论,发现好像有些地方不符合需求,恩,又再试了一个版本,这个版本目前是支持手机的,不过还是只能在webkit内核下使用哦,源码如下:
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>转盘</title> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"> <style> body { margin:0px; } .holder { text-align: center; overflow: hidden; display: block; margin: 10px auto; border: 3px solid black; border-radius: 10px; position: relative; } #table { cursor: pointer; display: inline-block; max-width: 521px; width: 100%; -webkit-transition:all 4s ease-in-out; } </style> </head> <body> <div class="holder"> <img id="table" src="//images0.cnblogs.com/i/631009/201406/181334125825974.png" alt=""> </div> <script type="text/javascript"> window.onload = function() { var degreeCount = 0, table = document.getElementById('table'), table_rect = table.getBoundingClientRect(), circle_center = { x: table_rect.width / 2 + table_rect.left, y: table_rect.height / 2 + table_rect.top }, min_circle_times = 2, max_circle_times = 6, getRandom = function(min, max) { max = max || 1000; min = min || 0; return Math.floor(Math.random() * (max - min) + min); }, // 根据两点求角度 getDegreeByPoint = function(start, enb) { var tan1 = (start.y - circle_center.y) / (start.x - circle_center.x), degree1 = Math.round(360 * Math.atan(tan1) / Math.PI), tan2 = (enb.y - circle_center.y) / (enb.x - circle_center.x), degree2 = Math.round(360 * Math.atan(tan2) / Math.PI); return -(degree1 - degree2); }, rotate_rings = 0, rotate = function(degree) { degree = degree - 0; if (Number.isNaN(degree)) { degree = degreeCount += getRandom(min_circle_times * 360, max_circle_times * 360); } else { degree += degreeCount; } requestAnimationFrame(function() { table.style.webkitTransform = 'rotate(' + degree + 'deg)'; }); }; // 事件监听器 var InputListener = function(tableId) { this.tableId = tableId; this.events = {}; if (window.navigator.msPointerEnabled) { //Internet Explorer 10 style this.eventTouchstart = "MSPointerDown"; this.eventTouchmove = "MSPointerMove"; this.eventTouchend = "MSPointerUp"; } else { this.eventTouchstart = "touchstart"; this.eventTouchmove = "touchmove"; this.eventTouchend = "touchend"; } this._beginListen(); }; InputListener.prototype = { on: function(event, callback) { if (!this.events[event]) { this.events[event] = []; } this.events[event].push(callback); }, emit: function(event, data) { var callbacks = this.events[event]; if (callbacks) { callbacks.forEach(function(callback) { callback(data); }); } }, _start: function(event) { this.emit("start", event); }, _rotate: function(event) { this.emit("rotate", event); }, _stop: function(event) { this.emit("stop", event); }, _celebrate: function(event) { this.emit("celebrate", event); }, _click: function(event) { this.emit("click", event); }, _getPointByEvent: function(event, toucherName) { toucherName = toucherName || 'touches'; var point = null; if (window.navigator.msPointerEnabled) { point = { x: event.pageX, y: event.pageY, time: Date.now() }; } else { point = { x: event[toucherName][0].clientX, y: event[toucherName][0].clientY, time: Date.now() }; } return point; }, _beginListen: function() { var self = this, table = document.getElementById(this.tableId), startPoint = null, movePath = []; // Respond to direction keys table.addEventListener('click', function(event) { self._click(); }); table.addEventListener(this.eventTouchstart, function(event) { if ((!window.navigator.msPointerEnabled && event.touches.length > 1) || event.targetTouches > 1) { return; // Ignore if touching with more than 1 finger } startPoint = self._getPointByEvent(event); movePath = [startPoint]; self._start({ start: startPoint }); event.preventDefault(); }); table.addEventListener(this.eventTouchmove, function(event) { var endpoint = self._getPointByEvent(event); if ( !! endpoint) { movePath.push(endpoint); self._rotate({ degree: getDegreeByPoint(startPoint, endpoint), start: startPoint, end: endpoint }); } event.preventDefault(); }); table.addEventListener(this.eventTouchend, function(event) { if ((!window.navigator.msPointerEnabled && event.touches.length > 0) || event.targetTouches > 0) { return; // Ignore if still touching with one or more fingers } var endpoint = self._getPointByEvent(event, 'changedTouches'), countToCal = 3, len = movePath.length; self._stop({ degree: getDegreeByPoint(startPoint, endpoint), start: startPoint, end: endpoint }); movePath.push(endpoint); if (len <= 3) { self._click({ start: startPoint }); } else { var p1 = movePath[len - 1], p2 = movePath[len - 1 - 3], // 转动的弧度 degree = getDegreeByPoint(p2, p1), time = p1.time - p2.time, speed = degree / time * 1000, // 速度转换为期望的周数,4指的是CSS动画时间 expectDegree = (speed * 4) + min_circle_times; self._celebrate({ start: p2, end: p1, degree: expectDegree }); } event.preventDefault(); }); } }; var listener = new InputListener('table'); listener.on('start', function(e) { table.style.webkitTransition = 'all 0s'; }); listener.on('rotate', function(e) { console.log(e.degree); rotate(e.degree); }); listener.on('stop', function(e) { degreeCount += e.degree; //degreeCount = degreeCount % 360; table.style.webkitTransition = 'all 4s ease-in-out'; }); listener.on('celebrate', function(e) { rotate(e.degree); }); listener.on('click', rotate); }; </script> </body> </html>
一个可以在线运行的地址:http://www.w3cfuns.com/home.php?mod=space&uid=5446932&do=blog&quickforward=1&id=5398670