问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

使用Tween.js实现精确控制的转盘抽奖功能

创作时间:
作者:
@小白创作中心

使用Tween.js实现精确控制的转盘抽奖功能

引用
CSDN
1.
https://m.blog.csdn.net/m0_38082783/article/details/138854230

实现效果

需求分析

  1. 与传统的指针式转盘抽奖不同,本实现要求奖品必须刚好停留在奖品的位置,不能随机停止。
  2. 通过上图可以看出,转盘需要精确控制转动角度,以确保奖品能够准确对齐。

常见转盘抽奖实现

常见的转盘抽奖实现方式包括九宫格抽奖和传统的指针式转盘抽奖。本实现将采用Tween.js库来实现精确的动画控制。

使用库

  1. Tween.js:一个轻量级的JavaScript动画库,支持多种缓动函数。
  2. 张鑫旭大佬实现的动画函数算法库

引入 Tween.js 算法库

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

HTML 布局

转盘抽奖界面由转盘图片、指针图片和开始按钮组成。

<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>

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;
}

点击旋转动画实现

抽奖功能通过Vue框架实现,主要步骤包括:

  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])
                }
            })
        }
    }
});

总结

  1. 使用Tween.js库可以大大简化动画实现的复杂度,提高开发效率。
  2. 本实现方案适用于不需要异步中奖结果的场景。如果需要异步中奖,可以考虑使用多个动画配合实现。
  3. 同一个需求可以有多种实现方式,选择最适合自己的方案是关键。
© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号