美文网首页Vue.js
转盘类型抽奖如何实现

转盘类型抽奖如何实现

作者: DaZenD | 来源:发表于2023-03-13 14:54 被阅读0次

需求

常规转动,如ease-in-out

这种方案适合已经得知中奖信息,得到旋转角度,直接旋转就ok

:style="{transform:rotate(360deg),transition:rotate_transition}"

transform:旋转的角度

transition:过渡方式。如:'transform 3s ease-in-out'

mark transition需要事件触发,所以没法在网页加载时自动发生。所以,只要让transfor或transition变动一次,动画就会执行一次

🙋🏻♀️:点击开始,给style赋值就ok了。transform每次赋值只有不一样,才会动。这就是transition的含义:过渡

rotate_deg = 'rotate(360deg)'

rotate_transition = 'transform 3s ease-in-out'

随机控制开始-旋转-结束

上面的方案适合内定中奖名单,不用考虑接口请求,😈。但如果要是随机中奖呢:开始抽奖,去向接口要中奖信息,接口返回中奖奖品,再决定转盘旋转多少。这种旋转时间是不一定的。啥时候结束旋转取决于接口什么时候返回。

效果:启动 - 加速 - 匀速 - 减速 - 停止

mark 动画效果取决于transform:结束到开始的差值,duration内执行完。。结束值大于初始值,就是正转。反之是反转

封装js控制工具

  • rotate.js
/**
 * mark: 入参interval都是秒,这里具体用到的地方*1000了
 * @param el 入参需要旋转的标签元素
 * @param stepDeg 标签元素step时间需要旋转的角度 360度是一圈
 */
export function doInifityRotate(el) {
  // 每一次的旋转,记录旋转的deg,下次更新style需要在totaldeg累加,规则:如果是大于totaldeg,正转。如果小于totaldeg,反转
  var hasDeg = 0
  // 每一次的旋转,记录已经旋转的时间
  var hasDura = 0

  var easeInImpl = (function() {
    return function($el, duration, deg) {
      hasDeg += deg
      hasDura += duration
      $el.style = 'transform:rotate(' + hasDeg + 'deg);' + 'transition:transform ' + duration + 's ease-in'
    }
  })()

  var interval
  var linearForeverImpl = (function() {
    return function($el, stepInterval, stepDeg) {
      interval = setInterval(() => {
        hasDeg += stepDeg
        hasDura += stepInterval
        $el.style = 'transform:rotate(' + hasDeg + 'deg);' + 'transition:transform ' + stepInterval + 's linear'
      }, (stepInterval * 1000))
      console.log('=====interval ' + interval)
    }
  })()

  var linearImpl = (function() {
    return function($el, duration, deg) {
      hasDeg += deg
      hasDura += duration
      $el.style = 'transform:rotate(' + hasDeg + 'deg);' + 'transition:transform ' + duration + 's linear'
    }
  })()

  var easeOutImpl = (function() {
    return function($el, duration, deg, targetDeg, callBack) {
      if (interval) {
        clearInterval(interval)
      }
      // 1、指定的多转的角度
      hasDeg += deg
      hasDura += duration
      // 2、向上取整到360度的倍数
      const lackDeg = 360 - (hasDeg % 360)
      hasDeg += lackDeg
      // 3、角度落到具体扇区
      hasDeg -= targetDeg
      $el.style = 'transform:rotate(' + hasDeg + 'deg);' + 'transition:transform ' + duration + 's ease-out'
      setTimeout(() => {
        callBack()
      }, (duration * 1000 + 50))
    }
  })()

  var stopImpl = (function() {
    return function($el) {
      console.log(hasDura)
      if (interval) {
        clearInterval(interval)
      }
      hasDura = 0
      hasDeg = 0
      $el.style = ''
    }
  })()

  return {
    easeIn: function(duration, deg) {
      // resetImpl(el)
      console.log('=== ease in')
      easeInImpl(el, duration, deg)
    },
    linearForever: function(stepInterval, stepDeg) {
      linearForeverImpl(el, stepInterval, stepDeg)
    },
    linear: function(duration, deg) {
      linearImpl(el, duration, deg)
    },
    /**
     *
     * @param duration 动画时长
     * @param deg 动画角度
     * @param targetDeg 0度起到奖品落到的角度。比如 需要把指针落到第二个扇区,那就需要多转45度
     */
    easeOut: function(duration, deg, targetDeg, callBack) {
      easeOutImpl(el, duration, deg, targetDeg, callBack)
    },
    stop: function() {
      stopImpl(el)
    }
  }
}

  • 使用
