Closed
Description
动画初探
最近要做动画有关的东西,看了两天动画有关的知识,零零散散的先记录下来。
业界动画引擎:
- PhysicsJS: 基于JavaScript、模块化、可扩展、易于使用的物理引擎,github
- animate.css: CSS3动画,github
- Matter.js: 基于canvas,兼容IE9+,github
- collie:基于Canvas,IE9+
FPS:
动画间隔决定了动画的每秒帧数(FPS),一般的,FPS越高,动画就表现得越流畅,FPS偏低,动画就会不流畅、卡顿。JQuery中,动画间隔默认为13ms,也就是说理想状态下,动画的每秒帧数是70(1000/13)多。
但是动画间隔并非越短就越流畅,因为浏览器需要渲染的时间,所以间隔一方面必须足够短,从而使不同的动画都能流畅的进行,别一方面还要足够长,使得浏览器可以完成渲染。没有找到官方的文档,网上的文章大多倾向于13ms。
参考:
requestAnimationFrame:
setInterval
和 setTimeout
的缺陷:
- 无论是setInterval()还是setTimeout()都无法达到精确,这个延迟即你指定的第二个参数仅仅表示何时代码会添加到浏览器的可能被执行的UI线程队列中。如果队列中有其他工作在此之前,那代码将会等到他完成才会执行。简而言之,毫秒级的延迟不是表示何时代码会执行,而是表示何时代码会添加进队列;
- 当相应的浏览器窗口最小化,JavaScript 计时器在背景标签仍然持续运行,消耗CPU和电池。
CSS transitions
和 animations
的优势在于浏览器知道哪些动画将会发生,所以得到正确的间隔来刷新UI。而javascript动画,浏览器不知道动画正在发生,所以催生了requestAnimationFrame,对于延迟做了很大程度的优化。
- 仅绘制用户可见的动画,这意味着在页面不可见时不会绘制动画,节省 CPU 和电池;
- 绘制动画不可能出现多个排队的回调函数,或者阻塞浏览器;
- 由于浏览器准备好时(空闲时)才绘制帧,不会有等待绘制的帧,没有多余的帧绘制,因此动画更平滑,CPU 和电池使用被进一步优化。
注意:在有多个动画时,出现一个可见一个不可见,requestAnimationFrame 会导致动画不同步,所以, 指定一个参数确保所有需要同步的动画状态,不受可见程度的影响(如一组动画从开始以来经过的时间),而不是根据每个动画的前一帧。
兼容各浏览器的 requestAnimationFrame
方法:RAF.js。
总结:
目前的动画库基本通过两种方式:css3
和 canvas
,css3难度相对小一些,但降级方案成本比较大,canvas
学习成本会高一些,具体的降级方案还有待研究。
在做之前,需要先确认好具体要支持哪些需求,别人怎么使用,然后再选择一个最优的方案。
Activity
imsobear commentedon Mar 20, 2014
关于动画的流畅度
先了解一个概念,FPS(帧率):描述每秒播放的帧数,单位为 Hz 或者 frame/s (帧/秒)。
一般来说,FPS越高,也就是每秒播放的帧数越多,动画会越流畅,但是,因为大部分的显示器刷新频率是 60Hz,当动画的FPS超过 60Hz 时,显示器会把两个或更多的帧显示在同一画面上,这样就会出现 画面撕裂,画面撕裂跟掉帧一个意思,所以通常来讲 FPS 为 60frame/s 时动画效果最好,也就是每帧16.67ms,在浏览器中要减去渲染时间1ms左右,得到的结果是每帧时间大概15ms。
但是我们可以在 jQuery 的源码中发现它的
interval
是13ms:jQuery.fx.interval = 13
, 按照上面的说法:1000 /(13+1.5)= 70 > 60hz,这样会出现画面撕裂,作为业界标准的 jQuery 显然是不会出现这种低级错误的,所以2ms的差别是怎么个意思?John Resig有一篇博客对13ms做了解释,文章链接见末尾。因为jQuery的动画是基于
setInterval
的,所以会存在一定的延迟:setTimeout(func, delay)
,这里是说在delay时间后将任务func
加入 UI 任务队列,而非立即执行该任务,所以这里会有一定的延迟;对于
setInterval
的问题,新的方法requestAnimationFrame
是很好的改进,具体可参见The secret to silky smooth JavaScript animation!这篇文章。参考链接: