原生JS实现根据后台的值进行大转盘抽奖

3,979 阅读3分钟

思路

  • 1. 转盘是360度,指针指向的位置的度数 = 360 - 转盘转动的度数
  • 2. 随机的设置一个转动的度数(0~360/45整除的度数 = (45的倍数)) var random = Math.round(Math.random() * 8) * 45;
  • 3. 返回的data.index的值*45就是转了的度数,var messAlert = winIndex * 45;
  • 4. 得到指针指向位置的度数 var posDeg = 360 - messAlert;
  • 5. 只是简单实现了功能,后续在整理更精简的代码

html 部分

<body>
  <div class="wrap" id="wrap">
    <div class="bg">

      <div class="turntable">
        <img class="wheelImg" src="./img/bigwheel.png" alt="幸运大转盘">
      </div>
      <!-- 转盘 + 按钮 -->
      <div class="boxCir" id="boxCir">
        <div class="luckDoload" id="luckDoload"></div>
        <div id='boxBtn' class="start"></div>
      </div>

      <!-- 循环上移li所有数据信息 -->
      <div>
        <ul class="m-buyer">
          #foreach($prize in $!{prizes})
          <li style="" class="news-item">恭喜&nbsp;<i>$!{prize.nickName}</i>&nbsp;中奖&nbsp;<i>$!{prize.prizeText}</i></li>
          #end
        </ul>
      </div>

      <!-- 中奖弹窗 -->
      <div class="alertBg" id="alertBg">
        <!-- <b id="close">
          <img class="closeImg" src="./img/close.png" alt="">
        </b>
        <h3>中奖了</h3>
        <span>恭喜你获得了500钻</span>
        <p id="changeBtn">
          <img class="alertImg" src="./img/tablechange.png" alt="">
        </p> -->
      </div>

      <!-- 余额不足弹窗 -->
      <div class="alertBgRed" id="alertBgRed">
        <b id="closeRed">
          <img id="closeImgRed" src="./img/close.png" alt="">
        </b>
        <h3>很遗憾</h3>
        <span>您的钻石不足,买点来抽吧</span>
        <p id="changeBtnRed">
          <img id="alertImgRed" src="./img/flowerNo.png"
            onclick="gotoWalletFragment()" alt="">
        </p>
      </div>

    </div>
  </div>
</body>

JS部分

  • 引入用到的JS插件
<script src="./js/public/viewport.js"></script>
<script src="./js/public/jquery-2.1.4.min.js"></script>
<script src="./js/jquery.bootstrap.newsbox.min.js" type="text/javascript"></script>
  • 获取ajax数据部分,点击抽奖的时候来执行
 //获取转盘数据
  function Roulette() {
    $.ajax({
      url: '127.0.1:9000/web/lottery/roulette/commit',
      method: 'POST',
      async: true,
      cache: false,
      dataType: 'json',
      contentType: 'application/json;charset=utf-8',
      headers: {
        'header-encrypt-code': httpHeader
      },
      success(data) {
        // 中奖弹窗
        if (data.code == 0) {
          go(random, data)
          prizeWindow()
          window.queryRoulette = data;
          console.log(window.queryRoulette, '请求成功的window.queryRoulette');
        }
        if (data.code == 21010) {
          // code = 21010,弹出余额不足弹窗
          prizeNotWindow()
        }
      },
      error: function (err) {
        console.log(err);
      }
    });
  }
  • 转盘默认为false,为true的时候让它转
