說到在網頁裏建立動畫,你可能很快會想到jQuery的animate()
方法,或者css3的animation
和transition
。如今,本文將介紹另外一個web動畫的可選方案,GSAP。javascript
GSAP的全名是GreenSock Animation Platform,這個名字是有些怪異(官網還在各類安利你加入它的Club),但它的確是一個從flash時代一直髮展到今天的專業動畫庫。css
在官網選擇Download zip就能夠拿到GSAP源碼,解壓後能夠看到有這些文件:java
這裏的TweenLite.js
、TweenMax.js
、TimelineLite.js
和TimelineMax.js
4個文件就是GSAP的通常引用庫文件,不過,這幾個文件還有一些重疊和包含的關係,以下圖:css3
所以,若是想要簡單地引入GSAP的主體功能,使用TweenMax.js
這一個文件便可(請看前一張圖中反映出的這個文件的大小)。而若是要爭取更小的庫文件大小,應該使用TweenLite.js
(必需)+ 其餘文件的組合。web
這4個文件分別包含了什麼東西呢?數組
TweenLite
是GSAP的主體核心,它用於建立基本動畫,是其餘各種模塊的基礎。通常都會搭配plugins/CSSPlugin
以實現DOM元素的動畫(也就是咱們最熟悉的動畫了)。瀏覽器
TimelineLite
是一個叫作時間軸的動畫容器,它用於對多個動畫進行有序的組織與控制。函數
TimeLineMax
是TimelineLite
的升級版,在TimelineLite
的基礎之上,能夠有更高級的組織與控制。工具
TweenMax
是GSAP集合包,除前面3個以外,還包括plugins
裏的經常使用插件以及easing
裏的緩動函數補充。post
GSAP在Customize裏是這樣描述本身擁有的模塊的:
默認勾選的TweenLite
+ css plugin
是最簡單的應用組合,本文就先從它們開始(v1.18.4)。
一切動畫,都從值的變化開始。
TweenLite做爲主體核心,作的就是這件事。TweenLite具體如何使用呢?請看下面這個例子:
var obj = { myProp: 0 }; TweenLite.to(obj, 0.2, { myProp: 1, onUpdate: function() { console.log("[update] obj.myProp = ", obj.myProp); } });
TweenLite.to(target, duration, vars)
是TweenLite最經常使用的方法,target
指定動畫元素,duration
指定動畫持續時間,vars
指定動畫的目標值。請注意,這裏並無操做任何DOM元素,因此和咱們通常寫的動畫不太同樣。運行一下:
能夠看到,TweenLite的做用是,讓obj
的屬性myProp
從初始值0
,變化到目標值1
。雖然沒有視覺效果,但這就是基本的值動畫。
TweenLite加上plugins/CSSPlugin
後,就能夠作咱們熟悉的DOM元素的動畫了。例如:
TweenLite.to("#ball1", 2, { x: 200 });
效果:
GSAP用x
、y
表示transform的translateX
和translateY
。TweenLite.to(target, duration, vars)
的第一個參數target
能夠是選擇符,所以這裏就是選取id爲ball1
的元素,執行時長爲2s的動畫,從當前位置移動到translateX(200px)
的位置。
你能夠在的第3個參數vars
內添加任意css屬性,它們都會被用做被選取元素的動畫目標值。
第3個參數vars
內除了css屬性以外,還能夠指定許多具備特定意義的屬性,用於配置動畫。GSAP會自動根據名字來區分它們。
例如,delay
和ease
分別用於設置動畫延遲及緩動函數:
TweenLite.to("#ball1", 2, { x: 200, delay: 2, ease: Linear.easeNone });
這裏的動畫將延遲2s運行,並且改成線性變化(默認爲Quad.easeOut
)。
若是想要在動畫開始,動畫運行的每一幀,動畫結束時分別執行對應的事件函數,使用onStart
、onUpdate
、onComplete
。前文的值動畫的例子就是經過onUpdate
把值的變化打印出來的。
GSAP有專門的位置能夠查詢緩動函數。更多的可用特定屬性,請參考官方文檔。
有些時候咱們可能不清楚元素當前是否已經有translate
,但就是想讓元素相對它本來的位置移動一段距離。這時能夠用相對值,像這樣:
TweenLite.to("#ball1", 2, { x: "+=200px" });
相似的還有-=
,按照以上寫法,不管元素當前的translateX
是多少,都會相對偏移200px
。
除to()
以外,還有from()
和fromTo()
。單詞都很簡單,對吧?
from()
和to()
的參數及用法徹底同樣,只是vars
裏的屬性定義的是動畫初始值,而元素本來的屬性用做動畫目標值。例如:
TweenLite.from("#ball1", 2, { x: "+=200px", backgroundColor: "#2196f3" });
效果:
這裏能夠看到,顏色動畫也是可用的。
TweenLite.fromTo(target, duration, fromVars, toVars)
的參數要多1個,不過從字面意思就很容易理解,即分別讓你指定動畫的初始和結尾。須要注意的是,前面提到的具備特定意義的屬性,如delay
,ease
,都要寫在toVars
裏,在fromVars
裏定義的無效。
和jQuery.animate()
的風格不一樣,GSAP以動畫爲主體,你能夠這樣保存動畫:
var tween = TweenLite.to("#ball1", 2, { x: "+=200px" });
而後你能夠作精細的控制:
// 暫停 tween.pause(); // 繼續播放 tween.resume(); // 反轉播放 tween.reverse(); // 跳轉到1s進度處開始播放 tween.seek(1); // 重播 tween.restart(); // 動畫變爲三倍速 tween.timeScale(3);
這些能夠看作GSAP做爲專業動畫庫的體現。
前面的例子中反覆用到了相似jQuery的選擇器,但GSAP並無自帶選擇器,相關源碼以下:
TweenLite.selector = window.$ || window.jQuery || function(e) { var selector = window.$ || window.jQuery; if (selector) { TweenLite.selector = selector; return selector(e); } return (typeof(document) === "undefined") ? e : (document.querySelectorAll ? document.querySelectorAll(e) : document.getElementById((e.charAt(0) === "#") ? e.substr(1) : e)); };
GSAP不依賴jQuery,但若是引入了jQuery,GSAP會使用jQuery的選擇器,不然回退到document.querySelectorAll()
及document.getElementById()
。
好像TweenLite
+ css plugin
就已經足夠用了,這個Timeline系列是作什麼的呢?
想象你是一個動畫的導演,你要按劇本安排演員在一個CUT裏依次上場和退場。在前文的例子裏,咱們只有一個演員(#ball1
),但如今,咱們要拍一個有20+演員的動畫大片,要怎麼辦呢?
你也許曾用css3的animation
作過相似的事情,作法是,當轉換到一個場景(CUT)後,爲場景裏的全部演員依次設定適當的delay
。只要delay
計劃好,看起來就是漂亮精彩的大片。
不過,這可沒有那麼簡單,假如你已經安排好了20位演員的上場時間,如今改了下劇本,來了第21位演員要在最開始上場,你會發現你可能要依次調整在它以後的全部演員的delay
...
GSAP的TweenLite也會有一樣的問題,所以,咱們須要有一個工具來統一管理多個元素的多個動畫,這就是TimelineLite。
若是你作過視頻編輯,你必定很熟悉「時間軸」這個概念。簡單來講,每個元素的單次動畫都是一段素材,咱們須要把它們分別放置到同一個時間軸的適當位置,才能集合在一塊兒獲得有序的動畫大片。
如今咱們引入TimelineLite
。下面是一個例子:
var tl = new TimelineLite(); tl.from("#ball1", 1, { y: "-=60px", autoAlpha: 0 }).from("#ball2", 1, { x: "+=60px", autoAlpha: 0 }).from("#ball3", 1, { y: "+=60px", autoAlpha: 0 }).from("#ball4", 1, { x: "-=60px", autoAlpha: 0 });
效果是:
以上的tl.from()
等同於如下代碼:
tl.add(TweenLite.from("#ball1", 1, { y: "-=60px", autoAlpha: 0 }));
可見,TimelineLite像一個容器,它能夠經過add()
方法將TweenLite動畫添加到本身的時間軸上。而後,動畫將以時間軸爲總體,進行播放。
在默認狀況下,TimelineLite會這樣按添加順序依次排列它們的位置,就這樣,咱們不借助delay
作出了這種較複雜的動畫組合。
若是畫一下這裏的時間軸,是這樣的:
若是要讓第2個動畫不是在第1個剛結束時播放,而是更提早一點,看起來更連貫的話?
這樣作:
var tl = new TimelineLite(); tl.from("#ball1", 1, { y: "-=60px", autoAlpha: 0 }).from("#ball2", 1, { x: "+=60px", autoAlpha: 0 }, "-=0.7").from("#ball3", 1, { y: "+=60px", autoAlpha: 0 }, "-=0.7").from("#ball4", 1, { x: "-=60px", autoAlpha: 0 }, "-=0.7");
其中tl.from(target, duration, vars, position)
等同於tl.add(TweenLite.from(target, duration, vars), position);
,這裏的position
參數指定動畫在時間軸上的位置,默認爲+=0
也就是取前一個動畫的結束點。以上的-=0.7
就是相對這個位置再提早0.7s,這樣就讓動畫互相之間有了重疊,看起來更連貫流暢一些。
效果:
時間軸像這樣:
把多個動畫裝進時間軸的重要做用是,能夠當作一個總體進行控制和調整。時間軸的這些方法相似TweenLite:
// 在1s時間進度位置暫停 tl.pause(1); // ... (和前面tween同樣) // 跳轉到50%進度處 tl.progess(0.5);
若是多個元素的動畫是同樣的,並且它們須要有規律地安排在時間軸的不一樣位置,那麼很是適合用staggerFrom()
、staggerTo()
及staggerFromTo()
。例如:
tl.staggerFrom(["#ball1", "#ball2", "#ball3", "#ball4", ], 1, { scale: "-=0.5", autoAlpha: 0 }, 2);
這樣使用數組,就能夠同時選中多個元素。
效果是:
能夠看到,每個元素按照順序依次執行動畫,間隔2s。
若是你以爲還須要一些動畫和時間軸的更高級功能(如同一動畫間隔重複),能夠選擇TimelineMax和TweenMax。它們並不須要更多的學習成本,如字面意思所示,TweenMax是TweenLite的升級版,擁有其所有特性,只是增長了一些額外的高級控制。它們的語法徹底一致,你能夠試試用全局搜索把全部TweenLite替換成TweenMax,不會有任何影響。TimelineMax和TimelineLite的關係也是如此。
能夠到IE6(使用jQuery1.x的選擇器)。
另外,不要指望在不支持的瀏覽器上作3d transform動畫。
若是你大部分動畫都使用同一種緩動函數,那麼用TweenLite.defaultEase
會很方便,好比修改成Expo.easeOut
:
TweenLite.defaultEase = Expo.easeOut;
默認狀況下,執行過動畫的元素會留下style
的內聯樣式,若是你擔憂這可能形成額外影響,能夠設定clearProps
參數清空它:
TweenLite.to("#ball1", 2, { x: 200, clearProps: "all", autoAlpha: 0 });
若是隻須要清理個別樣式,單獨寫出來便可,如clearProps: "opacity"
。
前文反覆用到的autoAlpha
並非css屬性,而是GSAP給定的一個特殊屬性。autoAlpha
是opacity
和visibility
這2個css屬性的結合。
爲何要結合起來呢?通常來講,opacity
爲0
的不可見元素,咱們會認爲它也是不可交互的(好比onclick
不觸發),所以附加visibility: hidden
能夠保證這一點。GSAP會正確處理動畫過程當中這2個css屬性的變化。
GSAP有一份包含豐富參考代碼的備忘單(Cheat Sheet),能夠幫助你節約時間。
GSAP裏的不少概念和API設計能夠追溯到flash時代。雖然flash在今天已經不多被使用,但「flash動畫」一詞可以深刻人心是有它的緣由的。
GSAP是專業動畫庫,在大部分狀況下,它也具有更好的動畫性能。若是你打算在網頁裏製做一個動畫大片,那你如今應該知道什麼能夠幫助你了 :) 。
(從新編輯自個人博客,原文地址:http://acgtofe.com/posts/2016/05/gsap-for-animation-pro)