简单改造了一个九宫格转盘,还有需要优化的地方~
上代码:
<template>
<div class="v-common-com-lottery">
<ul class="list">
<li
class="item"
:class="['item' + index, { active: item.active }]"
:key="index"
v-for="(item, index) in list"
>
<span class="info">{{ item.info }}</span>
<span class="mask"></span>
</li>
<li class="btn" @click="move">
<span class="text">按钮</span>
<i class="mask"></i>
</li>
</ul>
</div>
</template>
export default {
data() {
return {
list: [
{
info: "谢谢参与",
active: false,
},
{
info: "5元现金券",
active: false,
},
{
info: "50元代金券",
active: false,
},
{
info: "谢谢参与",
active: false,
},
{
info: "谢谢参与",
active: false,
},
{
info: "5元现金券",
active: false,
},
{
info: "20元现金券",
active: false,
},
{
info: "100元现金券",
active: false,
},
],
// 上次停留位置 index
lastIndex: 0,
// 服务器返回停留位置 index
stopIndex: 0,
// 正常转动动画
timer1: null,
// 进入低速转动动画
timer2: null,
// 低速转动动画
timer3: null,
// 正在执行动画
isMoving: false,
// 转动次数 最小12次(一圈半) 防止转动时间过短
times: 0,
// 接口成功返回停止stopIndex 标识
ajaxEnd: false,
// 进入低速转动动画 标识
timerEnd: false,
luckyTimes: 100, // 用户抽奖次数
};
},
watch: {
times(val) {
// 如果计数过程中,ajax未成功
if (!this.ajaxEnd) {
return false;
}
// 控制转盘转动次数
if (val >= 21) {
this.timerEnd = true;
}
},
},
methods: {
getStopIndex() {
this.ajaxEnd = true;
this.stopIndex = 5;
},
move() {
// 点击开始游戏按钮
if (!this.luckyTimes) {
console.log("没有抽奖次数了");
return false;
}
// 判断是否正在转盘
if (this.isMoving) {
return false;
}
this.isMoving = true;
this.ajaxEnd = false;
this.timerEnd = false;
this.times = 0;
console.log("上次停止位置: ", this.lastIndex);
let i = this.lastIndex;
// 执行ajax请求数据
this.getStopIndex();
// 执行动画
this.timer1 = setInterval(() => {
this.times++;
i++;
if (i === 8) {
i = 0;
}
this.list.map((item) => {
item.active = false;
});
// 设置当前转到的区域显示蒙层
this.$set(this.list[i], "active", true);
// 当获取到服务器数据 index
if (this.timerEnd) {
console.log("服务器返回的停止位置: ", this.stopIndex);
clearInterval(this.timer1);
this.enter(i, this.stopIndex);
}
}, 100);
},
enter(cur, stop) {
// 计算需要停止的index
console.log("enter", cur, stop);
let count = stop - cur;
console.log("计算需要停止的index", count);
if (count <= 4) {
count = count > -4 ? count + 8 : count + 16;
}
console.log("计算需要停止的index", count);
let i = cur;
this.timer2 = setInterval(() => {
count--;
i++;
if (i === 8) {
i = 0;
}
this.list.map((e) => {
e.active = false;
});
this.$set(this.list[i], "active", true);
if (count === 4) {
clearInterval(this.timer2);
this.stop(i, stop);
}
}, 100);
},
stop(cur, stop) {
console.log(stop);
// 计算需要停止的index
let count = 0;
let i = cur;
this.timer3 = setInterval(() => {
count++;
i++;
if (i === 8) {
i = 0;
}
this.list.map((e) => {
e.active = false;
});
this.$set(this.list[i], "active", true);
if (count === 4) {
clearInterval(this.timer3);
this.isMoving = false;
this.lastIndex = this.stopIndex;
this.luckyTimes--;
}
}, 200);
},
},
beforeDestroy() {
// 组件销毁前
// 清除定时器
clearInterval(this.timer1);
clearInterval(this.timer2);
clearInterval(this.timer3);
},
};
<style lang="scss">
.v-common-com-lottery {
height: 100%;
font-size: 0.24rem;
color: #fff;
.list {
position: relative;
background: lightblue;
width: 100%;
padding-bottom: 100%;
}
.item {
width: 32%;
padding-bottom: 32%;
position: absolute;
background: rgb(212, 212, 212);
border-radius: 0.24rem;
overflow: hidden;
&.item0 {
left: 0;
top: 0;
}
&.item1 {
left: 34%;
top: 0;
}
&.item2 {
left: 68%;
top: 0;
}
&.item3 {
left: 68%;
top: 34%;
}
&.item4 {
left: 68%;
top: 68%;
}
&.item5 {
left: 34%;
top: 68%;
}
&.item6 {
left: 0;
top: 68%;
}
&.item7 {
left: 0;
top: 34%;
}
.icon {
position: absolute;
height: 100%;
width: 100%;
z-index: 1;
}
.info {
position: absolute;
left: 0;
bottom: 0;
background: linear-gradient(rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.5));
height: 1.48rem;
width: 100%;
z-index: 2;
display: flex;
align-items: center;
justify-content: center;
}
.mask {
position: absolute;
left: 0;
top: 0;
z-index: 3;
width: 100%;
height: 100%;
background: rgba(241, 141, 10, 0.884);
opacity: 0;
}
&.active .mask {
opacity: 1;
}
}
.btn {
width: 32%;
padding-bottom: 32%;
background: lightsalmon;
position: absolute;
left: 34%;
top: 34%;
font-size: 0.72rem;
border-radius: 0.24rem;
overflow: hidden;
.text {
position: absolute;
height: 100%;
width: 100%;
display: flex;
align-items: center;
justify-content: center;
z-index: 2;
}
.mask {
position: absolute;
height: 100%;
width: 100%;
display: flex;
align-items: center;
justify-content: center;
z-index: 2;
}
}
.lucky-times {
color: #000;
font-size: 0.36rem;
}
}
</style>