vue实现数字抽奖
Vue 实现数字抽奖功能
基本思路
通过 Vue 的数据响应式特性,结合定时器和随机数生成,实现数字快速滚动后停在指定奖品的动画效果。核心是利用 setInterval 控制数字变化速度,通过 setTimeout 控制停止时机。
基础实现代码
<template>
<div class="lottery">
<div class="display">{{ displayNumber }}</div>
<button @click="startLottery" :disabled="isRolling">开始抽奖</button>
</div>
</template>
<script>
export default {
data() {
return {
displayNumber: 0,
targetNumber: 8888, // 预设中奖数字
isRolling: false,
rollInterval: null
}
},
methods: {
startLottery() {
if (this.isRolling) return
this.isRolling = true
this.displayNumber = 0
const duration = 3000 // 动画总时长
const startTime = Date.now()
this.rollInterval = setInterval(() => {
const elapsed = Date.now() - startTime
const progress = Math.min(elapsed / duration, 1)
// 缓动函数使动画先快后慢
const easeOut = t => 1 - Math.pow(1 - t, 3)
const currentProgress = easeOut(progress)
// 生成随机数过渡效果
this.displayNumber = Math.floor(
this.targetNumber * currentProgress * Math.random() * 1.5
)
if (progress === 1) {
clearInterval(this.rollInterval)
this.displayNumber = this.targetNumber
this.isRolling = false
}
}, 30)
}
}
}
</script>
<style>
.lottery {
text-align: center;
font-family: Arial;
}
.display {
font-size: 48px;
margin: 20px;
color: #e74c3c;
}
button {
padding: 10px 20px;
font-size: 16px;
background: #3498db;
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
}
button:disabled {
background: #95a5a6;
}
</style>
进阶优化方案
增加奖品列表支持
data() {
return {
prizes: [100, 200, 500, 1000, 2000, 5000],
currentPrizeIndex: -1
}
},
methods: {
getRandomPrize() {
this.currentPrizeIndex = Math.floor(Math.random() * this.prizes.length)
return this.prizes[this.currentPrizeIndex]
},
startLottery() {
this.targetNumber = this.getRandomPrize()
// 其余逻辑保持不变
}
}
添加音效增强体验
<audio ref="rollSound" src="rolling-sound.mp3" loop></audio>
<audio ref="winSound" src="win-sound.mp3"></audio>
<script>
methods: {
startLottery() {
this.$refs.rollSound.play()
// ...原有逻辑
if (progress === 1) {
this.$refs.rollSound.pause()
this.$refs.winSound.play()
}
}
}
</script>
数字动画优化技巧
自定义缓动函数
// 在方法中添加不同的缓动效果
const easingFunctions = {
easeInOut: t => t<.5 ? 2*t*t : -1+(4-2*t)*t,
elastic: t => (.04 - 1/(t*20+1)) * Math.sin(25*t) + 1
}
数字格式化显示
computed: {
formattedNumber() {
return this.displayNumber.toLocaleString()
}
}
注意事项
- 移动端适配需要调整字体大小和按钮样式
- 长时间滚动可能影响性能,建议设置最大持续时间
- 中奖概率可通过调整奖品数组中的数值比例控制
- 对于大额数字,建议增加千位分隔符提高可读性
实际项目中可根据需求添加背景动画、光影效果等视觉元素增强表现力。关键是要平衡动画时长和用户体验,通常3-5秒的动画持续时间较为合适。







