266 lines
6.4 KiB
Vue
266 lines
6.4 KiB
Vue
<template>
|
||
<page-container title="每日免费送" :showBack="true">
|
||
<view class="prize-draw">
|
||
<view style="height: 512rpx;"></view>
|
||
<view class="choujiang">
|
||
<view style="height:52rpx;"></view>
|
||
<view class="neiquan">
|
||
<view class="grid-container">
|
||
<view class="jiangping" v-for="(item, index) in 9"
|
||
:class="{ 'xuanzhong': currentIndex === index && !isFinalWin, 'win-flash': currentIndex === index && isFinalWin }"
|
||
:key="index">
|
||
<!-- 奖品图片将在这里显示 -->
|
||
<image src="https://image.zfunbox.cn/huodong/kuang.png" style="width:95%;height:95%;margin-left: 1rpx;border-radius: 25rpx;">
|
||
</image>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<view class="draw-btn-container">
|
||
<view class="draw-btn" @click="startDraw"></view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</page-container>
|
||
</template>
|
||
|
||
<script>
|
||
import PageContainer from '@/components/page-container/page-container.vue'
|
||
|
||
export default {
|
||
components: {
|
||
PageContainer
|
||
},
|
||
data() {
|
||
return {
|
||
isDrawing: false,
|
||
prizes: [
|
||
// 这里可以放置奖品数据
|
||
],
|
||
currentIndex: -1, // 当前选中的索引
|
||
timer: null, // 定时器
|
||
speed: 100, // 初始速度,数值越小速度越快
|
||
times: 0, // 动画运行次数计数
|
||
targetIndex: 0, // 最终中奖索引
|
||
isFinalWin: false, // 是否到达最终中奖状态
|
||
animationType: 1, // 动画类型:1=顺序遍历,2=8字形
|
||
path8Index: 0, // 8字形路径当前位置
|
||
animationTypes: {
|
||
SEQUENTIAL: 1, // 顺序遍历
|
||
FIGURE_EIGHT: 2 // 8字形走法
|
||
},
|
||
pathFigureEight: [0, 1, 2, 5, 4, 3, 6, 7, 8, 5, 4, 3], // 8字形路径
|
||
};
|
||
},
|
||
methods: {
|
||
startDraw() {
|
||
if (this.isDrawing) return;
|
||
this.isDrawing = true;
|
||
this.isFinalWin = false; // 重置中奖闪烁状态
|
||
|
||
// 清除可能存在的定时器
|
||
if (this.timer) {
|
||
clearInterval(this.timer);
|
||
this.timer = null;
|
||
}
|
||
|
||
// 重置计数和速度
|
||
this.times = 0;
|
||
this.speed = 100;
|
||
this.path8Index = 0;
|
||
|
||
// 随机选择动画类型:1-2之间
|
||
this.animationType = Math.floor(Math.random() * 2) + 1;
|
||
let animationName = "顺序遍历";
|
||
if (this.animationType === this.animationTypes.FIGURE_EIGHT) {
|
||
animationName = "8字形";
|
||
}
|
||
console.log('抽奖动画类型:', animationName);
|
||
|
||
// 随机生成中奖索引(0-8之间)
|
||
this.targetIndex = Math.floor(Math.random() * 9);
|
||
|
||
// 开始动画
|
||
this.runAnimation();
|
||
},
|
||
|
||
runAnimation() {
|
||
this.timer = setInterval(() => {
|
||
this.times++;
|
||
|
||
// 根据不同的动画类型选择下一个格子
|
||
if (this.animationType === this.animationTypes.SEQUENTIAL) {
|
||
// 顺序遍历方式
|
||
this.currentIndex = (this.currentIndex + 1) % 9;
|
||
} else {
|
||
// 8字形路径
|
||
this.path8Index = (this.path8Index + 1) % this.pathFigureEight.length;
|
||
this.currentIndex = this.pathFigureEight[this.path8Index];
|
||
}
|
||
|
||
// 动画速度控制
|
||
if (this.times > 20) { // 前20次保持高速
|
||
if (this.times > 30) { // 30次后开始减速
|
||
this.speed += 10; // 速度递减
|
||
}
|
||
|
||
// 如果速度减到一定程度,并且当前索引接近中奖索引,则停止
|
||
if (this.speed > 300 && this.currentIndex === this.targetIndex) {
|
||
clearInterval(this.timer);
|
||
this.timer = null;
|
||
this.startWinAnimation();
|
||
return; // 重要:确保不再继续执行
|
||
}
|
||
|
||
// 只有在需要改变速度时才重新设置定时器
|
||
clearInterval(this.timer);
|
||
this.timer = null;
|
||
this.runAnimation();
|
||
}
|
||
}, this.speed);
|
||
},
|
||
|
||
startWinAnimation() {
|
||
// 开始中奖闪烁动画
|
||
this.isFinalWin = true;
|
||
|
||
// 播放闪烁效果后显示结果
|
||
setTimeout(() => {
|
||
this.showResult();
|
||
}, 1500); // 闪烁1.5秒后显示结果
|
||
},
|
||
|
||
showResult() {
|
||
// 动画结束后的操作
|
||
setTimeout(() => {
|
||
this.isDrawing = false;
|
||
uni.showToast({
|
||
title: '恭喜获得奖品!',
|
||
icon: 'none',
|
||
duration: 2000
|
||
});
|
||
|
||
// 这里可以添加中奖弹窗或其他效果
|
||
}, 500);
|
||
}
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style lang="scss">
|
||
.prize-draw {
|
||
background: url($baseurl+'huodong/bg.png') no-repeat center center;
|
||
background-size: 100% 100%;
|
||
height: 1495.14rpx;
|
||
width: 100vw;
|
||
|
||
.choujiang {
|
||
background: url($baseurl+'huodong/ke.png') no-repeat center center;
|
||
background-size: 100% 100%;
|
||
margin: 0px auto;
|
||
height: 829.86rpx;
|
||
width: 90%;
|
||
position: relative;
|
||
|
||
.neiquan {
|
||
width: 430rpx;
|
||
height: 465rpx;
|
||
margin: 0px auto;
|
||
padding: 15rpx;
|
||
box-sizing: border-box;
|
||
}
|
||
|
||
.grid-container {
|
||
display: grid;
|
||
grid-template-columns: repeat(3, 1fr);
|
||
grid-template-rows: repeat(3, 1fr);
|
||
gap: 10rpx;
|
||
width: 100%;
|
||
height: 100%;
|
||
}
|
||
|
||
.jiangping {
|
||
// background: url($baseurl+'huodong/kuang.png') no-repeat center center;
|
||
// background-size: 100% 100%;
|
||
// border: 1px dashed #75C5FF;
|
||
|
||
border-radius: 12rpx;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
background-color: rgba(255, 255, 255, 0.7);
|
||
transition: all 0.05s; // 加快过渡效果,让动画更流畅
|
||
|
||
&:active {
|
||
transform: scale(0.95);
|
||
}
|
||
}
|
||
|
||
.draw-btn-container {
|
||
position: absolute;
|
||
bottom: 95rpx;
|
||
left: 50%;
|
||
transform: translateX(-50%);
|
||
width: 100%;
|
||
display: flex;
|
||
justify-content: center;
|
||
|
||
}
|
||
|
||
.draw-btn {
|
||
width: 298.61rpx;
|
||
height: 118.75rpx;
|
||
background: url($baseurl+'huodong/anniu.png') no-repeat;
|
||
background-size: 100% 100%;
|
||
font-size: 32rpx;
|
||
font-weight: bold;
|
||
//border-radius: 40rpx;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
//box-shadow: 0 4rpx 8rpx rgba(255, 87, 34, 0.3);
|
||
transition: all 0.3s;
|
||
|
||
&:active {
|
||
transform: scale(0.95);
|
||
//box-shadow: 0 2rpx 4rpx rgba(255, 87, 34, 0.3);
|
||
}
|
||
}
|
||
}
|
||
|
||
.xuanzhong {
|
||
background: url($baseurl+'huodong/xuanzhong.png') no-repeat !important;
|
||
background-size: 100% 100% !important;
|
||
width: 100% !important;
|
||
height: 100% !important;
|
||
}
|
||
|
||
.win-flash {
|
||
background: url($baseurl+'huodong/xuanzhong.png') no-repeat !important;
|
||
background-size: 100% 100% !important;
|
||
width: 100% !important;
|
||
height: 100% !important;
|
||
animation: win-blink 0.3s 5 alternate;
|
||
}
|
||
|
||
@keyframes win-blink {
|
||
0% {
|
||
opacity: 1;
|
||
transform: scale(1);
|
||
}
|
||
100% {
|
||
opacity: 0.5;
|
||
transform: scale(1.05);
|
||
}
|
||
}
|
||
|
||
@keyframes pulse {
|
||
from {
|
||
opacity: 1;
|
||
}
|
||
to {
|
||
opacity: 0.8;
|
||
}
|
||
}
|
||
}
|
||
</style>
|