vue轮播抽奖实现思路
Vue轮播抽奖实现思路
数据结构设计
使用数组存储奖品列表,每个奖品对象包含名称、图片、背景色等属性。示例数据结构:

prizes: [
{ id: 1, name: '奖品1', icon: 'prize1.png', bgColor: '#FF0000' },
{ id: 2, name: '奖品2', icon: 'prize2.png', bgColor: '#00FF00' }
]
核心动画实现
采用CSS过渡或requestAnimationFrame实现平滑滚动效果。通过动态修改transform属性实现无限循环滚动:

// 关键动画逻辑
updatePosition() {
this.currentPosition -= this.speed
if (Math.abs(this.currentPosition) >= this.itemWidth) {
this.currentPosition = 0
this.cycleCount++
}
this.$refs.carousel.style.transform = `translateX(${this.currentPosition}px)`
}
抽奖控制逻辑
设置减速曲线和停止位置算法,确保最终停在指定奖品位置:
stopAtPrize(targetIndex) {
const totalItems = this.prizes.length
const targetPosition = -(targetIndex * this.itemWidth + this.cycleCount * totalItems * this.itemWidth)
// 缓动函数实现减速
const easing = t => t*(2-t)
let startTime = null
const duration = 3000
const animate = (timestamp) => {
if (!startTime) startTime = timestamp
const progress = (timestamp - startTime) / duration
const easedProgress = easing(progress)
this.currentPosition = this.startPosition + (targetPosition - this.startPosition) * easedProgress
this.$refs.carousel.style.transform = `translateX(${this.currentPosition}px)`
if (progress < 1) {
requestAnimationFrame(animate)
} else {
this.isRolling = false
}
}
requestAnimationFrame(animate)
}
视觉优化技巧
添加半透明遮罩层增强视觉焦点效果,使用CSS滤镜突出中心奖品:
.mask {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: linear-gradient(
to right,
rgba(0,0,0,0.8) 0%,
rgba(0,0,0,0) 20%,
rgba(0,0,0,0) 80%,
rgba(0,0,0,0.8) 100%
);
pointer-events: none;
}
.active-prize {
transform: scale(1.2);
filter: drop-shadow(0 0 10px gold);
transition: all 0.3s ease;
}
完整组件示例
<template>
<div class="lottery-container">
<div class="mask"></div>
<div class="prize-carousel" ref="carousel">
<div
v-for="(prize, index) in prizes"
:key="prize.id"
class="prize-item"
:style="{ backgroundColor: prize.bgColor }"
:class="{ 'active-prize': activeIndex === index }"
>
<img :src="prize.icon" />
<p>{{ prize.name }}</p>
</div>
</div>
<button @click="startLottery" :disabled="isRolling">
开始抽奖
</button>
</div>
</template>
注意事项
- 移动端需添加touch事件支持
- 奖品数量变化时需要重新计算itemWidth
- 中奖概率算法应独立于UI组件实现
- 大量奖品时考虑虚拟滚动优化性能
- 添加resize事件监听器处理窗口大小变化






