vue实现点击红包雨
Vue 实现点击红包雨效果
实现思路 红包雨效果通常包含随机位置生成红包、动画下落、点击交互和计分功能。Vue的响应式特性可以方便地管理红包状态和用户交互。
核心代码实现
<template>
<div class="red-envelope-rain" @click="handleCanvasClick">
<canvas ref="canvas"></canvas>
<div class="score">得分: {{ score }}</div>
<button @click="startRain">开始红包雨</button>
</div>
</template>
<script>
export default {
data() {
return {
envelopes: [],
score: 0,
animationId: null,
canvas: null,
ctx: null
}
},
mounted() {
this.canvas = this.$refs.canvas
this.ctx = this.canvas.getContext('2d')
this.resizeCanvas()
window.addEventListener('resize', this.resizeCanvas)
},
beforeDestroy() {
cancelAnimationFrame(this.animationId)
window.removeEventListener('resize', this.resizeCanvas)
},
methods: {
resizeCanvas() {
this.canvas.width = window.innerWidth
this.canvas.height = window.innerHeight
},
startRain() {
this.score = 0
this.envelopes = []
this.createEnvelopes()
this.animate()
},
createEnvelopes() {
for (let i = 0; i < 30; i++) {
this.envelopes.push({
x: Math.random() * this.canvas.width,
y: -50,
speed: 2 + Math.random() * 3,
width: 40,
height: 50,
color: `hsl(${Math.random() * 30 + 0}, 100%, 50%)`,
clicked: false
})
}
},
animate() {
this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height)
this.envelopes.forEach(env => {
if (!env.clicked) {
env.y += env.speed
this.drawEnvelope(env)
if (env.y > this.canvas.height) {
env.y = -50
env.x = Math.random() * this.canvas.width
}
}
})
this.animationId = requestAnimationFrame(this.animate)
},
drawEnvelope(env) {
this.ctx.fillStyle = env.color
this.ctx.fillRect(env.x, env.y, env.width, env.height)
this.ctx.fillStyle = 'gold'
this.ctx.font = '16px Arial'
this.ctx.fillText('¥', env.x + 15, env.y + 30)
},
handleCanvasClick(e) {
const rect = this.canvas.getBoundingClientRect()
const x = e.clientX - rect.left
const y = e.clientY - rect.top
this.envelopes.forEach(env => {
if (!env.clicked &&
x > env.x && x < env.x + env.width &&
y > env.y && y < env.y + env.height) {
env.clicked = true
this.score += Math.floor(Math.random() * 10) + 1
}
})
}
}
}
</script>
<style>
.red-envelope-rain {
position: relative;
width: 100vw;
height: 100vh;
overflow: hidden;
}
canvas {
display: block;
background: linear-gradient(to bottom, #87CEEB, #E0F7FA);
}
.score {
position: absolute;
top: 20px;
right: 20px;
font-size: 24px;
color: white;
text-shadow: 1px 1px 2px black;
}
button {
position: absolute;
bottom: 20px;
left: 50%;
transform: translateX(-50%);
padding: 10px 20px;
font-size: 18px;
background: #FF5252;
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
}
</style>
功能优化建议
增加视觉效果
- 添加红包打开动画效果,点击时显示金额弹窗
- 实现红包旋转摆动效果增强真实感
- 添加背景音乐和点击音效
性能优化
- 使用对象池管理红包对象,避免频繁创建销毁
- 对于不可见区域的红包暂停渲染
- 使用CSS transform代替直接修改位置属性
游戏机制扩展
- 添加倒计时功能限制游戏时间
- 实现不同红包类型和不同分值
- 添加最高分记录功能
实现要点说明
Canvas渲染 使用Canvas而非DOM元素渲染红包,能获得更好的性能表现,特别是在大量红包同时下落时。
响应式设计 通过监听resize事件确保Canvas始终适应窗口尺寸,保证在各种设备上正常显示。
动画循环 使用requestAnimationFrame实现平滑动画效果,在组件销毁时记得取消动画循环防止内存泄漏。
碰撞检测 通过简单的矩形碰撞检测判断点击位置是否落在红包上,这是实现交互功能的关键。







