目录
requestAnimationFrame是浏览器用于定时循环操作的一个接口,类似于setTimeout,主要用途是按帧对网页进行重绘,让各种网页动画效果(DOM动画、Canvas动画、SVG动画、WebGL动画)能够有一个统一的刷新机制,从而节省系统资源,提高系统性能,改善视觉效果。
在运行过程中,window.requestAnimationFrame() 告诉浏览器——你希望执行一个动画,并且要求浏览器在下次重绘之前调用指定的回调函数更新动画。该方法需要传入一个回调函数作为参数,该回调函数会在浏览器下一次重绘之前执行
注意:若你想在浏览器下次重绘之前继续更新下一帧动画,那么回调函数自身必须再次调用window.requestAnimationFrame()
2、设置这个API的目的是什么?
用js来实现动画,一般是用setTimeout或setInterval这两个函数。css3动画出来后,实现动画的方式又多了一种选择,而且性能和流畅度也得到了很大的提升。
但是css3动画还是有不少局限性,比如不是所有属性都能参与动画、动画缓动效果太少、无法完全控制动画过程等等。但是setTimeout和setInterval有着严重的性能问题,就算现代浏览器对其极力优化,但还是无法跟css3的动画性能相提并论。
有需求就会有市场,有痛点就会有想要去解决
requestAnimationFrame 是一个专门为实现高性能的帧动画而设计的API,目前不管是移动端还是桌面端,新版本的浏览器都已经支持了这个API。
3、requestAnimationFrame的优缺点
(相对于setTimeout、setInterval)
4、requestAnimationFrame的使用
window.requestAnimationFrame(callback);
参数:callback
下一次重绘之前更新动画帧所调用的函数(即上面所说的回调函数)。该回调函数会被传入DOMHighResTimeStamp参数,该参数与performance.now()的返回值相同,它表示requestAnimationFrame() 开始去执行回调函数的时刻。
返回值:
一个 long 整数,请求 ID ,是回调列表中唯一的标识。是个非零值,没别的意义。你可以传这个值给 window.cancelAnimationFrame() 以取消回调函数。
var start = null;var element = document.getElementById('SomeElementYouWantToAnimate');
element.style.position = 'absolute';
function step(timestamp) {
if (!start) start = timestamp;
var progress = timestamp - start;
element.style.left = Math.min(progress / 10, 200) + 'px';
if (progress < 2000) {
window.requestAnimationFrame(step);
}}
window.requestAnimationFrame(step);
(范例来源于MDN web docs)
setTimeout 是通过设置一个间隔时间来不断的改变图像的位置,从而达到动画效果的。但是利用seTimeout实现的动画在某些低端机上会出现卡顿、抖动的现象。
那为什么会出现卡顿呢
以上两种情况都会导致setTimeout的执行步调和屏幕的刷新率不一致,从而出现掉帧现象。
那为什么步调不一致就会引起丢帧呢?
首先要明白,setTimeout的执行只是在内存中对图像属性进行改变,这个变化必须要等到屏幕下次刷新时才会被更新到屏幕上。如果两者的步调不一致,就可能会导致中间某一帧的操作被跨越过去,而直接更新下一帧的图像。
举个栗子:
假设屏幕每隔16.7ms刷新一次,而setTimeout每隔10ms设置图像向左移动1px, 就会出现如下绘制过程:
从上面的绘制过程中可以看出,屏幕没有更新left=2px的那一帧画面,图像直接从1px的位置跳到了3px的的位置,这就是丢帧现象,这种现象就会引起动画卡顿。
(setTimeout解释大部分来源于百度,经过作者略微修改,仅供参考)
{{ cmt.username }}
{{ cmt.content }}
{{ cmt.commentDate | formatDate('YYYY.MM.DD hh:mm') }}