更好的浏览器动画实现 requestAnimationFrame

时间:2023-04-25 15:07:13

requestAnimationFrame 是专门为实现高性能的帧动画而设计的一个API:

  js一般是借助setTimeout或setInterval这两个函数实现动画,性能不佳。

  css3动画,性能和流畅度得到了很大的提升。但是css3动画还是有不少局限性,比如不是所有属性都能参与动画、动画缓动效果太少、无法完全控制动画过程等等。

requestAnimationFrame 比起 setTimeout、setInterval的优势主要有两点:

1、requestAnimationFrame 会把每一帧中的所有DOM操作集中起来,在一次重绘或回流中就完成,并且重绘或回流的时间间隔紧紧跟随浏览器的刷新频率,一般来说,这个频率为每秒60帧。

2、在隐藏或不可见的元素中,requestAnimationFrame将不会进行重绘或回流,这当然就意味着更少的的cpu,gpu和内存使用量。

下面是一些缓动函数requestAnimationFrame 的一些基础知识:

各个浏览器之间的兼容:

window.requestAnimFrame = ( function() {
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
function( callback ) {
window.setTimeout( callback, / );
};
})();

动画的逻辑:

记录当前时间startTime,作为动画开始的时间。 
请求下一帧,带上回调函数。 
下一帧触发时,回调函数的第一个参数为当前的时间,再与startTime进行比较,确定时间间隔ellapseTime。 
判断ellapseTime是否已经超过事先设定的动画时间time,如果超过,则结束动画。 
计算动画属性变化的差值differ = to - from,再确定在ellapseTime的时候应该变化多少step = differ / time * ellapseTime。 
计算出现在应该变化到的位置Math.round(from + step),并重新对样式赋值。 
继续请求下一帧。

动画函数:

function animate(element, name, from, to, time) {
time = time || 800; // 默认0.8秒
var style = element.style,
startTime = new Date;
function go(timestamp) {
var progress = timestamp - startTime;
if (progress >= duration) {
style[name] = to + 'px';
return;
}
var now = (to - from) * (progress / duration);
style[name] = now.toFixed() + 'px';
requestAnimationFrame(go);
}
style[name] = from + 'px';
requestAnimationFrame(go);
}

参考:http://www.jb51.net/article/32497.htm