js幸运大转盘开发

最终效果实例下载:http://www.oschina.net/code/snippet_2352644_54997

 

一.大转盘准备工作

网上的一个抽奖大转盘实例http://www.jq22.com/yanshi2252

这就是我们要开发的效果,不过我们是让指针转,我们先分析这个效果:

  1. 结构有2部分,上面是指针背景图,下面是奖项图

  2. 点击指针元素开始抽奖,会转动一定圈数停下来

  3. 停下来的位置指针指使那个奖项,就会弹出获奖信息提示

这是参考效果,我们分析自己的大概实现:

  1. 同样上下2部分

  2. 点击指针转动,不过是指针动

  3. 转动一定圈数停止

  4. 根据指向弹出获奖信息

  5. 设置抽奖次数,假如只能三次

  6. 设置不同奖项中奖概率

在最后我们在写一个九宫格大转盘

 

二.如何转起来

转就是css3的2d旋转处理,css3就不写了,看下面。

 

三.静态结构搭建

问题出现了,那就是两张图,一个奖项图,一个指针图,不能设计不可怕,我们直接把参考效果的扒取下来就好了,省略下载操作,我们已经有图了,请下载。

back.png

js幸运大转盘开发_第1张图片

pointer.png

书写我们的静态结构,背景图目录看css设置:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>幸运大转盘抽奖</title>
    <style type="text/css">
/*reset*/
*{ padding:0; margin:0}
body{ height: 100%; width: 100%; font-size:12px; color:#333;}
ul{ list-style:none;}
/*demo*/
#box{ width:531px; height:531px; margin:50px auto;position:relative; background:url(images/back.png) no-repeat left top;}
#zhizhen{ width:174px; height:228px; position:absolute;background:url(images/pointer.png) no-repeat left top; 
left:178.5px; z-index:999; cursor:pointer; top:132.5px;
transform-origin:87px 133px;}
#zhizhen{animation:animations 2s linear infinite forwards;transform:rotate(0deg);}
@keyframes animations{
    0%{transform:rotate(0deg);}
    100%{transform:rotate(360deg);}
}
</style>
</head>
<body>
    <!--幸运大转盘抽奖-->
    <div id="box">
     <div id="zhizhen"></div>
    </div>
</body>
<script type="text/javascript">
window.onload=function(){
 //幸运大转盘抽奖
 
 
};
</script>
</html>

一个基于css3动画配合2d变化的旋转指针就出现了,下面我们将分析top ,left,旋转圆心为何如此设置的。

 

四.静态结构重要样式分析

红线的就是最核心样式,首先是top和left的设置:

js幸运大转盘开发_第2张图片

这不需要太多解释吧,篮框就是我们指针,我们摆正后测量就可以了,

注意:一定要1px无偏差摆正,不然旋转时就跑偏了!

我们把指针已经放在中心位置,因为图不是正方形,需要具体测量,可见把指针处理为正方形会大大简化我们的处理。

js幸运大转盘开发_第3张图片

这就是旋转圆心位置,指针是非正方形,我们的测量位置就是在中心圆中心,不过y要加上偏差。

什么是旋转圆心?我们在桌子上摆好一个日记本,然后按住一个点,日记本转动,按住的点就是圆心。

为了测试是否可以不跑偏的转动,我们结合动画进行测试。

 

五.利用js开始转起来

我们利用动画已经不停的转了起来,利用js我们如何转动?

一说到js,还说到动,我们要瞬间想到setInterval函数,我们利用间隔函数,动态的不断修改2d变化旋转的角度大小,就可以转起来了,我们同样加入事件的处理,点击后触发转动:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>幸运大转盘抽奖</title>
    <style type="text/css">
/*reset*/
*{ padding:0; margin:0}
body{ height: 100%; width: 100%; font-size:12px; color:#333;}
ul{ list-style:none;}
/*demo*/
#box{ width:531px; height:531px; margin:50px auto;position:relative; background:url(images/back.png) no-repeat left top;}
#zhizhen{ width:174px; height:228px; position:absolute;background:url(images/pointer.png) no-repeat left top; 
left:178.5px; z-index:999; cursor:pointer; top:132.5px;
transform-origin:87px 133px;transform:rotate(0deg);}
</style>
</head>
<body>
    <!--幸运大转盘抽奖-->
    <div id="box">
     <div id="zhizhen"></div>
    </div>
</body>
<script type="text/javascript">
window.onload=function(){
 //幸运大转盘抽奖
 //获得指针元素
 var zhizhen=document.getElementById("zhizhen");
 //存放间隔动画id,用来清除运动
 var dbox=null;
 //间隔动画所用时间,表示转动快慢
 var dtime=2;
 //角度,和css设置对应,初始为0
 var deg=0;
 //变化增量
 var cc=2;
 //监听点击事件
 zhizhen.onclick=function(){
  dbox=setInterval(dong,dtime);
 };
 function dong(){
  deg+=cc;
  zhizhen.style.transform="rotate(" + deg + "deg)";
 }
 
};
</script>
</html>

 

六.转动一定角度后停止

我们知道,转一定圈数后,是要停止的,停止的位置根据指向,会弹出中奖信息提示,先说转,我们是从0一直增加,一说停止肯定是到一个角度不动了,假如是1460角度停止。

换算成圈数就是360度*4圈 +20度,就是赚了4圈多20度。

既然是停止,我们只要到1460时清除间隔函数就可以了,clearInteval的使用,传入间隔id。

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>幸运大转盘抽奖</title>
    <style type="text/css">
