requestAnimationFrame

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

setTimeout/ setInterval 的显著缺陷就是设定的时间并不精确,它们只是在设定的时间后将相应任务添加到任务队列中,而任务队列中如果还有前面的任务尚未执行完毕,那么后添加的任务就必须等待,这个等待的时间造成了原本设定的动画时间间隔不准requestAnimationFrame的到来就是解决这个问题的 ,它采用的是系统时间间隔(约16.7ms),保持最佳绘制效果与效率,使各种网页动画有一个统一的刷新机制,从而节省系统资源,提高系统性能。


如下是MDN文档requestAnimationFrame的解释

window.requestAnimationFrame() 告诉浏览器——你希望执行一个动画,并且要求浏览器在下次重绘之前调用指定的回调函数更新动画

从中可知,该方法需要传入一个回调函数作为参数,且回调函数会在页面被刷新时前调用

语法如下:

window.requestAnimationFrame(callback);
  • callback下一次重绘之前更新动画帧所调用的函数(即上面所说的回调函数)。回调函数会被传入DOMHighResTimeStamp参数(时间戳,十进制数,单位是毫秒,最小精度为1ms),DOMHighResTimeStamp指示当前被 requestAnimationFrame()排序的回调函数被触发的时间。
  • 返回值:是个非零值( long 整数),请求 ID ,是回调列表中唯一的标识。可以传这个值给 window.cancelAnimationFrame() 以取消回调函数。

注意:若你想在浏览器下次重绘之前继续更新下一帧动画,那么回调函数自身必须再次调用window.requestAnimationFrame()

举个例子

var s = 0
function f(DOMHighResTimeStamp) {
  s++
  console.log(s);
  console.log(DOMHighResTimeStamp);
  if (s < 99) {
    window.requestAnimationFrame(f)
  }
}
window.requestAnimationFrame(f)

控制台不断输出s直到99。
在这里插入图片描述
接下来,我们实现一个进度条

<body>
    <div style="width: 0px;height:12px;line-height: 12px;background: pink;">
    0%</div>
    <script>
        var div=document.querySelector('div')
        div.onclick=function(){
            var timer=requestAnimationFrame(function fn(){
                if(parseInt(div.style.width)<300){
                    div.style.width=parseInt(div.style.width)+3+'px';
                    div.innerHTML=parseInt(div.style.width)/3+'%'
                    timer=requestAnimationFrame(fn)
                }else{
                    cancelAnimationFrame(timer)
                }
            })
                
        }
           
    </script>
</body>

点击后,进度条逐渐变成100%
在这里插入图片描述

Logo

分享最新的 NVIDIA AI Software 资源以及活动/会议信息,精选收录AI相关技术内容,欢迎大家加入社区并参与讨论。

更多推荐