號外:kitjs官方討論QQ群建立了,QQ群號88093625,歡迎大家加入,討論前端相關話題
上一篇介紹了$Kit.Anim這個類的基本接口和特點以及用法,這一篇,我們深入代碼來了解了解$kit.anim是如何實現Css全屬性支持,Css Hack等等的
(一)一切緣起setInterval
每一個成功男人背后都有一個女人,對於使用javascript實現動畫來說,setInterval這個基本的定時器就是那個“女人”了,哈哈。基本上我研究過的動畫框架都是基於setInterval實現的,當然也有一些怪胎,是用setTimeout實現的,極少極少。
一般來說使用setInterval用javascript動畫的好處
1. 時間片固定,setTimeout的延時時間會受到setTimeout內的代碼執行時間的影響,而setInterval不會
2. (定點觸發,不用擔心被阻塞,setInterval到時間,就會自動跳到setInterval方法體開始,從頭執行,無論之前js引擎執行到哪一段代碼 X 這句話是錯的,)
正確是,setInterval不計算方法體的時間,直接計算間隔時間,並將方法體放入執行隊列,而setTimeout做重復調用要算上方法體的時間+間隔時間,無論是setTimeout還是setInterval都是在參數指定的時間后將待執行方法放到執行隊列中,因為javascript是單線程的,沒有goto
所以kitjs也不例外的使用了setInterval用了基本的動畫引擎
對於每個一個setInterval定義后,都會返回一個timeout的id,這是一個數字,與當前頁面有關,切唯一,我們可以通過clearInterval的方式終止這個定時器,也就是終止了動畫。
(二)依然是通過對象作為參數
anim類的motion方法,接受的參數為一個json對象,使用json對象的好處,
1. 是方便擴充更多的方法和屬性
2. 是如果參數過多,需要記住輸入順序很麻煩,使用json對象做配置,則沒有這么麻煩。
(三)config.el是不是單個節點,而是一個selector
是的,當初考慮的時候,我的理解是對於一個動畫來說,運動元素不應該僅僅是一個元素,比如說我們要做一個四面八方聚攏的效果,有個N個元素集中在一個固定點。如果用jQ的話,會創建N個interval,個人覺得不是很必要。因為對於這個動畫的開發狀態,就是被動畫元素的初始位置,完全可以通過Js獲取他當前的Css屬性獲得,而我們只需要設置下終點坐標即可。所以我在設計kitjs Animation的時候,將config.el屬性設置接收一個selector,或者nodeList,可以說是為了節省性能相關,也讓代碼更加簡潔。
通過代碼可以看到,config.el會將接收到的selector變成一個node數組
(四)根據from重置初始狀態
作為一個動畫來說,可能初始狀態是他現在的狀態,也可能初始狀態不是他現在的狀態,所以我們需要根據傳入的config.from屬性重置狀態
(五)from為一個Css的json
為了方便設置狀態,這里直接使用json的方式,寫Css,更加方便,更加明了
(六)Css的json支持Css Hack
其實秘密在這里,上上漲圖片,我們可以看到他調用一個me.setStyle的方法,這里的me是this指針的別名。
而在setStyle方法里面,他會去調用$kit.css方法,
而kit是通過IE條件注釋的方法,實現iefix的
在ieFix的$kit.css方法里面,他要做一個_camelCssName的工作
秘密就在_camelCssName里面
同理在kit.js里面也有個處理firefox Css Hack的邏輯
(七)Fx動畫漸變計算
通過累計已經發生動畫的時間,加上動畫持續時間,開始狀態值,結束狀態值,帶入動畫參數計算,獲取當前狀態值,
$kit.anim也提供很多動畫函數,上一篇已有介紹
(八)實現rgba顏色通道漸變計算
因為對於rgba,rgb或者#xxxxx,這樣的顏色數值漸變,不能按照轉化為10進制,再單一數字Fx計算,他的漸變必須是r,g,b三個通道一起漸變,就是要計算三次。
kitjs使用正則分析form和to的Css json,判斷出是否是顏色數值,而走專門的處理方法
專門的rgb計算,和非rgb直接一步計算漸變數字
(九)拆分判斷Css屬性,哪些是具體漸變值,哪些是單位,這也是識別Css3 屬性的關鍵
這里kitjs用的技巧是使用正則匹配,分組合並的方式
使用以上的方法,可以將一段Css String,拆分成為多個獨立的小段 ,然后每一段對於value值做漸變計算,再合並成為一個Css String,這種方式對於Css3的transform特別有效,特別是那種多段的Css屬性,目前市面上也只有kitjs是這么實現了,別的框架基本都不支持。
(十)動畫鏈
當動畫進行時間超過持續時間時,kitjs注銷了這個動畫的interval的id,同時,將動畫元素重置到config.to參數的Css狀態,如果注冊了config.then參數,則繼續執行config.then參數,通過demo給出的例子,完成一個動畫鏈條的連續性。
(十一)小結
一般來說,在手機開發中,如果是高級瀏覽器,還是建議直接使用-webkit-transition,其次是-webkit-animation+keyframes,但是經過多次項目的教訓,這玩意不穩定,bug很多,最百搭的當然是javascript動畫,使用setInterval拯救地球。
也歡迎大家對於動畫實現的問題做交流討論。