轉盤式抽獎的第一個問題是隨機數個獎品在轉盤上的定位,固然每一個點的座標是能夠計算出來的:css
不過在js中不須要這麼繁瑣,有n個獎品,一個圓360度,因此每一個獎品之間的夾角是 360 / (n - 1)度,也就是說每一個獎品相對中心旋轉必定角度就能夠了。html
若是在canvas中那麼能夠自定義中心位置,若是用js的話,我目前爲了演示採起的作法是每一個點絕對定位在父元素頂部的中部(0, 50%),設置高度和父元素相同,這樣變形原點就在父元素的(50%,50%)處了(不改動transform-origin的話)。node
跑馬燈式抽獎效果的實現要簡單許多,由於原理就是將當前的高亮元素重置,並使下一個元素高亮,這樣能夠在setInerval()中根據高亮次數(每一個元素高亮一次,次數加1)來調整間隔。轉盤式抽獎的問題在於轉盤減速到選中獎品這個過程當中角度差別最大達到360度,因此抽獎間隔不是很好控制。因此最終我把減速這段效果給去除了。web
我估計用canvas實現轉盤式旋轉抽獎的效果要容易不少,canvas能夠定義原點,並且能夠很方便的繪製扇形(2直線+1圓弧)。canvas
給出的代碼裏各位不能自定義獎品的樣式,由於li標籤的樣式是用來保證變形原點的,固然能夠在li標籤內加上一個span標籤,在span標籤內自定義獎品樣式或者用圖片,若是這樣實現的話,那麼推薦在操做DOM的時候使用innerHTML,相似innerHTML += 'xxx',而後一次性加到父元素的節點下,我這裏給個演示圖片:瀏覽器
下面給出代碼,目前的抽獎效果不是很好,以後會想一想換用animaion來實現。app
<!doctype html> <html> <head> <meta charset="utf-8"> <title>lottery</title> <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"> <meta name="format-detection" content="telephone=no"> <meta name="apple-mobile-web-app-capable" content="yes"> <meta name="apple-mobile-web-app-status-bar-style" content="black"> <style> /*css reset*/ html{font-family:"Helvetica Neue",Helvetica,STHeiTi,sans-serif;-webkit-text-size-adjust:100%;-moz-text-size-adjust:100%;-ms-text-size-adjust:100%;} body{-webkit-overflow-scrolling:touch;margin:0;} ul{margin:0;padding:0;list-style:none;outline:none;} dl,dd{margin:0;} a{display:inline-block;margin:0;padding:0;text-decoration:none;background:transparent;outline:none;color:#000;} a:link,a:visited,a:hover,a:active{text-decoration:none;color:currentColor;} a,dt,dd{-webkit-touch-callout:none;-webkit-tap-highlight-color:transparent;} img{border:0;} p{margin:0;} input,button,select,textarea{margin:0;padding:0;border:0;outline:0;background-color:transparent;} /*css*/ body { height: 100vh; text-align: center; } .wrapper { margin: 0 auto; padding: 40px 0; max-width: 750px; } .wrapper .lottery { position: relative; display: inline-block; width: 600px; height: 600px; border: 1px solid #f0f0f0; border-radius: 50%; background-color: #f0f0f0; box-sizing: border-box; } .wrapper .lottery .list { position: absolute; top: 0; left: 300px; width: 0; height: 600px; } </style> </head> <body> <div class="wrapper"> <ul class="lottery"> </ul> </div> <script> var doc = document, fragment = doc.createDocumentFragment(), $ = function(node) { return doc.querySelector(node); }; var lotteryList = [0, 1, 2, 3, ,4], length = lotteryList.length, averRotate = 360 / (length - 1); lotteryList.forEach(function(i) { var node = doc.createElement('li'); node.setAttribute('id', 'list' + i); node.setAttribute('class', 'list'); node.innerHTML = i; fragment.appendChild(node); }) $('.lottery').appendChild(fragment); lotteryList.forEach(function(i) { $('#list' + i).style.transform = 'rotate(' + i * averRotate + 'deg)'; }) var speed = 40, i = 0, angle = 0, drawn = Math.floor(Math.random() * length); lotteryTimer = setInterval(lotterFunc, speed); function lotterFunc() { $('.lottery').style.transform = 'rotate(' + ++angle + 'deg)'; if (angle % 360 == 0) { i++; } if ((angle % 5 == 0) && speed > 10) { clearInterval(lotteryTimer); speed -= 1; lotteryTimer = setInterval(lotterFunc, speed); } else if (angle == (720 + drawn * averRotate)) { clearInterval(lotteryTimer); } } </script> </body> </html>
2017年7月2日補充:dom
嘗試了一下用canvas繪製一個抽獎的轉盤,canvas我只會基礎:spa
<!doctype html> <html> <head> <meta charset="utf-8"> <title>lottery</title> <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"> <meta name="format-detection" content="telephone=no"> <meta name="apple-mobile-web-app-capable" content="yes"> <meta name="apple-mobile-web-app-status-bar-style" content="black"> <style> /*css reset*/ html{font-family:"Helvetica Neue",Helvetica,STHeiTi,sans-serif;-webkit-text-size-adjust:100%;-moz-text-size-adjust:100%;-ms-text-size-adjust:100%;} body{-webkit-overflow-scrolling:touch;margin:0;} ul{margin:0;padding:0;list-style:none;outline:none;} dl,dd{margin:0;} a{display:inline-block;margin:0;padding:0;text-decoration:none;background:transparent;outline:none;color:#000;} a:link,a:visited,a:hover,a:active{text-decoration:none;color:currentColor;} a,dt,dd{-webkit-touch-callout:none;-webkit-tap-highlight-color:transparent;} img{border:0;} p{margin:0;} input,button,select,textarea{margin:0;padding:0;border:0;outline:0;background-color:transparent;} /*css*/ body { height: 100vh; text-align: center; } .wrapper { margin: 0 auto; padding: 40px 0; max-width: 750px; } </style> </head> <body> <div class="wrapper"> <canvas id="lottery" width="600" height="600"> 您的瀏覽器不支持canvas </canvas> </div> <script> var img = new Image(); img.src = '1.png'; var lotteryArr = [0, 1, 2, 3, 4, 5, 6]; var averRotate = 2 * Math.PI / (lotteryArr.length - 1); var lottery = document.getElementById('lottery'); var ctx = lottery.getContext('2d'); ctx.translate(300, 300); ctx.beginPath(); ctx.arc(0, 0, 280, 0, 2 * Math.PI); ctx.stroke(); ctx.closePath(); ctx.strokeStyle = 'rgba(0, 0, 0, .2)'; img.onload = function() { ctx.beginPath(); lotteryArr.forEach(function(data, i) { ctx.save(); ctx.rotate(averRotate * i); ctx.moveTo(0, 0); ctx.lineTo(0, - 280); ctx.stroke(); ctx.restore(); ctx.save(); ctx.rotate(averRotate * (i + 1 / 2)); ctx.drawImage(img, -25, 180, 50, 50); ctx.restore(); }) ctx.closePath(); } ctx.fillStyle = '#f50505'; ctx.strokeStyle = '#f50505'; ctx.beginPath(); ctx.arc(0, 0, 38, 0, 2 * Math.PI); ctx.stroke(); ctx.fill(); ctx.closePath(); ctx.beginPath(); ctx.moveTo(-25, 0); ctx.lineTo(0, -80); ctx.lineTo(25, 0); ctx.stroke(); ctx.fill(); ctx.closePath(); </script> </body> </html>