爲了獲取客戶、回饋客戶,平臺通常會推出抽獎活動類的營銷頁。所以web頁面中,有各式各樣的抽獎效果。javascript
格子式(九宮格),背景滾動式(數字/文字/圖案),旋轉式(轉盤),遊戲式(砸蛋/拼圖...)......css
這裏來說解下轉盤抽獎效果。html
當用戶進入這個抽獎頁面時,通常會「華麗」的設計所吸引,雖然明知中獎概率幾乎等於0,圖個運氣,都會去點「開始抽獎」,因而「折騰」開始了。java
你尚未登陸,請登陸後再來web
你尚未抽獎資格,請作作「什麼」後再來ajax
你的抽獎機會用完了,請明天再來dom
很抱歉,你沒有中獎ide
。。。函數
來看下效果:動畫
在BKY預覽效果無語了,彈出插件都不彈出了。
實際是這樣的:
貼上代碼,僅供參考:
頁面代碼:
<!doctype html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/> <title>旋轉-轉盤-抽獎</title> <style type="text/css"> *{margin: 0; padding: 0;} #ww_page{ overflow:hidden; width:100%;} #ww_rotate{position: relative; margin: 0 auto; width:640px; height:640px; } #ww_plate{position:absolute; top:0; left:0;width:640px; height:640px; background:url(http://i13.tietuku.com/416f769edc909de0.png) center no-repeat;background-size: 100% 100%; transition: none;} #ww_arrow{position:absolute; top:205px; left:50%; z-index: 10;margin-left: -75px;width:150px;height:190px; background:url(http://i13.tietuku.com/0e0b1c875d346f4d.png) center no-repeat; } </style> </head> <body> <div id="ww_page"> <div id="ww_box"> <div id="ww_rotate"> <div id="ww_plate"></div> <div id="ww_arrow"></div> </div> </div> </div> <link rel="stylesheet" type="text/css" href="js/Tips/mTips.css" /> <script type="text/javascript" src="js/Tips/mTips.min.js"></script> <script type="text/javascript" src="js/utils.js"></script> <script type="text/javascript" src="mRotate.js"></script> <script type="text/javascript"> //縮放 scalePage('#ww_box'); // 獎品數據 var prizeData = [ { id: 1, prize: "一等獎", angle: 3600 }, { id: 2, prize: "二等獎", angle: 3720 }, { id: 3, prize: "三等獎", angle: 3840 }, { id: 4, prize: "再接再礪", angle: 3750 }, { id: 5, prize: "要加油哦", angle: 3865 }, { id: 6, prize: "謝謝參與", angle: 3930 } ]; //旋轉 var arrow = document.getElementById('ww_arrow'), plate = document.getElementById('ww_plate'), isRotate = false; arrow.onclick = function() { if (isRotate) return; isRotate = true; var num = (Math.random() * prizeData.length) >> 0, data = prizeData[num]; // console.log(num); // console.time('計時'); new Rotate({ el: plate, //angle: 90, animateTo: data.angle, duration: 5000, easeing: 'easeInOutCirc', end: function() { // console.timeEnd('計時'); isRotate = false; Tips.alert(data.prize); } }); }; </script> </body> </html>
旋轉主程序mRotate.js
/** * LBS Rotate * Date: 2014-12-20 * ================================== * opts.el 旋轉對象(一個字符串的CSS選擇器或者元素對象) * opts.angle 初始角度 默認0 * opts.animateTo 目標角度 * opts.duration 持續時間 默認1000(毫秒) * opts.easing 動畫效果 (easeOutSine默認 easeInOutSine easeInOutCirc) * opts.end 旋轉完成 執行函數 * ================================== **/ var Rotate = function(opts) { opts = opts || {}; if (typeof opts.el === undefined) return; this.el = typeof opts.el === 'string' ? document.querySelector(opts.el) : opts.el; this.angle = opts.angle || 0; this.animateTo = opts.animateTo || this.angle + 360; this.duration = opts.duration || 1000; this.easing = (opts.easing && this.tween[opts.easing]) || this.tween.easeOutSine; this.end = opts.end || function() {}; this.animated = false; this.init(); }; Rotate.prototype = { init: function() { this.rotate(this.angle); this.start(); }, start: function() { this.animate(); }, animate: function() { if (this.animated) return; var start = this.angle, end = this.animateTo, change = end - start, duration = this.duration, startTime = +new Date(), ease = this.easing, _this = this; if (start == end) { this.end && this.end(); return; } this.animated = true; ! function animate() { var nowTime = +new Date(), timestamp = nowTime - startTime, delta = ease(timestamp / duration); _this.rotate(start + delta * change); if (duration <= timestamp) { _this.rotate(end); _this.animated = false; _this.end && _this.end(); } else { setTimeout(animate, 17); } }(); }, rotate: function(angle) { this.setTransform(angle % 360); }, setTransform: function(v) { v = v || 0; this.setStyle(this.el, 'transform', 'rotate(' + v + 'deg)'); }, setStyle: function(el, p, v) { !this.cache && (this.cache = {}); !this.cache[el] && (this.cache[el] = {}); !this.cache[el][p] && (this.cache[el][p] = this.prefix(p)); el.style[this.cache[el][p] || this.prefix(p)] = v; }, prefix: function(p) { var style = document.createElement('div').style; if (p in style) return p; var prefix = ['webkit', 'Moz', 'ms', 'O'], i = 0, l = prefix.length, s = ''; for (; i < l; i++) { s = prefix[i] + '-' + p; s = s.replace(/-\D/g, function(match) { return match.charAt(1).toUpperCase(); }); if (s in style) return s; } }, tween: { easeOutSine: function(pos) { return Math.sin(pos * (Math.PI / 2)); }, easeInOutSine: function(pos) { return (-.5 * (Math.cos(Math.PI * pos) - 1)); }, easeInOutCirc: function(pos) { if ((pos /= 0.5) < 1) return -0.5 * (Math.sqrt(1 - pos * pos) - 1); return 0.5 * (Math.sqrt(1 - (pos -= 2) * pos) + 1); } } };
很簡單的代碼,就是一個動畫函數,改變元素的旋轉rotate屬性。
CSS3 transform 屬性:http://www.w3school.com.cn/cssref/pr_transform.asp
動畫函數以下,得到元素的初始角度(起點),目標角度(終點),要多久(持續的時間),動畫效果(緩動公式)
animate: function() { if (this.animated) return; var start = this.angle, //起點 end = this.animateTo, //目的地 change = end - start, //距離 duration = this.duration, //持續時間 startTime = +new Date(), ease = this.easing, //運動效果 _this = this; if (start == end) { this.end && this.end(); return; } this.animated = true; !function animate() { var nowTime = +new Date(), timestamp = nowTime - startTime, delta = ease(timestamp / duration); _this.rotate(start + delta * change); if (duration <= timestamp) { _this.rotate(end); _this.animated = false; _this.end && _this.end(); } else { setTimeout(animate, 17); } }(); }
設置旋轉屬性
rotate: function(angle) { this.setTransform(angle % 360); }, setTransform: function(v) { v = v || 0; this.setStyle(this.el, 'transform', 'rotate(' + v + 'deg)'); }, setStyle: function(el, p, v) { !this.cache && (this.cache = {}); !this.cache[el] && (this.cache[el] = {}); !this.cache[el][p] && (this.cache[el][p] = this.prefix(p)); el.style[this.cache[el][p] || this.prefix(p)] = v; }, prefix: function(p) { var style = document.createElement('div').style; if (p in style) return p; var prefix = ['webkit', 'Moz', 'ms', 'O'], i = 0, l = prefix.length, s = ''; for (; i < l; i++) { s = prefix[i] + '-' + p; s = s.replace(/-\D/g, function(match) { return match.charAt(1).toUpperCase(); }); if (s in style) return s; } }
實際抽獎流程:點擊抽獎按鈕,發送ajax,獲得一個結果數據,執行抽獎程序,顯示結果。
瞭解動畫函數,結合緩動公式,是作出各類炫酷的效果的基礎。