vue简单实现转盘抽奖

本文实例为大家分享了vue简单实现转盘抽奖的具体代码,供大家参考,具体内容如下

1.0 思路整理

转盘抽奖很常见,之前也没写过,现在有空来写写,分析如下:

1.1 转盘旋转 ----- 可以用 transform 的 rotate 来解决
1.2 旋转动画 ----- transition 过渡来处理
1.3 停留目标位置及中奖提示 ? ------ 通过控制旋转角度控制停留位置,中奖提示,考虑添加回调

1.1 开始行动

上面的思考,我们知道了大概要实现的步骤,首先我们搞张图片

这个圆盘有 10 份,每一份 360/10 = 36deg,假设要停留在第二个---->20金币,顺时针(含初始位置并计为1),即 共需要旋转 (2 - 1)* 36 = 36,这样,我们可以得出,停留位置需要旋转的角度 = (target - 1)*36。

1.2 中奖回调

上面的步骤,我们知道了如何控制到目标位置,那接下来就是事件通知,起初想的是,固定转动时间,然后开启定时器计时,很显然不靠谱,有没有什么可以在动画结束后就通知呢?transitionend,我找到了这个事件,可以监听元素动画结束事件,只不过有些兼容 这个好办

/**
动画结束事件兼容
**/
whichTransitionEvent(){
 let el = document.createElement('span'),
 transitions = {
 'transition':'transitionend',
 'OTransition':'oTransitionEnd',
 'MozTransition':'transitionend',
 'WebkitTransition':'webkitTransitionEnd'
 };
 for(let t in transitions){
 if( el.style[t] !== undefined ){
  return transitions[t];
 }
 }
 el = null;
}

2.0 完整示例

控制转动位置和事件通知都找到方法了,接下来开干!

栗子:

完整代码

<template>
 <div>
 <h3>转盘抽奖</h3>
 <div class="round_box" >
  <img class="img_rotate" ref="rotImg" src="../assets/zhuan.png" alt="">
  <div class="center">
  <div class="pointer" ></div>
  </div>
 </div>
 <button @click="toDraw" >点击抽奖</button>
 </div>
</template>

<script>
export default {
 name:'rotaryDraw',
 data() {
 return {
  rotate: 0,
  resetRotate: 0,
  hitId: 1,// 1-10
  drawStatus: false
 }
 },
 async mounted() {
 await this.$nextTick();
 let evenTransition = this.whichTransitionEvent();
 let img = this.$refs.rotImg;
 let that = this;
 const hitAre = [ '30M流量包','20金币','20M流量包','10M流量包','5金币',
    '谢谢参与','10金币','50M流量包','2金币','100M流量包'
   ];
 // 监听 动画结束
 img.addEventListener(evenTransition,tranHand,false);

 function tranHand() {
  // 复位
  that.resetRotate = that.rotate > 360 ? that.rotate % 360 : 0;
  img.style.transition = "none 0s ease 0s";
  img.style.transform = `rotate(${that.resetRotate}deg)`;
  alert(`抽奖结果【 ${hitAre[that.hitId - 1]} 】`);
  that.drawStatus = false
 }
 },
 methods: {
 start() {
  this.$refs.rotImg.style.transition = "all 3s ease 0s";
  this.$refs.rotImg.style.transform = `rotate(${this.rotate}deg)`;
 },
 toDraw() {
  if(this.drawStatus){
  console.log('正在抽奖中');
  return
  }
  // 标记状态
  this.drawStatus = true
  /**
  * 圆盘共 10 份 每份 36度, 停位置(id)度数 (id - 1)*36
  * 基数 3圈 360*4
  * this.rotate 当前角度
  * **/
  let reset = 360 * 4;
  let idx = this.getRandomInt(1,11);
  // 设置命中
  this.hitId = idx;
  // 需要多转角度
  let addRotate = this.resetRotate > 0 ? 360 - this.resetRotate : 0;
  // 总共角度
  let allRotate = this.rotate + (idx - 1) * 36 + reset + addRotate;
  // 角度限制
  this.rotate = this.setRotate(allRotate);

  this.start()
 },
 // 递归计算角度 不超过 360*6
 setRotate(deg) {
  let rest = deg - 360;
  return rest > 360*6 ? this.setRotate(rest) : deg;
 },
 getRandomInt(min, max) {
  // 向上收
  min = Math.ceil(min);
  // 向下收
  max = Math.floor(max);
  return Math.floor(Math.random() * (max - min)) + min; //不含最大值,含最小值
 },
 // 动画兼容
 whichTransitionEvent(){
  let el = document.createElement('span'),
  transitions = {
  'transition':'transitionend',
  'OTransition':'oTransitionEnd',
  'MozTransition':'transitionend',
  'WebkitTransition':'webkitTransitionEnd'
  };
  for(let t in transitions){
  if( el.style[t] !== undefined ){
   return transitions[t];
  }
  }
  el = null;
 }
 }

}
</script>