/*reset*/
*{ padding:0; margin:0}
body{ height: 100%; width: 100%; font-size:12px; color:#333;}
ul{ list-style:none;}
/*demo*/
#box{ width:531px; height:531px; margin:50px auto;position:relative; background:url(images/back.png) no-repeat left top;}
#zhizhen{ width:174px; height:228px; position:absolute;background:url(images/pointer.png) no-repeat left top; 
left:178.5px; z-index:999; cursor:pointer; top:132.5px;
transform-origin:87px 133px;transform:rotate(0deg);}
</style>
</head>
<body>
    <!--幸运大转盘抽奖-->
    <div id="box">
     <div id="zhizhen"></div>
    </div>
</body>
<script type="text/javascript">
window.onload=function(){
 //幸运大转盘抽奖
 //获得指针元素
 var zhizhen=document.getElementById("zhizhen");
 //存放间隔动画id,用来清除运动
 var dbox=null;
 //间隔动画所用时间,表示转动快慢
 var dtime=2;
 //角度,和css设置对应,初始为0
 var deg=0;
 //变化增量
 var cc=2;
 //停止时的角度
 var stopdeg=1460; 
 //监听点击事件
 zhizhen.onclick=function(){
  dbox=setInterval(dong,dtime);
 };
 function dong(){
  deg+=cc;
  if(deg>stopdeg){
   clearInterval(dbox);
  }else{
   zhizhen.style.transform="rotate(" + deg + "deg)";
  };  
 }
 
};
</script>
</html>

 

六.停止角度转为圈数+角度

我们上面也提到了1460就是4圈+20度,这个停止角度如此表示之后

//旋转基本圈数
 var quan=4;
 //多余角度
 var odeg=20;
 //停止时的角度
 var stopdeg=quan*360+odeg;

采用这种设置以后,我们可以自定义旋转圈数,比如基本圈数是6圈,同样停止额外角度也可自定义,比如是80度:

//旋转基本圈数
 var quan=6;
 //多余角度
 var odeg=80;
 //停止时的角度
 var stopdeg=quan*360+odeg;

下面是修改后的代码:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>幸运大转盘抽奖</title>
    <style type="text/css">
/*reset*/
*{ padding:0; margin:0}
body{ height: 100%; width: 100%; font-size:12px; color:#333;}
ul{ list-style:none;}
/*demo*/
#box{ width:531px; height:531px; margin:50px auto;position:relative; background:url(images/back.png) no-repeat left top;}
#zhizhen{ width:174px; height:228px; position:absolute;background:url(images/pointer.png) no-repeat left top; 
left:178.5px; z-index:999; cursor:pointer; top:132.5px;
transform-origin:87px 133px;transform:rotate(0deg);}
</style>
</head>
<body>
    <!--幸运大转盘抽奖-->
    <div id="box">
     <div id="zhizhen"></div>
    </div>
</body>
<script type="text/javascript">
window.onload=function(){
 //幸运大转盘抽奖
 //获得指针元素
 var zhizhen=document.getElementById("zhizhen");
 //存放间隔动画id,用来清除运动
 var dbox=null;
 //间隔动画所用时间,表示转动快慢
 var dtime=2;
 //角度,和css设置对应,初始为0
 var deg=0;
 //变化增量
 var cc=2;
 //旋转基本圈数
 var quan=6;
 //多余角度
 var odeg=80;
 //停止时的角度
 var stopdeg=quan*360+odeg; 
 //监听点击事件
 zhizhen.onclick=function(){
  dbox=setInterval(dong,dtime);
 };
 function dong(){
  deg+=cc;
  if(deg>stopdeg){
   clearInterval(dbox);
  }else{
   zhizhen.style.transform="rotate(" + deg + "deg)";
  };  
 }
 
};
</script>
</html>

 

六.奖项依据

还是上面的延续,我们设置是6圈+80度,其实6圈我们不用考虑,只是让用户感觉在抽奖的假象,这个80才是我们真实考虑的东西,因为他代表在转盘上指针停在了哪里,要通过停在的位置弹出获奖信息:

js幸运大转盘开发_第4张图片

80度的位置和其实参考如图所示。

毫无疑问,0-6这7个奖项在0-360之间各占一定的区间,我们需要测量出来,例如:

0等奖:0-50度

6等奖:51-101度 等等一次类推

我们选择的图毫无疑问是失败的,若果是6等分,我们直接就算出来了(360*6),可是7份(360/7尴尬)的就要实际测量:

//区间奖项 
var jiang=[
  [1,51,"未中奖"], //未中奖
  [52,102,"6等奖"],//6等奖
  [103,153,"5等奖"],//5等奖
  [154,203,"4等奖"],//4等奖
  [204,251,"3等奖"],//3等奖
  [252,307,"2等奖"],//2等奖
  [307,360,"1等奖"]//1等奖
 ];

我们奖项和角度对应关系,我们现在是80度,那么就是6等奖

 

六.奖项判断

我们会在80度位置停止,我们的依据就是上面的数组,我们要写一个判定函数,去自动判断是几等奖,这样就非常的方便了,我们把80改为150也许自己判定结果。

//奖项判定函数
 function is(deg){
  var res="未中奖";
  for(var i=0;i<jiang.length;i++){
   if(deg>=jiang[i][0] && deg<jiang[i][1]){
    res=jiang[i][2];
   };
  };
  return res;
 };

我们在停止时弹出提示

