setTimeout
需手动控制频率,页面隐藏后仍会执行动画,更加耗费性能。
requestAnimationFrame
简称 RAF , 会在浏览器中每次刷新屏幕时调用一个函数,用于创建平滑的动画,因为它会自动适应屏幕的刷新率,无需手动控制频率。在页面隐藏时,自动暂停动画。
RAF动画 vs CSS动画
requestAnimationFrame通常用于需要高度控制动画的场景,例如游戏或者复杂的数据可视化。而CSS动画则更多用于简单的静态或者中等复杂度的动画设计。在性能上,当不需要高度控制或者频繁更新视图时,使用CSS动画是更好的选择,因为浏览器可以进行更多的优化。而requestAnimationFrame则更适合于需要实时更新视图的场景。
效果预览
演示代码
<template>
<div>
<div class="demoBox" :style="{ width: width + 'px' }"></div>
<button @click="setTimeout_animate">使用 setTimeout 执行动画</button>
<button @click="ref_animate">使用 ref 执行动画</button>
</div>
</template>
<script>
export default {
data() {
return {
width: 20,
maxWidth: 620,
};
},
mounted() {
// 4s 把宽度从 20px 变为 620px ,即增加 600px,每次需变化 600 px / (60帧/秒 *4秒) = 15px/帧
// 60帧/s 才能确保动画流畅, 即每 1000/60 = 16.7 ms 执行一次动画
// 得出最终动画效果为 每 16.7 ms , 宽度增加15px
// this.setTimeout_animate();
},
methods: {
setTimeout_animate() {
if (this.width < this.maxWidth) {
setTimeout(this.setTimeout_animate, 16.7); // 时间需要自己控制
this.width += 15;
} else {
this.width = 20;
}
},
ref_animate() {
if (this.width < this.maxWidth) {
requestAnimationFrame(this.ref_animate); // 时间不用自己控制
this.width += 15;
} else {
this.width = 20;
}
},
},
};
</script>
<style scoped>
.demoBox {
height: 30px;
background-color: red;
margin: 20px;
}
</style>