<style lang="scss" >
.img_rotate{
 transform: rotate(0deg);
}
.round_box{
 width: 100%;
 max-width: 375px;
 position: relative;
 overflow: hidden;
 img{
 width: 100%;
 }
 .center{
 position: absolute;
 top: 50%;
 left: 50%;
 transform: translate(-50%,-50%);
 .pointer{
  width: 5px;
  height: 90px;
  background-color: #f40;
  position: absolute;
  top: -90px;
 }
 .pointer::before{
  content:'';
  width: 0;
  height: 0;
  border-top: 15px solid transparent;
  border-right: 15px solid transparent;
  border-bottom: 15px solid #f40;
  border-left: 15px solid transparent;
  position: absolute;
  top: -20px;
  left: 50%;
  transform: translateX(-50%);
 }
 }
}

</style>

3.0 tips

总体来说有几个点需要注意

1、动画开始前上锁

2、动画结束后通知,状态复位

/**
比如:
基数3圈 reset 360*3
停留位置 第二个 (2 - 1)* 36 = 36
总共角度 360*3 + 36
动画停止后,因为还要继续旋转,所以不可能把角度一直增加,因此需要复位
360*3 + 36 其实可以考虑 就转了 36度,然后再增加需要转的角度
**/

3、继续旋转,因为我们计算是以 30M流量 为初始值的,所以在此旋转 仍然需要以 30M为起点,此时假设 现在停留位置是 300度,也就是说 再转 60度,也就回到了初始位置,本人也是按照这个思路进行复位的。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Vue.js实现大转盘抽奖总结及实现思路

    大家好!先上图看看本次案例的整体效果. 实现思路: Vue component实现大转盘组件,可以嵌套到任意要使用的页面. css3 transform控制大转盘抽奖过程的动画效果. 抽奖组件内使用钩子函数watch监听抽奖结果的返回情况播放大转盘动画并给用户弹出中奖提示. 中奖结果弹窗,为抽奖组件服务. 实现步骤如下: 构建api奖品配置信息和抽奖接口,vuex全局存放奖品配置和中奖结果数据信息. api: export default { getPrizeList () { let priz

  • vue实现手机号码抽奖上下滚动动画示例

    本文介绍了vue实现手机号码抽奖上下滚动动画示例,分享给大家.具体如下: <!DOCTYPE> <html> <head> <meta http-equiv="Content-type" content="text/html; charset=utf-8" /> <title>Document</title> <meta name="viewport" content=

  • 基于VUE实现的九宫格抽奖功能

    先给大家展示下效果图: HTML代码: <template> <div class="luckDraw"> <title-bar :title="title"></title-bar> <div class="container"> <div class="turntable-wrapper"> <div class="luck-wrapp

  • vue组件实现移动端九宫格转盘抽奖

    本文实例为大家分享了vue组件实现移动端九宫格转盘抽奖的具体代码,供大家参考,具体内容如下 vue-lucky-draw 移动端九宫格转盘抽奖vue组件,中奖的奖品数据由接口决定. 效果图 抽奖 因为中奖的结果是后台返回的,所以要考虑转盘的最终停下来的位置必须是在对应后台返回结果的奖品的位置,也就是要模拟出这个中奖的过程(所以所谓的抽奖都是骗人的,嘿嘿).先要写出移动的背景框对应的各个位置的css,然后动态切换class来使其呈现出转动效果.明白了过程就好写了. 中间的按钮用的是css3的ani

  • vue简单实现转盘抽奖

    本文实例为大家分享了vue简单实现转盘抽奖的具体代码,供大家参考,具体内容如下 1.0 思路整理 转盘抽奖很常见,之前也没写过,现在有空来写写,分析如下: 1.1 转盘旋转 ----- 可以用 transform 的 rotate 来解决 1.2 旋转动画 ----- transition 过渡来处理 1.3 停留目标位置及中奖提示 ? ------ 通过控制旋转角度控制停留位置,中奖提示,考虑添加回调 1.1 开始行动 上面的思考,我们知道了大概要实现的步骤,首先我们搞张图片 这个圆盘有 10

  • VUE实现大转盘抽奖

    UI 老规矩,先看下静态UI,以便于有个图像概念 初始参考各值参考图 方案分析-参数配置 核心思路: 将指针和中奖区域划分两部分,目前常规的效果,控制中奖区域旋转,然后停在指针处,当然控制指针也可以,一套思路,dom结构也比较简单,唯一算是复杂点的就是中奖区域,但是如果你足够懒,像我一样,你可以传递一张图也可以,完全依赖远端数据: 关于旋转位置 每个移动位置应均分,360/个数 === 每个奖品所占据的位置,以本文为例8个奖品位置,每个区域应为45deg,每个指针中心位置应为±22.5deg(±

  • vue实现大转盘抽奖功能

    本文实例为大家分享了vue实现大转盘抽奖的具体代码,供大家参考,具体内容如下 效果图如下 中奖提示 代码如下 <template>   <div class="dial" v-wechat-title="$route.meta.title">     <div class="times">抽奖次数{{LuckyClick}}</div>     <!-- 转盘包裹 -->     <

  • 利用Javascript实现简单的转盘抽奖

    首先来看看接口说明:  var _rotate = new iRotate('#div',{ start : 0, //开始角度,可不写,默认0 end :45, //结束角度 time :5000, //持续时间,可不写,默认1000 easing : 'easeOut', //动画形式,目前只有'linear'和'easeOut'两种,可不写,默认'easeOut' callback : function(){ //回调函数 //this为当前对象 } }); _rotate.stop(fu

  • Python使用Tkinter实现转盘抽奖器的步骤详解

    我使用 Python 中的 Tkinter 模块实现了一个简单的滚动抽奖器,接下来继续写一个简单的转盘抽奖器. Tkinter 实现滚动抽奖器参考:https://www.jb51.net/article/177913.htm 滚动抽奖器与点名的场景相似,是从一群人中抽出中奖的人,奖品是提前确定了的,抽奖只是确定中奖的人是谁.这种场景比较适合年会抽奖,奖品的种类和数量已经确定了,通过抽奖来抽出中奖人员,一个奖品对应一次抽奖,直到奖品抽完为止. 还有一种场景是只固定了奖品种类,数量不受限制,有参与

  • vue实现简单转盘抽奖功能

    本文实例为大家分享了vue实现简单转盘抽奖的具体代码,供大家参考,具体内容如下 样式请大家忽略(自己调),主要看JS代码实现,点击按钮后调用start方法,判断是否在转动状态,如果没转动则调用go方法,go方法主要封装了一次性定时器,是个递归函数,调用go函数后即可实现抽奖转盘的效果了,详细代码如下: 注释清晰哦 <template>   <div class="home">     <button @click="start">

  • 简单易扩展可控性强的Jquery转盘抽奖程序

    基于Jquery的Javascript转盘抽奖程序,可以自定义抽奖界面,奖品数量.图片等,可控制中奖的奖品,抽奖转盘转动的速度和圈数. 在实际使用中,应当把概率放到后台程序中运算,以保证安全性和产生中奖奖品的可控性 Javascript代码: <script type="text/javascript"> var index = 1, //当前亮区位置 prevIndex = 14, //前一位置 Speed = 300, //初始速度 Time, //计时器 arr_le

  • jquery.rotate.js实现可选抽奖次数和中奖内容的转盘抽奖代码

    需求: 最多可以抽奖5次,而且,每次只会中"2000元理财金"或者"谢谢参与",其它的不会抽中(哈哈,果然都是套路). 效果如下: 一.页面结构: <div class="g-content"> <div class="g-lottery-case"> <div class="g-left"> <h2>您已拥有<span class="play

随机推荐