vue实现抽奖滚动
实现抽奖滚动效果
使用Vue实现抽奖滚动效果可以通过动态绑定CSS样式和JavaScript定时器实现。以下是一个完整的实现方案:
基础实现方案
HTML结构

<template>
<div class="lottery-container">
<div class="prize-list" :style="{ transform: `translateY(${translateY}px)` }">
<div class="prize-item" v-for="(item, index) in prizes" :key="index">
{{ item.name }}
</div>
</div>
<button @click="startLottery">开始抽奖</button>
</div>
</template>
JavaScript逻辑
<script>
export default {
data() {
return {
prizes: [
{ name: '奖品1' },
{ name: '奖品2' },
{ name: '奖品3' },
{ name: '奖品4' },
{ name: '奖品5' },
{ name: '奖品6' }
],
translateY: 0,
isRolling: false,
targetIndex: 0,
speed: 50,
timer: null
}
},
methods: {
startLottery() {
if (this.isRolling) return;
this.isRolling = true;
this.targetIndex = Math.floor(Math.random() * this.prizes.length);
this.timer = setInterval(() => {
this.translateY -= 30;
if (this.translateY <= -this.targetIndex * 60 - 300) {
clearInterval(this.timer);
setTimeout(() => {
this.isRolling = false;
}, 1000);
}
}, this.speed);
}
}
}
</script>
CSS样式

<style>
.lottery-container {
height: 60px;
overflow: hidden;
position: relative;
}
.prize-list {
transition: transform 0.5s ease-out;
}
.prize-item {
height: 60px;
line-height: 60px;
text-align: center;
border-bottom: 1px solid #eee;
}
</style>
进阶优化方案
添加缓动效果
methods: {
easeOut(t, b, c, d) {
t /= d;
return -c * t*(t-2) + b;
},
startLottery() {
if (this.isRolling) return;
const duration = 3000;
const startTime = Date.now();
const startPosition = this.translateY;
const endPosition = -this.targetIndex * 60;
const animate = () => {
const now = Date.now();
const progress = now - startTime;
if (progress < duration) {
this.translateY = this.easeOut(progress, startPosition, endPosition - startPosition, duration);
requestAnimationFrame(animate);
} else {
this.translateY = endPosition;
this.isRolling = false;
}
};
this.isRolling = true;
this.targetIndex = Math.floor(Math.random() * this.prizes.length);
animate();
}
}
添加循环滚动效果
methods: {
startLottery() {
if (this.isRolling) return;
this.isRolling = true;
const rounds = 3;
const totalItems = this.prizes.length * rounds + this.targetIndex;
let current = 0;
this.timer = setInterval(() => {
current++;
this.translateY = - (current % this.prizes.length) * 60;
if (current >= totalItems) {
clearInterval(this.timer);
this.isRolling = false;
}
}, 100);
}
}
注意事项
- 确保奖品列表高度与容器高度匹配
- 动画结束后需要重置状态
- 防止用户重复点击开始按钮
- 考虑移动端兼容性问题
- 可以添加音效增强用户体验
以上方案可以根据实际需求进行调整,如改变动画速度、添加更多视觉效果等。






