在Vue/JS里面怎么做前端抽奖转盘,并且调整中奖概率?
一、受前端广大网友的启发,编写在Vue里面做抽奖转盘的程序,同时可以调整中奖概率;1、效果图2、附素材原图,可自行下载练习(名称顺序为pointer.pngturntable.pngturntable-bg.jpg)3、演示视频Vue/JS里做前端抽奖转盘二、实现原理:CSS的transitions:rotate属性,传入度数即可旋转;调整中奖概率各有各的做法
·
一、受前端广大网友的启发,编写在Vue里面做抽奖转盘的程序,同时可以调整中奖概率;
1、效果图
2、附素材原图,可自行下载练习(名称顺序为pointer.png turntable.png turntable-bg.jpg)
3、演示视频
Vue/JS里做前端抽奖转盘
二、实现原理:CSS的transitions:rotate属性,传入度数即可旋转;调整中奖概率各有各的做法,本文的做法是作者通过比较骇客的办法,写了几乎人人可以看懂的流程,也比较巧妙地实现了对概率的控制,称不上多牛*的算法,但确实达到了效果;
1、创建个Vue的项目,在App.vue文件里写以下程序:
<style>
#bg {
width: 650px;
height: 600px;
margin: 0 auto;
background: url('./turntable-bg.jpg') no-repeat;
position: relative;
}
.pointer{
position: absolute;
z-index: 10;
top: 155px;
left: 247px;
}
.turntable{
position: absolute;
z-index: 5;
top: 60px;
left: 116px;
transition: all 4s; /*动画执行时间为4s */
}
</style>
<template>
<div id="bg">
<img @click="go" class="pointer" src="./pointer.png" alt="pointer">
<img ref="turntable" class="turntable" src="./turntable.png" alt="turntable">
<h1>你的抽奖次数为:{{goTimes}}</h1>
</div>
</template>
<script>
export default {
name:'App',
data(){
return {
isGo: false, //是否正在执行动画
oTurntable:'', //执行动画的对象
randomDeg: 0, //即将旋转的度数
lastDeg:0, //上一次旋转的度数
goTimes:5 //抽奖次数
}
},
methods:{
go(){
if(!this.isGo && this.goTimes >0){ this.getNumber() }
else if(!this.isGo && this.goTimes <=0){ alert('抱歉您的抽奖次数用完了') }
else return //表明正在抽奖,未结束扔点击无效
},
getRandom(n,m){ //该方法能产生[n,m]之间随机数
let result = Math.floor(Math.floor(Math.random()*(m-n+1)+n))
return result;
},
getNumber(){
/*
调整中奖概率(让每次旋转前指针都在初始位置,这样才准确)
想转到第一项,需要转:360/7*0 + 360/7/2; --->该项为超级大奖奖项
想转到第二项,需要转:360/7*1 + 360/7/2;
想转到第三项,需要转:360/7*2 + 360/7/2;
想转到第四项,需要转:360/7*3 + 360/7/2;
想转到第五项,需要转:360/7*4 + 360/7/2;
想转到第六项,需要转:360/7*5 + 360/7/2;
想转到第七项,需要转:360/7*6 + 360/7/2; --->该项为未中奖项
*/
let number = this.getRandom(0,100)
let caseNum = ''
if(number === 0){
caseNum = 0 //粗略概率为1%
}else if(number > 0 && number <5){
caseNum = 1 //粗略概率为5%
}else if(number >= 5 && number <10){
caseNum = 2 //粗略概率为5%
}else if(number >= 10 && number <15){
caseNum = 3 //粗略概率为5%
}else if(number >= 15 && number <20){
caseNum = 4 //粗略概率为5%
}else if(number >= 20 && number <25){
caseNum = 5 //粗略概率为5%
}else{
caseNum = 6 //粗略概率为75%
}
switch(caseNum){
case 0:
this.ratating(360/7*0 + 360/7/2,"免单4999元");
break;
case 1:
this.ratating(360/7*1 + 360/7/2,"免单50元");
break;
case 2:
this.ratating(360/7*2 + 360/7/2,"免单10元");
break;
case 3:
this.ratating(360/7*3 + 360/7/2,"免单5元");
break;
case 4:
this.ratating(360/7*4 + 360/7/2,"免分期服务费");
break;
case 5:
this.ratating(360/7*5 + 360/7/2,"提高白条额度");
break;
default:
this.ratating(360/7*6 + 360/7/2,"未中奖");
break;
}
},
ratating(deg,text){
this.goTimes --
this.isGo = true
let times = this.getRandom(3,6)//圈数(从用户体验角度考虑,设计随机转3-6圈。最少3圈,最多6圈)
this.randomDeg = deg + 360 * times //记录这次要旋转的度数(传来的度数+圈数)
let realDeg = (360 - this.lastDeg % 360) + this.lastDeg + this.randomDeg
/*上次指针离初始状态的度数 + 上次的度数 + 这次要旋转的度数
(这样的目的是为了每次旋转都从原点开始,保证数据准确)*/
this.oTurntable.style.transform = `rotate(${realDeg}deg)`;
setTimeout(() => {
this.isGo = false
console.log(`以原点为基准共旋转了${this.randomDeg}度,
以一圈为基准相对旋转了${this.randomDeg % 360}度,最终结果为${text}`)
this.lastDeg = realDeg //把这次度数存储起来,方便下一次获取
},4000) //4000ms为css里面写的执行动画的时间
},
},
mounted(){
this.oTurntable = this.$refs.turntable
}
}
</script>
2、大家细心读完代码程序会发现我们每次旋转都加上了上一次旋转的度数,这是为什么:
----如果不加上上一次旋转的度数,直接用这次的旋转度数,会有问题,比如:我第一次旋转刚好旋转了1000度,正常转,没问题,但我第二次旋转抽中旋转500度,那么,旋转对象会在第一次的基础上往回退500度,因为他每次旋转都是以0参考对象,到时候一会逆时针转一会顺时针转,很难看,抽奖的人到时候都晕了,因此必须在上一次旋转的基础上再加上这次旋转的度数;
3、this.lastDeg % 360是获得余数,也就是排除圈数,获得离原点的度数;
4、希望本文能对你有帮助,参考本文的思想,去实现自己的抽奖程序。
更多推荐
已为社区贡献4条内容
所有评论(0)