年底了,公司开始各种优惠券抽取活动,在 H5 页面实现一个点击抽奖活动,中奖是后端控制,根据接口返回的奖项来停止转动;
效果图
代码
1、父组件
<template>
<div class="about">
<luck-draw :awards="awards" :award="award" :speed.sync="speed" :diff="diff"></luck-draw>
</div>
</template>
<script type="text/javascript">
import luckDraw from './luckDraw'
export default {
components:{ luckDraw },
data() {
return {
awards: [
// 名字与ID
{ id: 1, name: '1' },
{ id: 2, name: '2' },
{ id: 3, name: '3' },
{ id: 4, name: '4' },
{ id: 5, name: '5' },
{ id: 6, name: '6' },
{ id: 7, name: '7' },
{ id: 8, name: '8' },
{ id: 9, name: '9' }
],
//中奖项
award:{
id:2
},
//跳动速度
speed:300,
//衰减值
diff:12
}
}
}
</script>
2、子组件
<template>
<div class="container">
<div class="rotary_table">
<div v-for="(item, index) in awards" :key="index" class="award">
{{item.name}}
<div class="mask" v-if="index == current"></div>
</div>
</div>
<p class="start-btn" @click="start">点击抽奖</p>
</div>
</template>
<script>
export default {
name: "luckDraw",
props: {
awards: {
type: Array
},
award: {
type: Object
},
speed: {
type: Number,
default: 300
},
diff: {
type: Number,
default: 15
}
},
data() {
return {
speeds:200,
current: 0, // 当前索引值
time: 0, // 当前时间戳
timer: null, // 定时器
};
},
mounted(){
this.speeds = this.speed;
},
methods: {
// 开始抽奖
start() {
// 开始抽奖
this.move();
this.time = Date.now();
},
// 开始转动
move() {
this.timer = setTimeout(() => {
this.current++;
if (this.current > this.awards.length-1) {
this.current = 0;
}
// 若抽中的奖品id存在,则开始减速转动
if (this.award.id && (Date.now() - this.time) / 1000 > 2) {
this.speeds += this.diff; // 转动减速
// 若转动时间超过4秒,并且奖品id等于小格子的奖品id,则停下来
if ((Date.now() - this.time) / 1000 > 3 && this.award.id == this.awards[this.current].id) {
clearTimeout(this.timer);
setTimeout(() => {
//转盘结束之后可以调取父组件的方法,弹出获奖弹窗
console.log(`恭喜中奖${this.award.id}元`);
}, 0);
return;
}
} else {
// 若抽中的奖品不存在,则加速转动
this.speeds -= this.diff;
}
this.move();
}, this.speeds);
}
}
};
</script>
<style scoped>
.container{
width: 100%;
height: 100%;
}
.rotary_table{
display: flex;
flex-wrap: wrap;
}
.award{
border: 1px solid #ccc;
margin-bottom: 10px;
margin-right: 2vw;
position: relative;
border-radius: 10px;
width: 30vw;
height: 49px;
line-height: 49px;
text-align: center;
}
.award:nth-of-type(3n){
margin-right: 0;
}
.mask{
width: 30vw;
height: 49px;
position: absolute;
border-radius: 10px;
top: 0;
left: 0;
background-color: #fff0bd;
opacity: 0.6;
}
.start-btn {
width: 100%;
height: 49px;
text-align: center;
}
</style>