【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. 同一个需求,实现的方法很多,找到最适合自己的,多关注大佬的博客,学习,感觉收获满满!!!
  • 5
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
是的,three.jstween.js可以一起使用实现复杂的动画效果,包括飞线动画。以下是一个简单的例子,演示了如何使用three.jstween.js创建一条飞线动画: ```javascript // 创建three.js场景 var scene = new THREE.Scene(); // 创建相机 var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); camera.position.z = 5; // 创建渲染器 var renderer = new THREE.WebGLRenderer(); renderer.setSize(window.innerWidth, window.innerHeight); document.body.appendChild(renderer.domElement); // 创建飞线路径 var curve = new THREE.CatmullRomCurve3([ new THREE.Vector3(-10, 0, 0), new THREE.Vector3(-5, 5, 0), new THREE.Vector3(0, 0, 0), new THREE.Vector3(5, -5, 0), new THREE.Vector3(10, 0, 0) ]); // 创建飞线材质 var material = new THREE.LineBasicMaterial({ color: 0xffffff }); // 将飞线路径转换为几何体 var geometry = new THREE.Geometry(); geometry.vertices = curve.getPoints(50); // 创建飞线网格 var line = new THREE.Line(geometry, material); scene.add(line); // 创建飞线动画 var tween = new TWEEN.Tween({t:0}) .to({t:1}, 5000) // 5秒钟 .onUpdate(function() { // 根据tween的进度计算飞线的位置 var position = curve.getPoint(this.t); // 更新飞线网格的位置 line.position.copy(position); }) .start(); // 渲染场景 function render() { requestAnimationFrame(render); TWEEN.update(); // 更新tween动画 renderer.render(scene, camera); } render(); ``` 在这段代码中,我们首先创建了一个three.js场景、相机和渲染器。然后,我们创建了一个CatmullRomCurve3曲线,用于定义飞线路径,并将其转换为three.js几何体。接下来,我们创建了一个TWEEN.Tween对象,将其起始值设置为0,结束值设置为1,表示飞线动画的进度。在Tween对象的 onUpdate 回调函数中,我们根据飞线路径计算当前进度对应的位置,并将飞线网格的位置更新为该位置。最后,我们创建了一个渲染函数,用于在每帧更新Tween动画和渲染场景。 希望这个例子可以帮助你了解如何使用three.jstween.js创建飞线动画。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Rattenking

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

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

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

打赏作者

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

抵扣说明:

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

余额充值