vue实现子弹循环
Vue 实现子弹循环动画
在 Vue 中实现子弹循环动画可以通过 CSS 动画或 JavaScript 动态控制实现。以下是两种常见方法:
方法一:CSS 动画结合 Vue 动态样式
通过 Vue 绑定样式,利用 CSS 的 @keyframes 实现子弹移动效果。

<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: Array(5).fill().map(() => ({
x: Math.random() * 300,
y: Math.random() * 300
}))
};
},
mounted() {
setInterval(() => {
this.bullets = this.bullets.map(bullet => ({
x: (bullet.x + 5) % window.innerWidth,
y: bullet.y
}));
}, 50);
}
};
</script>
<style>
.bullet {
position: absolute;
width: 10px;
height: 10px;
background-color: red;
border-radius: 50%;
transition: transform 0.1s linear;
}
</style>
方法二:使用 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: Array(5).fill().map(() => ({
x: Math.random() * 300,
y: Math.random() * 300
}))
};
},
mounted() {
this.$nextTick(() => {
this.$refs.bullets.forEach((bullet, index) => {
gsap.to(bullet, {
x: window.innerWidth,
duration: 2,
repeat: -1,
yoyo: true,
ease: "none"
});
});
});
}
};
</script>
<style>
.bullet {
position: absolute;
width: 10px;
height: 10px;
background-color: blue;
border-radius: 50%;
}
</style>
性能优化建议
对于大量子弹实例,考虑使用 CSS transform 而非直接修改 top/left 属性,因为前者会触发硬件加速。
.bullet {
transform: translate3d(var(--x), var(--y), 0);
will-change: transform;
}
实现无限循环的技巧
通过监听子弹移出视口边界时重置位置,可以创建无缝循环效果:
updateBullets() {
this.bullets = this.bullets.map(bullet => {
const newX = bullet.x + 5;
return {
x: newX > window.innerWidth ? 0 : newX,
y: bullet.y
};
});
requestAnimationFrame(this.updateBullets);
}
响应式适配
添加窗口大小变化的监听,动态调整子弹初始位置:
created() {
window.addEventListener('resize', this.initBullets);
},
beforeDestroy() {
window.removeEventListener('resize', this.initBullets);
},
methods: {
initBullets() {
this.bullets = Array(5).fill().map(() => ({
x: Math.random() * window.innerWidth,
y: Math.random() * window.innerHeight
}));
}
}






