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數據,就丟失了原有的很多信息。