if(deg>stopdeg){
   clearInterval(dbox);
   alert(is(odeg));
  }else{
   zhizhen.style.transform="rotate(" + deg + "deg)";
  };

修改后全部代码:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>幸运大转盘抽奖</title>
    <style type="text/css">
/*reset*/
*{ padding:0; margin:0}
body{ height: 100%; width: 100%; font-size:12px; color:#333;}
ul{ list-style:none;}
/*demo*/
#box{ width:531px; height:531px; margin:50px auto;position:relative; background:url(images/back.png) no-repeat left top;}
#zhizhen{ width:174px; height:228px; position:absolute;background:url(images/pointer.png) no-repeat left top; 
left:178.5px; z-index:999; cursor:pointer; top:132.5px;
transform-origin:87px 133px;transform:rotate(0deg);}
</style>
</head>
<body>
    <!--幸运大转盘抽奖-->
    <div id="box">
     <div id="zhizhen"></div>
    </div>
</body>
<script type="text/javascript">
window.onload=function(){
 //幸运大转盘抽奖
 //获得指针元素
 var zhizhen=document.getElementById("zhizhen");
 //存放间隔动画id,用来清除运动
 var dbox=null;
 //间隔动画所用时间,表示转动快慢
 var dtime=2;
 //角度,和css设置对应,初始为0
 var deg=0;
 //变化增量
 var cc=2;
 //旋转基本圈数
 var quan=6;
 //多余角度
 var odeg=80;
 //停止时的角度
 var stopdeg=quan*360+odeg;
 //区间奖项 
var jiang=[
  [1,51,"未中奖"], //未中奖
  [52,102,"6等奖"],//6等奖
  [103,153,"5等奖"],//5等奖
  [154,203,"4等奖"],//4等奖
  [204,251,"3等奖"],//3等奖
  [252,307,"2等奖"],//2等奖
  [307,360,"1等奖"]//1等奖
 ]; 
 //奖项判定函数
 function is(deg){
  var res="未中奖";
  for(var i=0;i<jiang.length;i++){
   if(deg>=jiang[i][0] && deg<jiang[i][1]){
    res=jiang[i][2];
   };
  };
  return res;
 };
 //监听点击事件
 zhizhen.onclick=function(){
  dbox=setInterval(dong,dtime);
 };
 function dong(){
  deg+=cc;
  if(deg>stopdeg){
   clearInterval(dbox);
   alert(is(odeg));
  }else{
   zhizhen.style.transform="rotate(" + deg + "deg)";
  };  
 }
 
};
</script>
</html>

 

七.随机奖项生成

80度也就是6等奖,这个80度我们写死是不对的,应该产生一个0-360随机度数,这样每次抽奖就会随机中奖了,针对随机数的生成,是有固定写法的,比如生成0-8的随机数,那么就是:

var odeg=Math.floor(Math.random()*10);

0-360就是照猫画虎:

var odeg=Math.floor(Math.random()*361);

修改后整体程序:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>幸运大转盘抽奖</title>
    <style type="text/css">
/*reset*/
*{ padding:0; margin:0}
body{ height: 100%; width: 100%; font-size:12px; color:#333;}
ul{ list-style:none;}
/*demo*/
#box{ width:531px; height:531px; margin:50px auto;position:relative; background:url(images/back.png) no-repeat left top;}
#zhizhen{ width:174px; height:228px; position:absolute;background:url(images/pointer.png) no-repeat left top; 
left:178.5px; z-index:999; cursor:pointer; top:132.5px;
transform-origin:87px 133px;transform:rotate(0deg);}
</style>
</head>
<body>
    <!--幸运大转盘抽奖-->
    <div id="box">
     <div id="zhizhen"></div>
    </div>
</body>
<script type="text/javascript">
window.onload=function(){
 //幸运大转盘抽奖
 //获得指针元素
 var zhizhen=document.getElementById("zhizhen");
 //存放间隔动画id,用来清除运动
 var dbox=null;
 //间隔动画所用时间,表示转动快慢
 var dtime=2;
 //角度,和css设置对应,初始为0
 var deg=0;
 //变化增量
 var cc=2;
 //旋转基本圈数
 var quan=4;
 //多余角度
 var odeg=Math.floor(Math.random()*361);
 //停止时的角度
 var stopdeg=quan*360+odeg;
 //区间奖项 
 var jiang=[
  [1,51,"未中奖"], //未中奖
  [52,102,"6等奖"],//6等奖
  [103,153,"5等奖"],//5等奖
  [154,203,"4等奖"],//4等奖
  [204,251,"3等奖"],//3等奖
  [252,307,"2等奖"],//2等奖
  [307,360,"1等奖"]//1等奖
 ];  //奖项判定函数
 function is(deg){
  var res="未中奖";
  for(var i=0;i<jiang.length;i++){
   if(deg>=jiang[i][0] && deg<jiang[i][1]){
    res=jiang[i][2];
   };
  };
  return res;
 };
 //监听点击事件
 zhizhen.onclick=function(){
  dbox=setInterval(dong,dtime);
 };
 function dong(){
  deg+=cc;
  if(deg>stopdeg){
   clearInterval(dbox);
   alert(is(odeg));
  }else{
   zhizhen.style.transform="rotate(" + deg + "deg)";
  };  
 }
 
};
</script>
</html>

 

八.重复性抽奖

//监听点击事件
 zhizhen.onclick=function(){
  deg=0;
  odeg=Math.floor(Math.random()*361);
  stopdeg=quan*360+odeg;
  dbox=setInterval(dong,dtime);
 };

只要每次点击,对初始化角度,随机角度和停止角度重新赋值即可。

我们快速点击指针,发现转的越来越快?

因为每次点击都会生成一个间隔函数,我们要判断当前是不是在抽奖中,如果处在抽奖中,点击是不会触发间隔函数的。

//是否在动画中
 var able=false;

在开启后转为true,表示抽奖中

function dong(){
  able=true;
  deg+=cc;
  if(deg>stopdeg){   
   clearInterval(dbox);        
   able=false; 
   alert(is(odeg));
  }else{
   zhizhen.style.transform="rotate(" + deg + "deg)";
  };  
 }

点击判断是否抽奖中

zhizhen.onclick=function(){
  if(!able){
   deg=0;
   odeg=Math.floor(Math.random()*361);
   stopdeg=quan*360+odeg;
   dbox=setInterval(dong,dtime);
  };
  
 };

全部代码:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>幸运大转盘抽奖</title>
    <style type="text/css">
/*reset*/
*{ padding:0; margin:0}
body{ height: 100%; width: 100%; font-size:12px; color:#333;}
ul{ list-style:none;}
/*demo*/
#box{ width:531px; height:531px; margin:50px auto;position:relative; background:url(images/back.png) no-repeat left top;}
#zhizhen{ width:174px; height:228px; position:absolute;background:url(images/pointer.png) no-repeat left top; 
left:178.5px; z-index:999; cursor:pointer; top:132.5px;
transform-origin:87px 133px;transform:rotate(0deg);}
</style>
</head>
<body>
    <!--幸运大转盘抽奖-->
    <div id="box">
     <div id="zhizhen"></div>
    </div>
</body>
<script type="text/javascript">
window.onload=function(){
 //幸运大转盘抽奖
 //获得指针元素
 var zhizhen=document.getElementById("zhizhen");
 //存放间隔动画id,用来清除运动
 var dbox=null;
 //间隔动画所用时间,表示转动快慢
 var dtime=2;
 //角度,和css设置对应,初始为0
 var deg=0;
 //变化增量
 var cc=2;
 //旋转基本圈数
 var quan=4;
 //多余角度
 var odeg=Math.floor(Math.random()*361);
 //停止时的角度
 var stopdeg=quan*360+odeg;
 //区间奖项 
 var jiang=[
  [1,51,"未中奖"], //未中奖
  [52,102,"6等奖"],//6等奖
  [103,153,"5等奖"],//5等奖
  [154,203,"4等奖"],//4等奖
  [204,251,"3等奖"],//3等奖
  [252,307,"2等奖"],//2等奖
  [307,360,"1等奖"]//1等奖
 ]; 
 //奖项判定函数
 function is(deg){
  var res="未中奖";
  for(var i=0;i<jiang.length;i++){
   if(deg>=jiang[i][0] && deg<=jiang[i][1]){
    res=jiang[i][2];
   };
  };
  return res;
 };
 //是否在动画中
 var able=false;
 //监听点击事件
 zhizhen.onclick=function(){
  if(!able){
   deg=0;
   odeg=Math.floor(Math.random()*361);
   stopdeg=quan*360+odeg;
   dbox=setInterval(dong,dtime);
  };
  
 };
 function dong(){
  able=true;
  deg+=cc;
  if(deg>stopdeg){   
   clearInterval(dbox);        
   able=false; 
   alert(is(odeg));
  }else{
   zhizhen.style.transform="rotate(" + deg + "deg)";
  };  
 }
 
};
</script>
</html>

 

九.抽奖次数限制

到上面,我们已经和参考效果几乎一样了,我们结合实际,一般用户只有3次机会,其实机会应该在数据库中,我们这里只是模拟处理,既然是限制次数,我们就要设置存放次数的变量:

//可用次数
 var cishu=3;

每次点击监听可用次数:

//监听点击事件
 zhizhen.onclick=function(){
  if(!able){
   if(cishu==0){
    alert("次数耗光,等待次啊次机会!");
   }else{
    cishu-=1;
    deg=0;
    odeg=Math.floor(Math.random()*361);
    stopdeg=quan*360+odeg;
    dbox=setInterval(dong,dtime);
   };
  };
  
 };

完整代码:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>幸运大转盘抽奖</title>
    <style type="text/css">
/*reset*/
*{ padding:0; margin:0}
body{ height: 100%; width: 100%; font-size:12px; color:#333;}
ul{ list-style:none;}
/*demo*/
#box{ width:531px; height:531px; margin:50px auto;position:relative; background:url(images/back.png) no-repeat left top;}
#zhizhen{ width:174px; height:228px; position:absolute;background:url(images/pointer.png) no-repeat left top; 
left:178.5px; z-index:999; cursor:pointer; top:132.5px;
transform-origin:87px 133px;transform:rotate(0deg);}
</style>
</head>
<body>
    <!--幸运大转盘抽奖-->
    <div id="box">
     <div id="zhizhen"></div>
    </div>
