欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

原生js实现轮盘抽奖,控制中奖概率(完整示例)

程序员文章站 2022-07-12 12:50:42
...


本想找一个现成的,结果发现网上只有能实现转了,但是效果并不是让人很满意,于是我就借鉴一个样式,重新改了js实现,效果如下:

原生js实现轮盘抽奖,控制中奖概率(完整示例)

图片素材:(网上一搜就有=-=)

pointer.png

原生js实现轮盘抽奖,控制中奖概率(完整示例)

turntable.png
原生js实现轮盘抽奖,控制中奖概率(完整示例)

turntable-bg.jpg
原生js实现轮盘抽奖,控制中奖概率(完整示例)

1.实现旋转

原理很简单,就是通过css动画来实现旋转动画,用js来控制旋转度,


        img[src^="turntable"] {
            position: absolute;
            z-index: 5;
            top: 60px;
            left: 116px;
            transition: all 4s;
        }
//配合
  oTurntable.style.transform = "rotate(" +transformRotate+ "deg)";

2.控制得奖概率

控制概率,我将100当做概率,概率为 [randmArr[i-1],randmArr[i]),通过控制差值,来控制概率,当然这只是简单的demo,最好用map对象,更合理

  var randmArr = [1,5,10,20,35,55,100] //概率计算为randmArr[i-1]和randmArr[i]之间
  
   const rdm =parseInt(Math.random() * (100 - 1) + 1);//随机的数
            var num = 7
            console.log('rdm='+rdm);
            // 统计随机数次数
            if (!obj[rdm]) {
                  obj[rdm] = 1;
                } else {
                  obj[rdm] ++;
                }
            for(var i = 0;i<randmArr.length;i++){
              if(i===0){
                  if(rdm>=0&&rdm<=randmArr[0]){
                    num = i+1
                    break
                  }
              } else {
                if(rdm>randmArr[i-1]&&rdm<=randmArr[i]){
                  num = i+1
                    break
                  }
              }

          }

3. 控制旋转动画落点

虽然js是控制,单动画落点,也需要和我们所得一致,同时我们思考,一般抽奖都会固定旋转几圈,所以我们需要给个初始的旋转圈数,同时下一次旋转又是从上一次落点的基础上进行的,为了控制我们每次都是从原点开始,这样才能控制好落点和js一致,于是我设置初始圈为3圈,而第三圈为,第一次旋转后剩下度数(360-n),这样就能达到每次都是从原点开始,

    		 nextrdm = Math.floor((num* cat)-24); //定义本次抽奖结果
              var biginRotate = 2*360+(360-prevrdm) //定义默认的旋转圈数,同时补全使轮盘置零,
              prevrdm = nextrdm //缓存本次次的角度
                 transformRotate=nextrdm+biginRotate+transformRotate //本次旋转的度
              oTurntable.style.transform = "rotate(" +transformRotate+ "deg)";

4.测试概率

写是写完了,但不测试都是瞎扯淡,所以我定义了2个对象,用了记录每次所得的随机数和次数,还有中几等奖的次数

obj 和 form对象

  const rdm =parseInt(Math.random() * (100 - 1) + 1);//随机的数 
// 统计随机数次数 
if (!obj[rdm]) {
    obj[rdm] = 1;
} else {
    obj[rdm] ++;
}

  // 统计中奖概率
if ( !form['a'+num]) {
    form['a'+num] = 1;
} else {
    form['a'+num]++
}

示意图

原生js实现轮盘抽奖,控制中奖概率(完整示例)

打印发现其实随机比较公平的,但是毕竟我用的100,中奖概率还是比较大了,如果需要再小可以继续放小,

完整代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="description" content="">
    <meta name="author" content="marendu">
    <title>转盘抽奖效果</title>
    <!-- 这里是css部分 -->
    <style>
        #bg {
            width: 650px;
            height: 600px;
            margin: 0 auto;
            background: url(turntable-bg.jpg) no-repeat;
            position: relative;
        }

        img[src^="pointer"] {
            position: absolute;
            z-index: 10;
            top: 155px;
            left: 247px;
        }

        img[src^="turntable"] {
            position: absolute;
            z-index: 5;
            top: 60px;
            left: 116px;
            transition: all 4s;
        }
    </style>
