先上效果图:
点击抽奖的时候,轮盘会转,圈数及时间自己设定,一共是两张图片,一个是奖品背景,一个是抽奖按钮。
html页面结构:
css结构:
*{
margin:0;
padding:0;
}
.wrapper{
position:relative;
width:400px;
height:400px;
margin:100px auto;
}
.wrapper .box{
width: 100%;
height: 100%;
}
.wrapper .box img{
width: 100%;
}
.wrapper #button{
width:130px;
height:130px;
position:absolute;
border-radius: 50%;
top: 50%;
left: 50%;
margin-top: -65px;
margin-left: -65px;
}
.wrapper #button img{
position: absolute;
top:-23px;
width:130px;
}
接下来是最主要的js部分,先说一下思路。
写法主要是模仿的jquery源码去写的,首先先来个立即执行函数,保证封闭作用域,将需要漏给外部需要引用的部分添加到window的属性中 。创建一个构造函数,将构造函数暴露到window对象中,用于后续调用。win接收window对象,$符号接收jquery$运算符。
(function(win , $){
win.Lottery = Lottery;
function Lottery(){
}
})(window , $)
思考 :转盘实现的过程,首先我们要知道点击的元素,点击按钮会触发大背景旋转,旋转结束之后会停留到某个奖项中,我们需要对几等奖做一个回调函数。如此我们的构造函数基本的对象已经可以出来了。
(function(win , $){
var defaultPar = {
rotate : 5 , // 旋转的圈数
body : 'body' , / / 默认的元素
clickCb : function(){}, / / 点击触发的事件
randerCb : function(){} // 旋转结束的回调
}
win.Lottery = Lottery;
function Lottery(pars){
this.pars = $.extend(true, {},defaultPar , pars); // 如果传值则覆盖原默认值,不传则用默认值。
}
})(window , $)
下面我们开始写构造函数的初始函数,我们需要为按钮添加点击事件,并且点击后会触发clickCb事件,及动画执行后的操作。并且我们需要有一个动画执行过程的函数,用于控制动画的显示效果。
(function(win , $){
var defaultPar = {
rotate : 5 ,
body : 'body' ,
clickCb : function(){},
randerCb : function(){}
}
win.Lottery = Lottery;
function Lottery(pars){
this.pars = $.extend(true, {},defaultPar , pars);
this.isDoing = false; // 开关,用于控制点击按钮之后不可重复点击
this.init(); // 初始化函数
}
Lottery.prototype.init = function(){
var $this = this; // 保留当前this 当前this指向Lottery对象
$(this.pars.body).on("click" , "#button" ,function(){ // 为按钮添加点击事件
if(!$this.isDoing){
$this.isDoing = true; // 如果已经点击一次,将开关闭合
$this.pars.clickCb(); // 执行clickCb() 点击的函数操作。
}
})
$(this.pars.body).find(".box").on("transitionend",function(){ // 动画旋转结束之后的操作
var deg = parseInt($($this.pars.body).attr("data-deg")); // 取出旋转的角度
$($this.pars.body).find(".box").css({
transform : "rotate("+ deg +"deg)", // 将旋转的角度重置
transition : "none" //重置回去,但是用户不可见
})
$this.isDoing = false; //动画结束,开关开启
$this.pars.randerCb(deg); // 动画结束执行回调函数
})
}
Lottery.prototype.goRotate = function(deg){ //接收旋转的角度
$(this.pars.body).attr("data-deg",deg); // 设置接收到的旋转角度,用于动画结束后重置
var rotateEnd = this.pars.rotateNum * 360 + deg; //需要旋转的角度,圈数乘以360度加上设置的角度
$(this.pars.body).find(".box").css({
transform : "rotate("+ rotateEnd +"deg)", //旋转动画的样式。
transition : "all 5s"
})
}
})(window , $)
至此我们插件所需要的功能都有了,那么现在开始调用 。
var pars = { // 传的参数,不传的话会用默认值,也就是defaultPar对象
rotateNum : "10",
body : ".wrapper",
clickCb : clickCbFun,
randerCb : randerCbFun
}
var lottery = new Lottery(pars); // 创建新对象继承构造函数属性方法。
function clickCbFun(){ //点击事件所走的函数。
var deg = Math.floor(Math.random() * 360); //设置所以的角度,360度随机取整
lottery.goRotate(deg); //执行动画操作,将设置的随机度数以参数传递。
}
function randerCbFun(deg){ //动画执行之后的回调函数,deg为旋转的角度,用来判断奖项
var str = "";
if(deg >= 0 && deg < 45){
str = "二等奖";
}else if(deg >=90 && deg<135 || deg >= 270 && deg <315 ){
str = "三等奖";
}else if(deg >=180 && deg < 225){
str = "一等奖";
}else{
str = "四等奖";
}
console.log("恭喜你获得:" + str);
}
本来打算好好写一写逻辑及思路的,弄一半就烦了,哈哈,以上全部功能都实现了,如果想加一些概率,可以在旋转动画goRotate中去判断设置的角度,然后让旋转角度+45,或者加多少都行,自己去控制吧,记得动画结束之后重置就可以了,如果对文中有不懂的地方可以留言,我看到的话会第一时间回复,对this指向不清楚的可以去看我的这篇面向对象查看this指向的规律。里面介绍的非常相信,想要源码及图片的可以留言你的邮箱,我会给你发过去,文中的大背景如果canvas功底好的话,可以用canvas去画,大体逻辑都是一样的。