vue怎么实现帧动画
Vue 中实现帧动画的方法
使用 CSS 动画和 v-for 动态渲染帧
通过 CSS 定义关键帧动画,结合 Vue 的 v-for 动态渲染每一帧图片。这种方法适合序列帧图片已预先加载的情况。

<template>
<div class="frame-container">
<img
v-for="(frame, index) in frames"
:key="index"
:src="frame"
:class="{ 'active': currentFrame === index }"
/>
</div>
</template>
<script>
export default {
data() {
return {
frames: [
'frame1.png',
'frame2.png',
// 添加更多帧...
],
currentFrame: 0,
interval: null
};
},
mounted() {
this.interval = setInterval(() => {
this.currentFrame = (this.currentFrame + 1) % this.frames.length;
}, 100); // 每 100ms 切换一帧
},
beforeDestroy() {
clearInterval(this.interval);
}
};
</script>
<style>
.frame-container img {
position: absolute;
opacity: 0;
transition: opacity 0.1s;
}
.frame-container img.active {
opacity: 1;
}
</style>
使用 Canvas 逐帧绘制
通过 Canvas API 动态绘制每一帧,适合需要高性能或复杂动画的场景。

<template>
<canvas ref="canvas" width="300" height="300"></canvas>
</template>
<script>
export default {
data() {
return {
frames: [],
currentFrame: 0,
interval: null
};
},
async mounted() {
await this.loadFrames();
this.animate();
},
methods: {
async loadFrames() {
// 假设通过异步加载帧图片
this.frames = await Promise.all([
this.loadImage('frame1.png'),
this.loadImage('frame2.png'),
// 加载更多帧...
]);
},
loadImage(src) {
return new Promise((resolve) => {
const img = new Image();
img.onload = () => resolve(img);
img.src = src;
});
},
animate() {
const ctx = this.$refs.canvas.getContext('2d');
this.interval = setInterval(() => {
ctx.clearRect(0, 0, 300, 300);
ctx.drawImage(this.frames[this.currentFrame], 0, 0);
this.currentFrame = (this.currentFrame + 1) % this.frames.length;
}, 100);
}
},
beforeDestroy() {
clearInterval(this.interval);
}
};
</script>
使用第三方库(如 GSAP)
GSAP 提供强大的动画控制能力,适合复杂动画序列或需要精细控制的场景。
<template>
<div ref="sprite" class="sprite"></div>
</template>
<script>
import { gsap } from 'gsap';
export default {
mounted() {
const frames = [
{ backgroundImage: 'url(frame1.png)' },
{ backgroundImage: 'url(frame2.png)' },
// 更多帧...
];
gsap.to(this.$refs.sprite, {
keyframes: frames,
duration: 1,
repeat: -1,
ease: 'steps(1)'
});
}
};
</script>
<style>
.sprite {
width: 100px;
height: 100px;
background-size: contain;
}
</style>
使用 CSS steps() 函数
通过 CSS 的 steps() 函数实现精灵图动画,适合将多帧合并为一张雪碧图的情况。
<template>
<div class="sprite" :style="{ backgroundPositionX: `${-currentFrame * 100}px` }"></div>
</template>
<script>
export default {
data() {
return {
currentFrame: 0,
totalFrames: 10,
interval: null
};
},
mounted() {
this.interval = setInterval(() => {
this.currentFrame = (this.currentFrame + 1) % this.totalFrames;
}, 100);
},
beforeDestroy() {
clearInterval(this.interval);
}
};
</script>
<style>
.sprite {
width: 100px;
height: 100px;
background-image: url('sprite.png');
background-repeat: no-repeat;
animation: play 1s steps(10) infinite;
}
@keyframes play {
from { background-position-x: 0; }
to { background-position-x: -1000px; }
}
</style>
注意事项
- 性能优化:大量帧动画可能消耗内存,建议使用 Canvas 或雪碧图减少 DOM 操作。
- 预加载资源:确保所有帧图片加载完成后再开始动画,避免闪烁。
- 响应式设计:通过计算属性动态调整帧速率或尺寸以适应不同设备。
- 清理资源:组件销毁时清除定时器或动画实例,防止内存泄漏。






