MojoJS-Animation是一个简洁、高效、强大的开源JS动画引擎(Github),其功能和实现有如下特点:
- 支持CSS Style和Transform动画。
- 支持队列和并发动画。
- 支持多个元素的组动画。
- 支持动画延迟执行。
- 支持组动画完成的事件回调(不是单个元素完成回调)。
- 支持可配置的动画链式调用。
- 支持标准和自定义的Tween缓动算法。
首先,看两个直观的实现效果,第一个是Transform,第二个是CSS Style。更多在线示例和代码展示,见这里:Online Demo。


其次,代码实现结构,如下:

由上图,可以从宏观整体,看清动画框架的实现逻辑。
- 全局动画执行器,循环更新Animation数组。
- 每个Animation包含:队列Actions,并发Actions,回调Actions,及Elements。
- 队列Actions每次Pop出一个Action,进入并发Action,并发Actions实时执行,完成后执行回调Actions。(运行时,API可以动态添加Action,到队列Actions、并发Actions、回调Actions)
- 每个并发Action都可以设置延迟执行时间,并驱动Animation所包含的Elements完成Tween缓动动画。(Action会生成多个副本,与Element一一对应)
- 每个Element执行Action,使用Tween Easing函数驱动Style、Color、Transform的属性变化。
- Action每一帧的变化量,会拼接成cssText字符串,并更新到Element。
- 完成Action后,执行回调函数。(由于同一个Action模板,会应用到所有Elements,所以Action完成只会统一回调一个事件在所有Elements上)
最后,重要的是MojoJS-Animation的这个动画框架,虽然是用JS实现的,但它的内核其实是一个通用的实现模式,可以用任意编程语言去实现。
例如,C语言的Tween动画框架实现:Tween.h,Tween.c。
结语
MojoJS-Animation最初的算法实现,完成于2010并开源,后来又陆续用C和C#进行了实现,其核心的框架结构和思路都没有变化,只有API层面的调整。
从实践中,可以发现这一套Tween缓动的实现模式,不仅可以满足日常的UI动画需求,还非常的稳定和高效,也具有高度的可定制扩展性。
不过,在最初JS的实现中,是没有Transform和requestAnimationFrame的,于是最近找时间把这个JS库更新了一个大版本加入了这两个特性,并进行了诸多的优化(主要是代码结构上的抽象清晰度),修复了一些细节上的bug(主要是单位转换上的)。
另外,值得一说的就是——可配置的动画链式调用——这个特性。
实际中,我们经常需要在某个Action完成之后,进行另外的Action操作,并且对于复杂的动画序列,一个队列Action是无法胜任的,于是我们就会在回调函数里进行操作,而这会有两个问题,第一大部分动画库的回调都是在元素上(不是针对Action回调),第二回调函数破坏了链式调用的统一性与阅读性,写多了也不方便。
那么,可配置的动画链式调用——就是把回调函数的嵌套结构,变成了平行结构。如下示例:
MojoJS.createAnimation("#target").animate({left: 0, top: 0}, 1000, {id : "reset"})// id为reset的action,完成后回调.animate({left: 500 }, 1000, {appendTo: "reset"})
最后,不得不说的感受,就是加入Transform的实现,着实让人有些伤脑筋,有很多的取舍和纠结,没有一个完美的方案——尤其是相对运动,如何对Matrix数据的提取,Native API并没有“尽责”,因为Transform信息一旦合并成Matrix数据,就丢失了原有的很多信息。