</head>
<body>
    <!-- 这里是HTML结构部分 -->
    <div id="bg"><img src="pointer.png" alt="pointer"><img src="turntable.png" alt="turntable"></div>
    <button onclick="btn()">概率统计</button>
    <button onclick="test()">测试100次抽奖</button>
    <!-- 这里是js部分 -->
    <script>
        var oPointer = document.getElementsByTagName("img")[0];
        var oTurntable = document.getElementsByTagName("img")[1];
        var cat = 51.4; //总共7个扇形区域,每个区域约51.4度
        var offOn = true; //是否正在抽奖
        var transformRotate = 0 //转圈度数
        var randmArr = [1,5,10,20,35,55,100] //概率计算为randmArr[i-1]和randmArr[i]之间
        // 打印概率
        function btn(){
            console.log(form);
            console.log(obj);
            let num = 0
          Object.keys(obj).map(item=>{
            num += obj[item]
          })
          console.log(num);

        }
        oPointer.onclick = function () {
            if (offOn) {
                offOn = !offOn;
                ratating();
            }
        }
          let n= 0
          var testTime = null
        function test(){
          testTime = setInterval(()=>{
                n++
                if(n>99){
            clearInterval(testTime)
         }
               ratating();
        
           },300);
      }
        //旋转
        //TODO: 规定中奖区间,通过区间判定值
        var prevrdm = 0; //缓存上一次的旋转度
        var obj ={} //产生的随机数的次数
        var form = {} //统计中奖的概率
        var timer = null
        function ratating() {
            var timer = null;
            const rdm =parseInt(Math.random() * (100 - 1) + 1);//随机的数
            var num = 7
            var nextrdm = 0; //本次旋转度
            console.log('rdm='+rdm);
            // 统计随机数次数
            if (!obj[rdm]) {
                  obj[rdm] = 1;
                } else {
                  obj[rdm] ++;
                }
            for(var i = 0;i<randmArr.length;i++){
              if(i===0){
                  if(rdm>=0&&rdm<=randmArr[0]){
                    num = i+1
                    break
                  }
              } else {
                if(rdm>randmArr[i-1]&&rdm<=randmArr[i]){
                  num = i+1
                    break
                  }
              }

          }
          console.log('num='+num);
            clearTimeout(timer);
            timer = null
            timer = setTimeout(function () {
              nextrdm = Math.floor((num* cat)-24); //定义本次抽奖结果
              var biginRotate = 2*360+(360-prevrdm) //定义默认的旋转圈数,同时补全使轮盘置零,
              prevrdm = nextrdm

              transformRotate=nextrdm+biginRotate+transformRotate //本次旋转的度
            // 测试中奖的概率时,把下面注释掉,同时将timeout时间设置为0
              oTurntable.style.transform = "rotate(" +transformRotate+ "deg)";
                    setTimeout(function () {
                        offOn = !offOn;
                        // 统计中奖概率
                          if ( !form['a'+num]) {
                            form['a'+num] = 1;
                          } else {
                            form['a'+num]++
                          }
                        console.log('transformRotate='+transformRotate);
                        if (nextrdm <= cat * 1) { console.warn("一等奖"); console.log("nextrdm=" + nextrdm + "rdm=" + rdm + "," + "4999元"); }
                        else if (nextrdm <= cat * 2) { console.warn("二等奖"); console.log("nextrdm=" + nextrdm + "rdm=" + rdm + "," + "50元"); }
                        else if (nextrdm <= cat * 3) { console.warn("三等奖"); console.log("nextrdm=" + nextrdm + "rdm=" + rdm + "," + "10元"); }
                        else if (nextrdm <= cat * 4) { console.warn("四等奖"); console.log("nextrdm=" + nextrdm + "rdm=" + rdm + "," + "5元"); }
                        else if (nextrdm <= cat * 5) { console.warn("五等奖"); console.log("nextrdm=" + nextrdm + "rdm=" + rdm + "," + "免息服务"); }
                        else if (nextrdm <= cat * 6) { console.warn("六等奖"); console.log("nextrdm=" + nextrdm + "rdm=" + rdm + "," + "提交白金"); }
                        else if (nextrdm <= cat * 7) { console.warn("七等奖"); console.log("nextrdm=" + nextrdm + "rdm=" + rdm + "," + "未中奖"); }
                    }, 0);
            }, 30);
        }
    </script>
</body>
</html>