效果展示
函数解释
MDN描述:window.requestAnimationFrame() 告诉浏览器你希望执行一个动画,并且要求浏览器在下次重绘之前调用指定的回调函数更新动画。该方法需要传入一个回调函数作为参数,该回调函数会在浏览器下一次重绘之前执行
创建和销毁
JavaScript
function animate() {
// 执行动画逻辑
timer = requestAnimationFrame(animate);
}
// 启动动画
let timer = requestAnimationFrame(animate);
//取消动画
cancelAnimationFrame(timer);
requestAnimationFrame 会把每一帧中的所有DOM操作集中起来,在一次重绘或回流中就完成,
并且重绘或回流的时间间隔紧紧跟随浏览器的刷新频率。充分利用了显示器的刷新机制,比较节省系统资源
(显示器有固定的刷新频率(60Hz或75Hz),也就是说,每秒最多只能重绘60次或75次)
requestAnimationFrame是一个全局函数。
调用requestAnimationFrame后,它会要求浏览器根据自己的频率进行一次重绘,
它会接收一个回调函数作为参数,在浏览器即将开始重绘时,会调用这个函数,
并会给这个函数传入调用回调函数时的时间作为参数。之后会反复不断地调用requestAnimationFrame,
以达到动画效果;
节省了CPU、GPU和电力,当页面处理未激活的状态下,该页面的屏幕刷新任务也会被系统暂停,因此跟着系统步伐走的requestAnimationFrame也会停止渲染,当页面被激活时,动画就从上次停留的地方继续执行,有效节省了CPU、GPU和电力开销
上方效果的完整代码
HTML
<style>
.SM_loadingBox {
display: flex;
justify-content: center;
align-items: center;
height: 5vh;
}
.SM_loadingBox .item {
width: 20px;
height: 20px;
background-color: rgb(24, 24, 24);
margin: 5px;
border-radius: 50%;
transition: all .5s;
}
.item.on {
animation-name: on;
animation-duration: .5s;
animation-fill-mode: forwards;
background-color: burlywood;
}
@keyframes on {
0% {
width: 20px;
height: 20px;
}
50% {
width: 25px;
height: 35px;
}
100% {
width: 20px;
height: 20px;
}
}
</style>
</head>
<div class="SM_loadingBox">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
<script>
const loading = document.querySelectorAll('.SM_loadingBox .item')
let index = 0
let timer = null
function changeLoadingMov(timestamp) {
if (!changeLoadingMov.startTime) {
changeLoadingMov.startTime = timestamp;
}
const progress = timestamp - changeLoadingMov.startTime;
if (progress > 500) {
loading[index % loading.length].classList.add('on');
index++;
changeLoadingMov.startTime = timestamp;
}
if (index < loading.length) {
timer = requestAnimationFrame(changeLoadingMov);
} else {
setTimeout(() => {
loading.forEach(item => item.classList.remove('on'));
cancelAnimationFrame(timer)
setTimeout(() => {
index = 0;
timer = requestAnimationFrame(changeLoadingMov);
}, 500);
}, 500);
}
}
timer = requestAnimationFrame(changeLoadingMov);
</script>
路人经过,看起来挺有意思的