// 开始请求网络 获取本次抽奖中奖信息
      this.prize()

// 转盘控制组件
      var rotate = doInifityRotate(this.$refs['wheel'])
      
// 开始旋转:加速旋转
      rotate.easeIn(2, 720)
// 加速2s后,开始匀速旋转
      setTimeout(() => {
        rotate.linearForever(0.01, 6)
      }, 2000)

// 此间,持续关注着网络请求结果。这里控制了阈值4s
      var interval
      var time = 0
      interval = setInterval(() => {
        time++
        if (Object.keys(this.raffledPrize).length > 0) {
          // 抽到奖了
          clearInterval(interval)
          const that = this
          // 具体的奖品在奖盘上的位置角度
          const targetDeg = this.getTargetDeg()
          
          if (time > 4000) {
          // 减速旋转,直到结束,停到奖品对应的角度位置
            rotate.easeOut(2.5, 720, targetDeg, function() {
            // 中奖后的操作
              that.wheelOver()
            })
          } else {
          // 这里表示,如果网络请求很快,从开始旋转到中奖结果回来,不够4s,那就转够4s。然后开始减速-结束
            setTimeout(() => {
              rotate.easeOut(2.5, 720, targetDeg, function() {
                that.wheelOver()
              })
            }, (4000 - time))
          }
        } else if (this.raffleError) {
          // 抽奖请求失败
          clearInterval(interval)
          const that = this
          setTimeout(() => {
            rotate.stop()
            that.isAllowClick = true
          }, 2100)
        }
      }, 1000)

相关文章

  • css 如何“画”一个抽奖转盘

    主要描述的是如何运用 css 绘制一个抽奖转盘,并运用原生 js 实现转盘抽奖效果。 先来张效果图: 布局 一般来...

  • 博彩类玩法

    一、调查 以下是pick语音的玩法 抽奖分成三种类型,普通转盘、黄金转盘和幸运转盘。 普通转盘+黄金转盘次数=20...

  • JS实现抽奖转盘

    超级简单的原理:点击转盘指针后随机得到一个数(每个数字对应一个奖项),并确定每个奖项在轮盘上的大概角度,然后调用 ...

  • canvas实现转盘抽奖

    用canvas写了一个简单的转盘抽奖插件, 给大家参考下下。。。 做的时候的想法是,通过传进来的标签以及属性,直接...

  • Android超简单实现九宫格抽奖

    目录 前言 如果有小伙伴想实现转盘抽奖效果的话请看我的另一篇文章《Android超简单实现自定义抽奖转盘效果》 效...

  • 小程序实现大转盘,九宫格抽奖,带跑马灯效果

    基本实现功能 1,小程序仿天猫超市大转盘 2,九宫格转盘抽奖 3,积分抽奖 4,抽到的积分随机生成 5,抽奖结果可...

  • Scratch—转盘抽奖

    【知识延伸】 传统抽奖分为抽奖盒抽取、转盘抽奖等 【要求】 今天我们按照平时转盘抽奖、利用Scratch做一个转盘...

  • php实现刮刮卡大转盘抽奖概率

    php实现刮刮卡大转盘抽奖概率 本文实例为大家分享了php中奖概率算法,可用于刮刮卡,大转盘等抽奖算法,用法很简单...

  • iOS--老虎机的抽奖实现

    除了转盘形式得抽奖,还有一种老虎机形式用的也比较多,今天我们就来实现下老虎机抽奖的实现

  • 随时开始随时结束的抽奖转盘

    公司要实现点击抽奖开始动画,结果返回后缓慢停止到抽奖区域,在网上Google出来的大部分转盘demo都是等抽奖结果...

网友评论

    本文标题:转盘类型抽奖如何实现

    本文链接:https://www.haomeiwen.com/subject/jxucrdtx.html