我是靠谱客的博主 活力刺猬,这篇文章主要介绍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,我找到了这个事件,可以监听元素动画结束事件,只不过有些兼容 这个好办

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/** 动画结束事件兼容 **/ 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 完整示例

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

栗子:

完整代码

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
<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、动画结束后通知,状态复位

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

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

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

最后

以上就是活力刺猬最近收集整理的关于vue简单实现转盘抽奖的全部内容,更多相关vue简单实现转盘抽奖内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(176)

评论列表共有 0 条评论

立即
投稿
返回
顶部