vue简单实现转盘抽奖
4621
这篇文章主要为大家详细介绍了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 >
- <img ref="rotImg" src="../assets/zhuan.png" alt="">
- <div>
- <div ></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 >
- .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度,也就回到了初始位置,本人也是按照这个思路进行复位的。
本文网址:https://www.zztuku.com/index.php/detail-8718.html
站长图库 - vue简单实现转盘抽奖
申明:如有侵犯,请 联系我们 删除。
您还没有登录,请 登录 后发表评论!
提示:请勿发布广告垃圾评论,否则封号处理!!