var doing = false; //设置转盘是否转动 ,默认否
  var defNum = 4 * 360; //4是所需要转动的圈数,每一圈是360度;
  var random = Math.round(Math.random() * 8) * 45; //旋转到45的倍数,指针在中间位置

  function go(random, data) {
    if (doing) {
      return;
    }
    doing = true;
    // var ranDeg = random + defNum; //随机度数 45的倍数* 360*4圈
    var winIndex = data.data.index; //返回的data.index值
    var messAlert = winIndex * 45; //返回的data.index 的值 *45
    var posDeg = defNum - messAlert; // 转了 360*4圈 - 45*n 度

    $('#boxCir').attr("data-deg", posDeg); //设置自定义属行,旋转停下来就是指定的度数
    console.log(posDeg, '第一次转的度数')

    //让转盘转起来
    luckDoload.style.transform = "rotate(" + posDeg + "deg)";
    luckDoload.style.transition = "all 5s";
  }
  
   $('#boxBtn').click(function () {
    //是否包含这个类名,已经点击了就不能在点了
    if ($(this).hasClass('start') && !doing) {
      // 点击按钮请求数据,请求成功开始旋转
      Roulette();
    } else {
      //活动未开始的提示逻辑
    }
  })
  • 停下的位置,data.index 的值对应的奖品位置
//指针指向的位置的度数  = 360 - 转盘转动的度数
  var transitionend = 'transitionend' || 'webkitTransitionEnd';
  luckDoload.addEventListener(transitionend, function () {
    doing = false;
    var winData = window.queryRoulette.data;
    var winIndex = window.queryRoulette.data.index; //返回的data.index 的 值
    var messAlert = winIndex * 45; //返回的data.index 的值 *45
    var posDeg = 360 - messAlert; // 转了315度
    var indexDeg = messAlert / 45; //转了45的几倍

    console.log(winData, 'winData')
    console.log(indexDeg, 'indexDeg')

    luckDoload.style.transform = "rotate(" + posDeg + "deg)";
    luckDoload.style.transition = "none";

    getPrize(indexDeg, winData);
  }, false)
  • 绑定中奖数据,根据data.index 的值 提醒中奖信息弹框
  //中奖信息
  function getPrize(indexDeg, winData) {

    console.log("恭喜您中奖了:" + indexDeg);
    console.log(indexDeg, 'indexDeg')

    if (indexDeg == 7) {

      console.log('谢谢惠顾')
      $('#alertBg').show();
      bindPrize(winData)
      prizeWindow();

    } else if (indexDeg == 6) {

      console.log('华为Mate30')
      $('#alertBg').show();
      bindPrize(winData)
      prizeWindow();

    } else if (indexDeg == 5) {

      console.log('500钻')
      $('#alertBg').show();
      bindPrize(winData)
      prizeWindow();

    } else if (indexDeg == 4) {

      console.log('100元抵扣卷')
      $('#alertBg').show();
      bindPrize(winData)
      prizeWindow();

    } else if (indexDeg == 3) {

      console.log('50钻')
      $('#alertBg').show();
      bindPrize(winData)
      prizeWindow();

    } else if (indexDeg == 2) {

      console.log('10钻')
      $('#alertBg').show();
      bindPrize(winData)
      prizeWindow();

    } else if (indexDeg == 1) {

      console.log('2钻')
      $('#alertBg').show();
      bindPrize(winData)
      prizeWindow();

    } else if (indexDeg == 0) {

      console.log('vivo x27')
      $('#alertBg').show();
      bindPrize(winData)
      prizeWindow();

    } else {
      return
    }
  }
  • 中奖信息弹窗和未中奖弹窗
//中奖弹窗
  function prizeWindow() {
    $('.closeImg').on('click', function () {
      $('#alertBg').hide();
    })
    $('.alertImg').on('click', function () {
      $('#alertBg').hide();
      Roulette();
    })
  }
  
    //未中奖弹窗
  function prizeNotWindow() {
    $('#alertBgRed').show();
    $('#closeImgRed').on('click', function () {
      $('#alertBgRed').hide();
    })
    $('#alertImgRed').on('click', function () {
      $('#alertBgRed').hide();
    })
  }
  • 中奖提示消息,引入jquery.bootstrap.newsbox.min.js 库
  // 消息上移
  function mesTops() {

    $(".m-buyer").bootstrapNews({
      newsPerPage: 2,
      autoplay: true,
      pauseOnHover: true,
      navigation: false,
      direction: 'up',
      newsTickerInterval: 2000,
      onToDo: function () {
        //console.log(this);
      }
    });
  }
  mesTops()