以往JS掌握的动画大多运用setInterval
或许setTimeout
每隔一段时候革新元素的位置,来到达动画的结果,然则这类体式格局并不能正确地掌握动画帧率,只管主流的浏览器关于这两个函数完成的动画都有肯定的优化,然则这依旧没法弥补它们机能题目。主要原因是因为JavaScript的单线程机制使得其能够在有壅塞的情况下没法准确到毫秒触发。
requestAnimationFrame()
要领恰是为了满足高机能动画的需求而供应的API,经由过程setInterval
要领掌握的动画其挪用的间隔由程序员设置,而requestAnimationFrame()
不必设置挪用间隔, 它自动紧跟浏览器的绘制的帧率(平常浏览器的显现帧率是60fps,差不多每帧间隔16.7ms)
关于过去的setInterval
掌握的动画与requestAnimationFrame()
的结果的对照,这里援用‘艾伦’的帖子中的栗子。原帖地点?动画requestAnimationFrame
setInterval动画DEMO
requestAnimationFrame动画DEMO
点击预览以上两个demo能够显著感受到前者有点卡顿,后者更加流通。
别的requestAnimationFrame()
在隐蔽或不可见的元素中将不会举行重绘或回流,大大降低了开支。关于该要领的其他细节见MDN文档? window.requestAnimationFrame
以上都是空话,多写才体味。这里我尝试用该要领写了个晃悠动画(点击黑盒晃悠,个人演习并没有斟酌兼容性):
JS代码:
//从网页中猎取一个元素
var box = document.getElementById('box')
shake(box, 500, 15)
//接收三个参数:动画元素,持续时候,晃悠间隔
function shake(elm, dur, distance) {
if (elm) {
var dur = dur || 500
var distance = distance || 10
//保留原款式
var original_css = elm.style.cssText
elm.addEventListener('click', ani, false)
} else {
return 'no param'
}
function ani() {
var start = null
requestAnimationFrame(act)
//requestAnimationFrame每次挪用向callback中传入一个时候戳,时候戳为每次挪用的时候点
function act(time_stamp) {
if(start === null) start = time_stamp
var elapsed = time_stamp - start
if ((elapsed / dur) < 1) {
//乘以4PI,往返来去两次, 运用正弦函数获得比例
elm.style.transform = 'translateX(' + distance * Math.sin((elapsed / dur) * 4 * Math.PI) + 'px' + ')'
//挪用该要领将返回一个ID值用于完毕挪用
var time_id = requestAnimationFrame(act)
} else {
//恢复原款式,住手动画
elm.style.cssText = original_css
cancelAnimationFrame(time_id)
}
}
}
}
在现实开辟中, 固然只管运用css动画, 毕竟css动画机能更优。然则关于一些庞杂的动画,比方有停息,继承等庞杂交互等动画照样须要requestAnimationFrame
,在张鑫旭大神的这篇文章中CSS3动画那末强,requestAnimationFrame另有毛线用? 深入浅出的阐释了该要领, 别的他的demo中也有一个很直观的栗子?
该要领其他参考资料mark下:
机能更好的js动画完成体式格局——requestAnimationFrame
HTML5探秘:用requestAnimationFrame优化Web动画