【JavaScript】---- 使用 Tween 实现转盘抽奖

1. 实现效果

在这里插入图片描述

2. 需求分析

  1. 它和正常的转盘抽奖不一样,一般实现都是指针形式的,转盘转动,最后指针停留在奖品的随机位置;
  2. 通过上边图发现奖品必须刚好停留在奖品的位置,因为不是指针,所以不能最后落到随机位置。

3. 常见转盘抽奖实现

在这里插入图片描述

常见九宫格抽奖和转盘抽奖组件实现!!!

4. 使用库

  1. 张鑫旭大佬实现的动画函数算法库
  2. 如何使用Tween.js各类原生动画运动缓动算法,使用文档

5. 引入 Tween.js 算法库

	<script src="./js/tween.js"></script>
    <script src="./js/animation.js"></script>

6. HTML 布局

  1. 转盘图片 game_luck.png;
  2. 指针图片 game_check.png;
  3. 开始按钮 game_btn.png。
    <div class="rui-game-luck-content">
        <img src="./images/game_luck.png" 
        :style="`transform: translate(-50%, -50%) rotate(${angleNumber}deg)`" 
        :data-id="angleNumber"
        id="turntable" 
        class="rui-game-luck-img" alt="">
        <img src="./images/game_check.png" style="z-index: 10;" class="rui-game-luck-img" alt="">
        <img src="./images/game_btn.png" @click="drawLuck" class="rui-game-luck-btn" alt="">
      </div>

7. CSS 实现

	.rui-game-luck-content{
        width: 5.38rem;
        height: 5.38rem;
        position: relative;
        margin: 1.55rem auto 0.35rem;
      }
      .rui-game-luck-img{
        width: 5.38rem;
        height: 5.38rem;
        position: absolute;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
      }
      .rui-game-luck-btn{
        width: 2.26rem;
        height: 2.26rem;
        position: absolute;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
        z-index: 12;
      }

8. 点击旋转动画实现

  1. 申明一个 Lock 锁,用于防止抽奖时的重复点击;
  2. 抽奖的各个变量申明;
  3. 抽奖次数已用完判断;
  4. 判断锁是否生效;
  5. 生成0到5之间的随机整数;
  6. 计算最后的角度;
  7. 转盘旋转动画;
  8. 抽奖次数减少;
  9. 显示遮罩层中奖奖品;
  10. 记录上一次转动最终角度。
	  const lock = new Lock();
      var app = new Vue({
        el: "#app",
        data: {
          show: false, // 遮罩层
          luckNumber: 0, // 中奖位置
          luckList: ['成长快乐','笑口常开','健康活泼','成长快乐','笑口常开','健康活泼'], // 奖品列表
          angleNumber: 0, // 转盘旋转角度
          drawNumber: 3, // 抽奖次数
          recordPrevAngle: 0, // 上一次转动最终角度
          drawOverMask: false, // 抽奖次数已用完遮罩层
        },
        methods: {
          // 再抽一次
          drawAgainLuck(){
            this.show = false;
            this.drawLuck();
          },
          // 抽奖
          drawLuck(){
            // 抽奖次数已用完
            if(this.drawNumber <= 0){
              this.drawOverMask = true;
              return false;
            }
            // 判断锁是否生效
            if(lock.isLocked){
              return false;
            }
            // 获取锁
            lock.acquire(); 
            let _this = this;
            let prevLuckAngle = this.luckNumber * 60;
            // 生成0到5之间的随机整数
            let randomNum = Math.floor(Math.random() * this.luckList.length);
            this.luckNumber = randomNum;
            // 计算最后的角度
            let endAngle = 360 * 20 + _this.luckNumber * 60 - prevLuckAngle;
            // 转盘旋转动画
            Math.animation(_this.recordPrevAngle, _this.recordPrevAngle + endAngle, 5000, 'Cubic.easeInOut',function(value, isEnding) {
              _this.angleNumber = value;
              if(isEnding){
                lock.release(); // 释放锁
                // 抽奖次数减少
                _this.drawNumber--;
                // 显示遮罩层中奖奖品
                _this.show = true;
                // 记录上一次转动最终角度
                _this.recordPrevAngle += endAngle;
                console.log(_this.luckList[_this.luckNumber])
              }
            })
          }
        }
      });

9. 最终效果

在这里插入图片描述

10. 总结

  1. 使用现有的算法库,减少了我的工作量;
  2. 在不考虑异步中奖的时候,我觉得这个实现是比较便捷的方法,当然如果需要异步中奖结果,就需要多个动画配合实现,这个功能准备将这个算法库移植到微信小程序后再实现;
  3. 同一个需求,实现的方法很多,找到最适合自己的,多关注大佬的博客,学习,感觉收获满满!!!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Rattenking

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值