</body>
<script type="text/javascript">
window.onload=function(){
 //幸运大转盘抽奖
 //获得指针元素
 var zhizhen=document.getElementById("zhizhen");
 //存放间隔动画id,用来清除运动
 var dbox=null;
 //间隔动画所用时间,表示转动快慢
 var dtime=2;
 //角度,和css设置对应,初始为0
 var deg=0;
 //变化增量
 var cc=2;
 //旋转基本圈数
 var quan=4;
 //多余角度
 var odeg=Math.floor(Math.random()*361);
 //停止时的角度
 var stopdeg=quan*360+odeg;
 //区间奖项 
 var jiang=[
  [1,51,"未中奖"], //未中奖
  [52,102,"6等奖"],//6等奖
  [103,153,"5等奖"],//5等奖
  [154,203,"4等奖"],//4等奖
  [204,251,"3等奖"],//3等奖
  [252,307,"2等奖"],//2等奖
  [307,360,"1等奖"]//1等奖
 ]; 
 //可用次数
 var cishu=3;
 //奖项判定函数
 function is(deg){
  var res="未中奖";
  for(var i=0;i<jiang.length;i++){
   if(deg>=jiang[i][0] && deg<=jiang[i][1]){
    res=jiang[i][2];
   };
  };
  return res;
 };
 //是否在动画中
 var able=false;
 //监听点击事件
 zhizhen.onclick=function(){
  if(!able){
   if(cishu==0){
    alert("次数耗光,等待次啊次机会!");
   }else{
    cishu-=1;
    deg=0;
    odeg=Math.floor(Math.random()*361);
    stopdeg=quan*360+odeg;
    dbox=setInterval(dong,dtime);
   };
  };
  
 };
 function dong(){
  able=true;
  deg+=cc;
  if(deg>stopdeg){   
   clearInterval(dbox);        
   able=false; 
   alert(is(odeg));
  }else{
   zhizhen.style.transform="rotate(" + deg + "deg)";
  };  
 }
 
};
</script>
</html>

 

十.概率设置

中奖概率我们都听过,比如冰红茶,写着

1等奖 0.0008%

2等奖 0.05%

幸运奖 3.2%

我们实例有7个奖项,设置概率如下:

0   0.938%     

1   0.018%

2   0.014%

3   0.012%

4   0.008%

5   0.006%

6   0.004%

和是1就对了,我们开始跳出原有思维,我们如何应用上我们的概率?

我们现在有1000份,其中0-6 所对应份数就是上面乘以1000。

那么我们就建立这样一个长度是1000的数组,对0-6进行存放

var gailv=[[938,"未中奖"],[18,"6等奖"],[14,"5等奖"],[12,"4等奖"],[8,"3等奖"],[6,"2等奖"],[4,"1等奖"]];
var allarr=[];//长度1000,存放0-6 表示奖项
    for(var i=0;i<gailv.length;i++){
     for(var j=0;j<gailv[i][0];j++){
      allarr.push(gailv[i][1]);
     };
    };
    var real=allarr[Math.floor(Math.random()*1000)];

real存放的就是随机奖项,概率也是来自设置。

此时我们处理和未加入概率是反的,我们是先有了奖项,就是此时已经知道用户要用什么奖了,我们接着就要让客户看见,指针要停在这个奖项区间内,

比如我们利用概率是1等奖,那么生成的角度

odeg=Math.floor(Math.random()*361);

就应该固定在:

[307,360,"1等奖"]//1等奖

307到360之间,那么随机角度生成仅仅就是一个表现形式环节,我们修改如下产生额外角度:

//通过奖项设置额外角度的表现
 function set(real){
  var mindeg,maxdeg;
  for(var i=0;i<jiang.length;i++){
   if(real==jiang[i][2]){
    mindeg=jiang[i][0];
    maxdeg=jiang[i][1];
   };
  };
  return mindeg+Math.floor(Math.random()*(maxdeg-mindeg+1));
  
 };

赋值:

odeg=set(real);

全部代码:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>幸运大转盘抽奖</title>
    <style type="text/css">
/*reset*/
*{ padding:0; margin:0}
body{ height: 100%; width: 100%; font-size:12px; color:#333;}
ul{ list-style:none;}
/*demo*/
#box{ width:531px; height:531px; margin:50px auto;position:relative; background:url(images/back.png) no-repeat left top;}
#zhizhen{ width:174px; height:228px; position:absolute;background:url(images/pointer.png) no-repeat left top; 
left:178.5px; z-index:999; cursor:pointer; top:132.5px;
transform-origin:87px 133px;transform:rotate(0deg);}
</style>
</head>
<body>
    <!--幸运大转盘抽奖-->
    <div id="box">
     <div id="zhizhen"></div>
    </div>
