requestAnimationFrame

requestAnimationFrame

在Web应用中,实现动画效果的方法比较多,Javascript 中可以通过定时器 setTimeout/ setInterval 来实现,css3 可以使用 transition和 animation 来实现,html5 中的 canvas 也可以实现。除此之外,html5 还提供一个专门用于请求动画的API,那就是 requestAnimationFrame。

什么是 raf

requestAnimationFrame是浏览器⽤于定时循环操作的⼀个接口,类似于setTimeout,主要⽤途是按帧对网页进行重绘,让各种网页动
画效果(DOM动画、Canvas动画、SVG动画、WebGL动画)能够有⼀个统⼀的刷新机制,从而节省系统资源,提高系统性能,改善视觉效果。

为什么需要 raf

setTimeout/ setInterval 的两个问题:

  1. 时间不准

它们只是在设定的时间后将相应任务添加到任务队列中,并不是执行任务的时间。

  1. 和屏幕刷新率步调不一致

可能会掉帧

image-20220609201544048

requestAnimationFrame的到来就是解决这个问题的 ,它采用的是系统时间间隔(约16.7ms),保持最佳绘制效果与效率,使各种网页动画有一个统一的刷新机制,从而节省系统资源提高系统性能

raf 的优缺点

  1. cpu节能

使用setInterval实现的动画,当页面被隐藏或最小化时,setInterval仍然在后台执行动画任务。requestAnimationFrame在页面未激活时,该页面的屏幕刷新任务也会被系统暂停。当页面被激活时,任务会从上次停留的地方继续执行,有效节省了CPU开销。

  1. 流畅

不掉帧、不卡帧

缺点是兼容性问题

raf 的使用

简单使用

1
2
3
4
5
6
7
8
9
10
11
let myReq;
let i = 0;
function step(timestamp) {
console.log(i++);
myReq = window.requestAnimationFrame(step);
}
window.requestAnimationFrame(step);

document.onclick = function(){
window.cancelAnimationFrame(myReq); // 专属清除方式
}

封装:自定义秒数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
function animate(cb,time){
let myReq; // 记录requestAnimationFrame的返回值
let i = 1; // 记录requestAnimationFrame的执行次数(屏幕刷新次数)
myReq = requestAnimationFrame(function fn(){ // 开启初始requestAnimationFrame
// 计数器 % (60/一秒钟执行的次数)
if(i%parseInt(60/(1000/time)) == 0){
cb(); // 执行真正要做的事情
}
i++; // 记录requestAnimationFrame执行的次数
myReq = requestAnimationFrame(fn); // 开启下次requestAnimationFrame
window.myReq = myReq; // 将requestAnimationFrame返回值暴露,方便清除
});
}

// 测试
animate(function(){
console.log("自己封装了个计时器,好厉害呀");
}, 1000); // 自定义执行时间
document.onclick = function(){
// 主动控制清除动画
cancelAnimationFrame(myReq);
}

requestAnimationFrame
http://example.com/2023/02/01/requestAnimationFrame/
Author
John Doe
Posted on
February 1, 2023
Licensed under