requestAnimationFrame 请求动画帧 一定懂

2019-10-19  本文已影响0人  5e3a27a51fcd

requestAnimationFrame

在网页开发中实现动画实现动画的方式有下面几种。css中的 transition 和 animation。js中通过计时setInterval来触发动画。requestAnimationFrame是H5提供一个专门用于请求动画的API。

requestAnimationFrame的特性

系统来决定回调函数的执行时间。如果屏幕刷新率是60Hz(每秒60次的频率刷新),那么回调函数就每1000/60=16.7ms被执行一次,如果刷新率是75Hz,那么这个时间间隔就变成了1000/75=13.3ms,requestAnimationFrame的执行时间跟着系统的刷新刷新走。它能保证回调函数在屏幕每一次的刷新间隔中只被执行一次,这样就不会引起丢帧现象,也不会导致动画出现卡顿的问题。

setInterval的动画存在的问题

setInterval是通过定时,在一定时间间隔后,通过改变属性来达到动画的目的,而位置的变化必须要等到屏幕下次刷新时才会被更新到屏幕上,所以setInterval实现的动画可能会出现卡顿、抖动的现象,这是因为动画执行的时间不确定(任务队列,假设设定的时间是10ms,但是10ms后不一定会运行),还有就是屏幕的刷新频率不一样。如下面代码(假设60HZ,10毫秒后,动画一定执行):


var move= document.getElementById('test');

    var t=1;

    setInterval(() => {

    t=t+10;

    move.style.marginLeft=t+'px';

}, 10);

0ms: marginLeft 0

10ms marginLeft 1 (但是屏幕上位置并没有变化,因为屏幕没有刷新)

16.7ms: marginLeft 1(屏幕上的位置变化)

20ms: marginLeft 2 (但是屏幕上位置并没有变化,因为屏幕没有刷新)

30ms: marginLeft 3 (但是屏幕上位置并没有变化,因为屏幕没有刷新)

33.3ms: marginLeft 3 (屏幕上的位置变化)

但是我们可以看到屏幕上的位置是从1变化到了3,跳帧了。

requestAnimationFrame的实现


var progress=0;

function render() {

    progress += 1;

    window.requestAnimationFrame(render);

    moveTwo.style.marginLeft=progress+'px';

}

window.requestAnimationFrame(render);

比较效果图

image

requestAnimationFrame其余优势:

CPU节:requestAnimationFrame在页面处理未激活的状态下,该页面的屏幕刷新任务也会被系统暂停,因此跟着系统步伐走的requestAnimationFrame也会停止渲染,当页面被激活时,动画就从上次停留的地方继续执行,有效节省了CPU开销。

函数节流:在高频率事件中,使用requestAnimationFrame可保证每个刷新间隔内,函数只被执行一次,这样既能保证流畅性,也能更好的节省函数执行的开销。

上一篇下一篇

猜你喜欢

热点阅读