vue实现子弹循环
Vue实现子弹循环动画
在Vue中实现子弹循环动画可以通过CSS动画或JavaScript动画库实现。以下是几种常见方法:
方法1:使用CSS动画和Vue过渡
通过Vue的<transition>或<transition-group>组件结合CSS动画实现子弹移动效果:
<template>
<div class="bullet-container">
<div
v-for="(bullet, index) in bullets"
:key="index"
class="bullet"
:style="{ left: bullet.x + 'px', top: bullet.y + 'px' }"
></div>
</div>
</template>
<script>
export default {
data() {
return {
bullets: []
}
},
mounted() {
setInterval(() => {
this.bullets.push({
x: 0,
y: Math.random() * 300
})
}, 500)
setInterval(() => {
this.bullets = this.bullets.map(bullet => ({
...bullet,
x: bullet.x + 5
})).filter(bullet => bullet.x < 800)
}, 16)
}
}
</script>
<style>
.bullet {
position: absolute;
width: 10px;
height: 10px;
background-color: red;
border-radius: 50%;
transition: left 0.1s linear;
}
.bullet-container {
position: relative;
width: 800px;
height: 400px;
border: 1px solid #ccc;
}
</style>
方法2:使用GSAP动画库
GSAP提供更强大的动画控制能力:
<template>
<div ref="container" class="bullet-container">
<div
v-for="(bullet, index) in bullets"
:key="index"
ref="bullets"
class="bullet"
></div>
</div>
</template>
<script>
import { gsap } from 'gsap'
export default {
data() {
return {
bullets: []
}
},
mounted() {
setInterval(() => {
this.bullets.push({ id: Date.now() })
this.$nextTick(() => {
const bullet = this.$refs.bullets[this.$refs.bullets.length - 1]
const containerWidth = this.$refs.container.offsetWidth
gsap.fromTo(bullet,
{ x: 0, y: Math.random() * 300 },
{
x: containerWidth,
duration: 2,
onComplete: () => {
this.bullets.shift()
}
}
)
})
}, 500)
}
}
</script>
方法3:使用Canvas绘制
对于大量子弹效果,Canvas性能更好:
<template>
<canvas ref="canvas" width="800" height="400"></canvas>
</template>
<script>
export default {
data() {
return {
bullets: [],
ctx: null
}
},
mounted() {
this.ctx = this.$refs.canvas.getContext('2d')
setInterval(() => {
this.bullets.push({
x: 0,
y: Math.random() * 400,
speed: 2 + Math.random() * 3
})
}, 300)
requestAnimationFrame(this.animate)
},
methods: {
animate() {
this.ctx.clearRect(0, 0, 800, 400)
this.bullets.forEach((bullet, index) => {
bullet.x += bullet.speed
this.ctx.beginPath()
this.ctx.arc(bullet.x, bullet.y, 5, 0, Math.PI * 2)
this.ctx.fillStyle = 'red'
this.ctx.fill()
if(bullet.x > 800) {
this.bullets.splice(index, 1)
}
})
requestAnimationFrame(this.animate)
}
}
}
</script>
性能优化建议
- 对于少量子弹元素,使用CSS动画或GSAP更简单
- 对于大量子弹(50+),考虑使用Canvas或WebGL方案
- 使用对象池技术复用DOM元素或Canvas绘制对象
- 适当使用
requestAnimationFrame进行动画循环 - 在组件销毁时清除定时器和动画帧请求
以上方法可根据实际需求选择,CSS方案适合简单场景,GSAP提供更多动画控制,Canvas则适合高性能需求。