</body>
<script type="text/javascript">
window.onload=function(){
 //幸运大转盘抽奖
 //获得指针元素
 var zhizhen=document.getElementById("zhizhen");
 //存放间隔动画id,用来清除运动
 var dbox=null;
 //间隔动画所用时间,表示转动快慢
 var dtime=2;
 //角度,和css设置对应,初始为0
 var deg=0;
 //变化增量
 var cc=2;
 //旋转基本圈数
 var quan=4;
 //多余角度
 var odeg=Math.floor(Math.random()*361);
 //停止时的角度
 var stopdeg=quan*360+odeg;
 //区间奖项 
 var jiang=[
  [1,51,"未中奖"], //未中奖
  [52,102,"6等奖"],//6等奖
  [103,153,"5等奖"],//5等奖
  [154,203,"4等奖"],//4等奖
  [204,251,"3等奖"],//3等奖
  [252,307,"2等奖"],//2等奖
  [307,360,"1等奖"]//1等奖
 ]; 
 //可用次数
 var cishu=3;
 //奖项判定函数
 function is(deg){
  var res="未中奖";
  for(var i=0;i<jiang.length;i++){
   if(deg>=jiang[i][0] && deg<=jiang[i][1]){
    res=jiang[i][2];
   };
  };
  return res;
 };
 //是否在动画中
 var able=false;
 //概率
 var gailv=[[938,"未中奖"],[18,"6等奖"],[14,"5等奖"],[12,"4等奖"],[8,"3等奖"],[6,"2等奖"],[4,"1等奖"]];
 //通过奖项设置额外角度的表现
 function set(real){
  var mindeg,maxdeg;
  for(var i=0;i<jiang.length;i++){
   if(real==jiang[i][2]){
    mindeg=jiang[i][0];
    maxdeg=jiang[i][1];
   };
  };
  return mindeg+Math.floor(Math.random()*(maxdeg-mindeg+1));
  
 };
 //监听点击事件
 zhizhen.onclick=function(){
  if(!able){
   if(cishu==0){
    alert("次数耗光,等待次啊次机会!");
   }else{
    cishu-=1;
    deg=0;
    var allarr=[];//长度1000,存放0-6 表示奖项
    for(var i=0;i<gailv.length;i++){
     for(var j=0;j<gailv[i][0];j++){
      allarr.push(gailv[i][1]);
     };
    };
    var real=allarr[Math.floor(Math.random()*1000)];
    odeg=set(real);
    stopdeg=quan*360+odeg;
    dbox=setInterval(dong,dtime);
   };
  };
  
 };
 function dong(){
  able=true;
  deg+=cc;
  if(deg>stopdeg){   
   clearInterval(dbox);        
   able=false; 
   alert(is(odeg));
  }else{
   zhizhen.style.transform="rotate(" + deg + "deg)";
  };  
 }
 
};
</script>
</html>

 

十一.最终实例1

上面的全部代码已经很完整的做到了效果交互,我们进一步做优化,让代码看起来更加整洁,去除无用的操作:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>幸运大转盘抽奖</title>
    <style type="text/css">
/*reset*/
*{ padding:0; margin:0}
body{ height: 100%; width: 100%; font-size:12px; color:#333;}
ul{ list-style:none;}
/*demo*/
#box{ width:531px; height:531px; margin:50px auto;position:relative; background:url(images/back.png) no-repeat left top;}
#zhizhen{ width:174px; height:228px; position:absolute;background:url(images/pointer.png) no-repeat left top; 
left:178.5px; z-index:999; cursor:pointer; top:132.5px;
transform-origin:87px 133px;}
</style>
</head>
<body>
    <!--幸运大转盘抽奖-->
    <div id="box">
     <div id="zhizhen"></div>
    </div>
</body>
<script type="text/javascript">
window.onload=function(){
 //幸运大转盘抽奖
 //获得指针元素
 var zhizhen=document.getElementById("zhizhen");
 //存放间隔动画id,用来清除运动
 var dbox=null;
 //间隔动画所用时间,表示转动快慢
 var dtime=1;
 //角度,和css设置对应,初始为0
 var deg=null;
 //初始角度
 var sdeg=0;
 //由js设置默认角度
 zhizhen.style.transform="rotate(" + sdeg + "deg)";
 //变化增量
 var cc=5;
 //旋转基本圈数
 var quan=4;
 //多余角度
 var odeg=null;
 //停止时的角度
 var stopdeg=null;
 //区间奖项 
 var jiang=[
  [1,51,"未中奖"], //未中奖
  [52,102,"6等奖"],//6等奖
  [103,153,"5等奖"],//5等奖
  [154,203,"4等奖"],//4等奖
  [204,251,"3等奖"],//3等奖
  [252,307,"2等奖"],//2等奖
  [307,360,"1等奖"]//1等奖
 ]; 
 //可用次数
 var cishu=3;
 //奖项判定函数
 function is(deg){
  var res="未中奖";
  for(var i=0;i<jiang.length;i++){
   if(deg>=jiang[i][0] && deg<=jiang[i][1]){
    res=jiang[i][2];
   };
  };
  return res;
 };
 //是否在动画中
 var able=false;
 //概率
 var gailv=[[938,"未中奖"],[18,"6等奖"],[14,"5等奖"],[12,"4等奖"],[8,"3等奖"],[6,"2等奖"],[4,"1等奖"]];
 //通过奖项设置额外角度的表现
 function set(real){
  var mindeg,maxdeg;
  for(var i=0;i<jiang.length;i++){
   if(real==jiang[i][2]){
    mindeg=jiang[i][0];
    maxdeg=jiang[i][1];
   };
  };
  return mindeg+Math.floor(Math.random()*(maxdeg-mindeg+1));//生成min-max的随机数
  
 };
 //监听点击事件
 zhizhen.onclick=function(){
  if(!able){
   if(cishu==0){//可用次数处理
    alert("次数耗光,等待次啊次机会!");
   }else{
    cishu-=1;//次数减少
    deg=sdeg;
    var allarr=[];//长度1000,存放0-6 表示奖项
    for(var i=0;i<gailv.length;i++){
     for(var j=0;j<gailv[i][0];j++){
      allarr.push(gailv[i][1]);
     };
    };
    var real=allarr[Math.floor(Math.random()*1000)];
    odeg=set(real);
    stopdeg=quan*360+odeg;
    dbox=setInterval(dong,dtime);
   };
  };
  
 };
 //大转盘转动函数
 function dong(){
  able=true;
  deg+=cc;
  if(deg>stopdeg){   
   clearInterval(dbox);           
   setTimeout(function(){
    able=false; 
    alert(is(odeg));
   },500)
  }else{
   zhizhen.style.transform="rotate(" + deg + "deg)";
  };  
 }
 
};
</script>
</html>

