vue 实现红包雨
实现红包雨的基本思路
红包雨是一种常见的互动游戏效果,需要在屏幕上随机掉落多个红包,用户可以点击红包获取奖励。使用Vue实现红包雨需要结合CSS动画和JavaScript逻辑。
红包雨组件结构
创建Vue组件来管理红包的生成、动画和点击事件。组件需要包含红包元素和动画效果。
<template>
<div class="red-packet-rain">
<div
v-for="(packet, index) in packets"
:key="index"
class="red-packet"
:style="packet.style"
@click="onClickPacket(packet)"
>
{{ packet.value }}
</div>
</div>
</template>
红包数据初始化
在Vue的data中定义红包数组,每个红包对象包含位置、速度和值等属性。
data() {
return {
packets: [],
packetCount: 20,
maxSpeed: 5,
minSpeed: 2,
maxLeft: window.innerWidth - 50
}
}
生成随机红包
使用定时器或循环生成随机位置和速度的红包。

methods: {
createPacket() {
const left = Math.random() * this.maxLeft
const speed = this.minSpeed + Math.random() * (this.maxSpeed - this.minSpeed)
const value = Math.floor(Math.random() * 100) + 1
this.packets.push({
left,
speed,
value,
style: {
left: `${left}px`,
top: '-50px',
animationDuration: `${speed}s`
}
})
},
startRain() {
for (let i = 0; i < this.packetCount; i++) {
setTimeout(() => this.createPacket(), i * 300)
}
}
}
CSS动画效果
定义红包下落和消失的动画效果。
.red-packet-rain {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
pointer-events: none;
overflow: hidden;
}
.red-packet {
position: absolute;
width: 50px;
height: 60px;
background: red;
color: yellow;
text-align: center;
line-height: 60px;
border-radius: 5px;
pointer-events: auto;
animation: fall linear forwards;
}
@keyframes fall {
to {
transform: translateY(calc(100vh + 50px));
}
}
处理红包点击事件
点击红包时移除红包并触发奖励逻辑。

methods: {
onClickPacket(packet) {
this.packets = this.packets.filter(p => p !== packet)
this.$emit('reward', packet.value)
}
}
组件生命周期控制
在mounted钩子中开始红包雨,在组件销毁时清理资源。
mounted() {
this.startRain()
},
beforeDestroy() {
clearInterval(this.rainInterval)
}
优化性能
对于大量红包,可以使用Vue的transition-group或requestAnimationFrame优化性能。
// 使用requestAnimationFrame更新位置
updatePositions() {
this.packets.forEach(packet => {
packet.top += packet.speed
packet.style.top = `${packet.top}px`
if (packet.top > window.innerHeight) {
this.packets = this.packets.filter(p => p !== packet)
}
})
if (this.packets.length) {
requestAnimationFrame(this.updatePositions)
}
}
响应式调整
监听窗口大小变化,调整红包的最大水平位置。
created() {
window.addEventListener('resize', this.handleResize)
},
methods: {
handleResize() {
this.maxLeft = window.innerWidth - 50
}
},
beforeDestroy() {
window.removeEventListener('resize', this.handleResize)
}
使用注意事项
- 红包数量不宜过多,避免性能问题
- 移动端需要调整触摸事件处理
- 可以添加红包旋转或摆动动画增强效果
- 考虑添加背景音乐和音效提升体验
通过以上方法可以实现基本的红包雨效果,可以根据具体需求调整动画样式和交互逻辑。






