JavaScript动画
早期的JS动画
早期的JS循环动画主要是通过setInterval/setTimeout实现的
function jump() { console.log("我跳了一下"); } (function() { function updataAniamtion() { jump(); } setInterval(updataAniamtion, 17); })();
大多数显示器的刷新率为60HZ,因此最佳循环间隔约17ms,使用setInterval可以实现很平滑流畅的动画。
setInterval/setTimeout动画的缺陷
但是由于JS执行机制中,setInterval属于异步任务,实际上是每隔xx毫秒就将参数当中的函数添加到UI线程队列当中,然后等待当前event-Loop中同步任务执行完毕后才开始执行异步任务,这意味着,假如有一个for循环需要执行很久,那么即使你setInterval或者setTimeout当中的延时为0,依然不是马上执行。
setTimeout(function() { console.log("我是延时0的异步事件"); }, 0);for( let i = 0; i < 1000000000; i++) { continue; }
你可以将以上代码复制到你的代码编辑器当中,然后保存刷新,你会发现setTimeout当中的函数并不是马上执行,而是稍微停顿了一下才执行,如果你将for循环的i数值再增大3倍,那么将会更加明显的看出来。这就造成了setInterval动画的缺陷:不精确
想更加详细的了解JS执行机制的可以下面的第二篇参考。
requestAnimationFrame方法
该方法接收一个回调函数作为参数,告诉浏览器在下一次重绘之前调用该回调函数来执行动画,回调的次数通常是每秒60次,也就是大约时间间隔16.7ms,当然这个次数不绝对,准确说是根据浏览器的绘制间隔调整。该函数接收一个时间戳。
var element = document.getElementById('box'); element.style.position = 'absolute';function moveRight(timestamp) { // 根据时间戳改变样式 element.style.left = Math.min(timestamp / 10, 300) + 'px'; // 时间戳大于2000ms的时候停止 if (timestamp < 2000) { window.requestAnimationFrame(moveRight); } }// 调用window.requestAnimationFrame(moveRight);
假设html当中已经有一个ID为box的盒子,如以上的代码,这个盒子会做向右移动的动画,这里的时间戳可以理解为,第一次启动的时候开始一个计时器,然后通过计时器来进行动画,也就是基于时间戳的动画。
有了CSS3还需要JS动画吗?
需要,虽然CSS的animation以及transition非常强大,但是仍然有不足之处,而requestAnimationFrame可以解决这些问题。
统一的向下兼容策略
有一些效果CSS3实现兼容性差,例如淡入淡出,而requestAnimationFrame则方便许多,使用方法都是单回调的方式,同setTimeout相同属性兼容
对于CSS而言有些属性是不兼容的,而使用requestAnimationFrame可以,例如scrollTop配合缓动可以实现很复杂的动画效果
参考
JavaScript高级程序设计3-第25章
原文出处:http://www.cnblogs.com/souldee/p/9378754.html
共同学习,写下你的评论
评论加载中...
作者其他优质文章