主要修改了弹出获奖信息会在500毫秒以后相应,更加的舒服。

 

十二.最终实例2

 对比参考,人家可是开始快,最后慢的,我们既然写了,就做到他功能好的我都有,他缺的功能我也有这一步:

我们就让最后一圈慢,额外的转动最慢就可以了。

起始圈数是0,每次到达360倍数时就会增加圈数,我们对圈数计数和修改增量:

if(deg%360==0){//判断第几圈
    xq+=1;
    if(xq==quan-1){//到最后一圈
     cc=1;//增量变为1 变慢旋转
    };
    zhizhen.style.transform="rotate(" + deg + "deg)";
   }else{
    zhizhen.style.transform="rotate(" + deg + "deg)";
   };

完整实例:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>幸运大转盘抽奖</title>
    <style type="text/css">
/*reset*/
*{ padding:0; margin:0}
body{ height: 100%; width: 100%; font-size:12px; color:#333;}
ul{ list-style:none;}
/*demo*/
#box{ width:531px; height:531px; margin:50px auto;position:relative; background:url(images/back.png) no-repeat left top;}
#zhizhen{ width:174px; height:228px; position:absolute;background:url(images/pointer.png) no-repeat left top; 
left:178.5px; z-index:999; cursor:pointer; top:132.5px;
transform-origin:87px 133px;}
</style>
</head>
<body>
    <!--幸运大转盘抽奖-->
    <div id="box">
     <div id="zhizhen"></div>
    </div>
</body>
<script type="text/javascript">
window.onload=function(){
 //幸运大转盘抽奖
 //获得指针元素
 var zhizhen=document.getElementById("zhizhen");
 //存放间隔动画id,用来清除运动
 var dbox=null;
 //间隔动画所用时间,表示转动快慢
 var dtime=1;
 //角度,和css设置对应,初始为0
 var deg=null;
 //初始角度
 var sdeg=0;
 //由js设置默认角度
 zhizhen.style.transform="rotate(" + sdeg + "deg)";
 //变化增量
 var cc=5;
 //旋转基本圈数
 var quan=6;
 //多余角度
 var odeg=null;
 //停止时的角度
 var stopdeg=null;
 //区间奖项 
 var jiang=[
  [1,51,"未中奖"], //未中奖
  [52,102,"6等奖"],//6等奖
  [103,153,"5等奖"],//5等奖
  [154,203,"4等奖"],//4等奖
  [204,251,"3等奖"],//3等奖
  [252,307,"2等奖"],//2等奖
  [307,360,"1等奖"]//1等奖
 ]; 
 //可用次数
 var cishu=6;
 //奖项判定函数
 function is(deg){
  var res="未中奖";
  for(var i=0;i<jiang.length;i++){
   if(deg>=jiang[i][0] && deg<=jiang[i][1]){
    res=jiang[i][2];
   };
  };
  return res;
 };
 //是否在动画中
 var able=false;
 //概率
 var gailv=[[938,"未中奖"],[18,"6等奖"],[14,"5等奖"],[12,"4等奖"],[8,"3等奖"],[6,"2等奖"],[4,"1等奖"]];
 //开始到结束总时间
 var xq=0;
 //通过奖项设置额外角度的表现
 function set(real){
  var mindeg,maxdeg;
  for(var i=0;i<jiang.length;i++){
   if(real==jiang[i][2]){
    mindeg=jiang[i][0];
    maxdeg=jiang[i][1];
   };
  };
  return mindeg+Math.floor(Math.random()*(maxdeg-mindeg+1));//生成min-max的随机数
  
 };
 //监听点击事件
 zhizhen.onclick=function(){
  if(!able){
   if(cishu==0){//可用次数处理
    alert("次数耗光,等待次啊次机会!");
   }else{
    cishu-=1;//次数减少
    deg=sdeg;
    cc=5;
    xq=0;
    var allarr=[];//长度1000,存放0-6 表示奖项
    for(var i=0;i<gailv.length;i++){
     for(var j=0;j<gailv[i][0];j++){
      allarr.push(gailv[i][1]);
     };
    };
    var real=allarr[Math.floor(Math.random()*1000)];
    odeg=set(real);
    stopdeg=quan*360+odeg;
    alltime=stopdeg/cc*dtime;
    dbox=setInterval(dong,dtime);
   };
  };
  
 };
 //大转盘转动函数
 function dong(){
  able=true;
  deg+=cc;
  if(deg>stopdeg){   
   clearInterval(dbox);           
   setTimeout(function(){
    able=false; 
    alert(is(odeg));
   },500)
  }else{
   if(deg%360==0){//判断第几圈
    xq+=1;
    if(xq==quan-1){//到最后一圈
     cc=1;//增量变为1 变慢旋转
    };
    zhizhen.style.transform="rotate(" + deg + "deg)";
   }else{
    zhizhen.style.transform="rotate(" + deg + "deg)";
   };   
  };  
 }
 
};
</script>
</html>

 效果:

js幸运大转盘开发_第5张图片

 

 十三.九宫格大转盘

除了上面那种指针转盘,其实在类似效果中还有九宫格大转盘,也是常见效果之一,

参考:http://www.jq22.com/yanshi2022

他们的原理其实非常相似,只不过额外角度会变成额外的索引值,利用jq开发,增加速率:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>九宫格大转盘</title>
    <style type="text/css">
/*reset*/
*{ padding:0; margin:0}
body{ height: 100%; width: 100%; font-size:12px; color:#333;}
ul{ list-style:none;}
/*demo*/
#lottery{width:400px;height:400px;margin:20px auto 0; position:relative;}
#lottery div{width:100px;height:100px;text-align:centerfont-size:24px;color:#333; float:left;}
#lottery .cent{ background:#C33;}
#lottery .lottery-unit-0{ background:#CC6;}
#lottery .lottery-unit-1{ background:#F99;}
#lottery .lottery-unit-2{ background:#CC6;}
#lottery .lottery-unit-3{ background:#F99;}
#lottery .lottery-unit-4{ background:#CC6;}
#lottery .lottery-unit-5{ background:#F99;}
#lottery .lottery-unit-6{ background:#CC6;}
#lottery .lottery-unit-7{ background:#F99;}
#lottery .lottery-unit-8{ background:#CC6;}
#lottery .lottery-unit-9{ background:#F99;}
#lottery .lottery-unit-10{ background:#CC6;}
#lottery .lottery-unit-11{ background:#F99;}
#lottery div.select{background:#F0F;}
#lottery .start{ position:absolute; left:100px; top:100px; height:200px; width:200px;background:#C33; font-size:30px; text-align:center; cursor:pointer; line-height:200px; color:#fff;}
</style>
</style>
</head>
<body>   
 <!--九宫格大转盘-->
    <div id="lottery">
        
        <div class="lottery-unit lottery-unit-0">1</div>
        <div class="lottery-unit lottery-unit-1">2</div>
        <div class="lottery-unit lottery-unit-2">3</div>
        <div class="lottery-unit lottery-unit-3">4</div>
        
        <div class="lottery-unit lottery-unit-11">12</div>            
        <div class="cent"></div>
        <div class="cent"></div>            
        <div class="lottery-unit lottery-unit-4">5</div>
        
        <div class="lottery-unit lottery-unit-10">11</div>            
        <div class="cent"></div>
        <div class="cent"></div>            
        <div class="lottery-unit lottery-unit-5">6</div>
    
        <div class="lottery-unit lottery-unit-9">10</div>
        <div class="lottery-unit lottery-unit-8">9</div>
        <div class="lottery-unit lottery-unit-7">8</div>
        <div class="lottery-unit lottery-unit-6">7</div>
        <div class="start" id="start">抽奖</div>
    </div>
</body>
<script type="text/javascript" src="http://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>
<script type="text/javascript">
$(function(){
 //九宫格大转盘
 var count=3;//可用次数 
 var i=null;//初始位置,
 var speed=80;//转动速度
 var ok=null;//产生0-11的整数,标记中奖位置
 var count=null;//总变化次数
 var nowcount=null;//当前的变化位置
 var n=5;//圈数
 var paly=false;
 var xq=0;
 function dong(){//利用递归模拟setinterval的实现  
  if(nowcount>count){
   setTimeout(function(){
    paly=false;
    alert("恭喜你,中了"+eval(ok)+"等奖");
   },500);
  }else{   
   nowcount+=1;
   if(i>10){ 
    xq+=1; 
    if(xq==n-1){
     speed=300;
    }; 
    $(".lottery-unit").removeClass("select");
    $(".lottery-unit-11").addClass("select");
    i=0;
   }else{
    $(".lottery-unit").removeClass("select");
    $(".lottery-unit-"+i).addClass("select");
    i+=1;
   };
   setTimeout(dong,speed); 
  };   
  
 }; 
 $(".start").click(function(){
  if(!paly){
   if(count==0){
    alert("已经没有机会,下次再来!");
   }else{
    ok=Math.floor((Math.random()*12));//产生0-11的整数,标记中奖位置
   speed=80;
    count=n*12+ok;//总变化次数
    nowcount=0;//当前的变化位置
    i=0;//初始位置,
    paly=true;
    count-=1;
    dong();
   };
   
  }else{
   
  };
  
 });  
});
</script>
</html>

 为了增加知识量,我们的将间隔函数采用递归+延时函数的处理,中心原理几乎一致,额外的随机生成,总圈数的设置,最后开始变慢,不过这次我们是利用延时加长的设置,才用了总计数和圈计数的分别处理,同样i我们也可以利用 总计数/12 的模。

 效果:

js幸运大转盘开发_第6张图片

 最终效果实例下载:http://www.oschina.net/code/snippet_2352644_54997

 

结尾要吐槽:

近期大部分都是对js知识介绍,到这时已经70篇了(第一篇是15年8月),虽然几乎没人看,不过我还是会坚持下去(最起码作为自己学习日记使用)。这一片算是改改口味,贴合实际的实例开发。
吐槽:我的博客都是文字和源码结合展示,几乎全部手打,文字+源码,那么源码我敢粘贴到博客里让你去测试,说明我肯定运行过了,运行的前面要花费多少工夫,对于搞it的你写一个效果花费时间只多不少,而且一片博客有多少源码我就不骄傲了。
我自己感觉前端的东西是十分容易测试的(新建.html文件+复制+粘贴+运行),同样只有真的有了代码,去运行了,还看到结果了,然后结合一些解释,才可能或多或少学一点点东西(发现这个效果有点意思,我喜欢,也可能突然领悟就是这个原理)。
博客其实主要作用是自己知识的总结,分享出来感觉可能会帮助那么几个人。

 

你可能感兴趣的:(js大转盘,js大转盘抽奖,js幸运大转盘,js幸运大装盘抽奖,js九宫格大转盘)