GSAP (GreenSock Animation Platform):綠襪子動畫平台簡介

GSAP 是 GreenSock Animation Platform 的簡稱,是一套專門處理動畫與特效的 JS 套件。
GSAP 採用模組化與插件式的結構,保持了核心引擎的輕量。有四個核心 API,TweenLite、TimelinLite、TimelineMax、TweenMax,而 TweenMax 是所有 API 與 Plugin 的集合。

但 2019年底 GSAP 從 GSAP2 升級到 GSAP3,不再區分 TweenLite、TimelineLite、TimelineMax、TweenMax,全部合並為 gsap 物件。
前身為 TweenMax 與 TimelineMax 的動畫製作工具,是 JavaScript 的動畫製作函式庫。

舊版的 GreenSock:TweenLite 與 TweenMax V2

下主要分為:

舊 TimelineMax 用法可參考站內文章 TimelineMax 活用時間軸與SVG動畫TimelineMax 活用時間軸與SVG動畫 – 收音機實作

新版的 GSAP V3

GSAP3 官方相關資源如下:

GSAP3 的優點:

  • 檔案大小為 TweenMax 的一半,但新增了 50 多個功能。
  • 全部合並為 gsap 物件,不用在區分 TweenLite 和 TimelineMax 物件。
  • 新版本相容舊版本寫法,所以可以沿用,新寫法提供更好的可讀性。

V2 與 V3 新舊版用法可參考 GSAP3:專門處理動畫與特效的 JS 套件 (hackmd) 一文 (github 與 hackmd 內容相同)。
裡面有約略談到 V2 與 V3 有些不用的用法,但使用概念相同。


GSAP 的基本使用與概念

安裝與引入 GSAP 動畫函式庫

GSAP 官方文件:GSAP Installation 主要說明幾個方來源如下:

  1. Download
  2. Install helper
  3. CDN (easiest & fastest load)
  4. NPM
  5. GitHub (includes prior versions)
  6. CodePen (use bonus plugins on CodePen free anytime!)

比較有效率的方式是直接使用 CDN 的方式引入函式庫,另外也可以透過 GSAP 3 Install Helper 的部份去選取使用到的函式庫與相關資源,而基本上一定要引入本函式庫核心 GSAP 同時也會引入 Tween 與 Timeline)。


GSAP 3 物件與舊版 (TweenMax) 物件實體化方式與寫法差異

參考資料:MikeOnlineCourse / GSAP3-Update-10-Tips

舊版在 TweenMax.to() 的方法中,使用三個參數,其中第二個參數是直接指定時間數值,可讀性不高。

新版直接將 TweenLite、TimelinLite、TimelineMax、TweenMax 的相關應用函式庫,都整合到 gsap 物件中來使用。
<duration (執行時間)> 整合到第二個參數裡的 {} 物件中,一樣是以物件屬性與值的方式,提示可讀性。

新舊版的寫法相容,可直接使用舊版的寫法來使用,不過可讀性有差,在官方文件中也較推新的寫法。

See the Pen GSAP-3-新的撰寫風格 by Jimmy_Wu (@Jimmy_Wu) on CodePen.light


時間軸預設值 (Timeline-defaults) 使用方式

參考資料:GSAP3-Update-10-Tips/02-Timeline-defaults.html

使用時間軸 .timeline() 方法

  • 動畫中主要分為二段動畫,先動紅色區塊後接動藍色,這部份就需要使用到 .timeline() 時間軸功能進行動畫設計。
  • 使用 gsap 物件下的 .timeline() 方法,二段藍紅色動畫分別使用 .to() 法方加入動畫時間軸中,第一個參數設定對象 .cube1 紅色與 .cube2 藍色。
  • 二段動畫都有用到 ease: "elastic", duration: 1, 設定,但不同的地方只有 x: 100y: 100

See the Pen GSAP-3-時間軸預設值 (Timeline-defaults)-1 by Jimmy_Wu (@Jimmy_Wu) on CodePen.light

將後方的方法鍊裡重覆的設定屬性,移入時間軸預設值 defaults: {} 中

接續上面的部份,處理重覆的設定,透過 .timeline() 方法中,加入 {} 物件再包著 defaults: 設定,值的部份也是使用 {} 物件包著,將下方 .to() 中的參數設定,加入到 .timeline({ defaults: { <共用設定一>, <共用設定二> } })

See the Pen GSAP-3-時間軸預設值 (Timeline-defaults)-2 by Jimmy_Wu (@Jimmy_Wu) on CodePen.light

在 gsap 新的寫法,可使用 defaults: {} 設定將共用的設定屬性加入,如果後方的方法鍊有很多的話,就都可以透過這樣的方式都使用到一樣的設定。


全新的動畫交錯屬性

參考資料:GSAP3-Update-10-Tips/03-staggers.html
針對下面的元素透過按鈕觸發,操作執行交錯動畫。

原舊寫法的使用與缺點

舊寫法主要是使用 staggerTostaggerFromstaggerFromTo 方法來處理交錯的效果,但在新版中被捨棄。
同樣的,將舊的寫法 TweenMax.staggerTo() 應用於新版中撰寫應用,同樣也可以相容。
透過 x:"+=100" 設定,將對象在每次點按的 x 座標加總 100,每點按都會更往右移。
交錯動效也是由 0.5 秒接續後執行。

See the Pen GSAP-3-全新的動畫交錯屬性-舊寫法 by Jimmy_Wu (@Jimmy_Wu) on CodePen.light

新寫法使用與優點

透過新的寫法,在第二個參數 {} 物件裡,一樣與 duration: 屬性概念一樣,讓可讀性提示成為屬性設定。

See the Pen GSAP-3-全新的動畫交錯屬性-新寫法 by Jimmy_Wu (@Jimmy_Wu) on CodePen.light

新的寫法上更直觀,可以直接使用 stagger: 屬性進行設定,比較有類別的方式,不用另外在透過方法的部份來撰寫。


新的亂數函式功能

透過按鈕點按後,可透過設定泛圍隨機的值。
以操作 x 軸的座標值來說,透過 random(<起始數值>, <最大數值>) 的方法進行動態亂數產生座標數值。

需特別注意 random(<起始數值>, <最大數值>) 方法外面要使用 "" 字串包起來,這樣 gsap 才會認出是專屬新的方法,進行運作產生亂數。

透過 random() 設定,在每點按按鈕後就會有不同座標產生。

See the Pen GSAP-3-全新的動畫交錯屬性-新的亂數函式功能 by Jimmy_Wu (@Jimmy_Wu) on CodePen.light


動畫影格功能

參考資料:GSAP3-Update-10-Tips/05-Keyframes.html

Keyframes: 是 gsap 新版中的新功能,主要用來做單一物件的操作,比較 timeline: 主要用來針對多個物件進行操作。

動效執行順序是由左到右、由上到下、旋轉,每個部份都間隔都會是 1 秒,另外後二個有設定廷遲 ( duration)。

使用方式是在 gsap 鍊方法中的第二個物件 {} 參數,以一個屬性值名稱 keyframs: 與屬性值設定,屬性基是一個 [] 陣列,裡面用 {} 來設定每個影格的設定。

See the Pen GSAP-3-全新的動畫交錯屬性-動畫影格功能 by Jimmy_Wu (@Jimmy_Wu) on CodePen.light


寬高的自動擴展

參考資料:GSAP3-Update-10-Tips/06-width-height-auto.html

gsap 透過原本元素的高寬度 (h100, y100),在點按按鈕後讓高寬度的屬性變數 auto,轉按後在元素對象變化中,原本的 CSS 直接修改 auto 是直接變化容器,但使用 gsap 操作的話,會在變化的過程中加入動畫。

See the Pen GSAP-3-全新的動畫交錯屬性-寬高的自動擴展 by Jimmy_Wu (@Jimmy_Wu) on CodePen.light


新的repeatRefresh設定(亂數定位接續)

參考資料:GSAP3-Update-10-Tips/07-new-repeatRefresh.html

相關的元素結構如下,動畫的部份主要希望使用 repeat: 5,x: "random(100, 500)", 進行重新執行動畫 5 次,每一次重新執行都在原本亂數座標中接續於下一個新的亂數座標。

不使用 repeatRefresh: true 屬性設定,讓亂數定位會在重新都由原定位點開始

repeatRefresh: true 沒加入屬性設定,所有的亂數定位都會被由原本的起始位置跑起。

See the Pen GSAP-3-全新的動畫交錯屬性-repeatRefresh設定(亂數定位接續)-1 by Jimmy_Wu (@Jimmy_Wu) on CodePen.light

使用 repeatRefresh: true 屬性設定,讓亂數定位接續定位點開始

新的 repeatRefresh 功能會再repeat執行時,記錄當前狀態然後再執行,而不會整個重新開始。
repeatRefresh: true 沒加入屬性設定,所有的亂數定位都會被由原本的起始位置跑起。

See the Pen GSAP-3-全新的動畫交錯屬性-repeatRefresh設定(亂數定位接續)-2 by Jimmy_Wu (@Jimmy_Wu) on CodePen.light


全域動畫設定

參考資料:GSAP3-Update-10-Tips/08-global-timeline.html

全局的動畫控制 & 設定如下:

  • gsap.globalTimeline.timeScale(0.1); 控制整個動化的速率 0 ~ 1
  • gsap.globalTimeline.pause(); 停止目前所有動畫
  • gsap.globalTimeline.play(); 播放目前所有動畫
  • gsap.globalTimeline.paused(); 回傳目前動畫狀態 true:暫停 / false:播放

gsap 提供新的方法,在畫面上有二個元素執行動畫,透過 .timeline() 進行執行操作,讓二個元素透分別由左至右與由上至下移動。

globalTimeline.pause() 停止所有動畫與 gsap.globalTimeline.play() 接續所有動畫播放

但目前的動無是無法直接播放,主要是 gsap 新功能 globalTimeline 功能能控製所有 gsap 裡的所有動畫,由 globalTimeline.pause(); 所停止。

gsap.globalTimeline.play() 用來操作部份動畫播放,由於一開炲使用 globalTimeline.pause(); 先停止著動畫,透過點按按鈕執行 gsap.globalTimeline.play() 後才開炲播放。

正在進行播放一半時,點按下 globalTimeline.pause(); 會使得動畫在一半停止,但在次點按 globalTimeline.play(); 後又接續播放。

See the Pen GSAP-3-全新的動畫交錯屬性-全域動畫設定-1 by Jimmy_Wu (@Jimmy_Wu) on CodePen.light

gsap.globalTimeline.timeScale() 調整全局動畫播放速度

gsap.globalTimeline.timeScale() 主要用來操作 gsap 全局動畫的方法,數值 1 會是正常播放,但如果是使用 0.5 會是慢速 0.5 倍慢播動畫,如果是設定成 0.1 時就是以 1/10 的速度播放。

See the Pen GSAP-3-全新的動畫交錯屬性-全域動畫設定-2 by Jimmy_Wu (@Jimmy_Wu) on CodePen.light

gsap.globalTimeline.timeScale() 主要針對的是全局動畫的速度,但如果單一的話就不要使用,

gsap.globalTimeline.paused() 檢測動畫狀態

透過 gsap.globalTimeline.paused(); 查看動畫播放的狀態, false 是播放而 true 是停止播放。
一開始可正當取得對象與播放動畫,所以使用 console.log(gsap.globalTimeline.paused()) 會回 false
另外在停止按鈕的地方對加上 console.log(gsap.globalTimeline.paused()),當點按後會出現 <code>true

See the Pen GSAP-3-全新的動畫交錯屬性-全域動畫設定-3 by Jimmy_Wu (@Jimmy_Wu) on CodePen.light


更貼近web開發使用者屬性

參考資料:GSAP3-Update-10-Tips/09-used_to_in_css.html

在 gsap 新版中加強了可讀性外,另外也針對屬性的部份以 css 屬性進行操作。

以舊版 gsap 中對應出新版以較習慣 css 屬性寫法運用,對照如下:
x => translateX
y => translateY
rotation => rotate
rotationX => rotateX
rotationY => rotateY

新舊版 translateX 與 x 寫法對應操作

以新版寫法來說,使用 translateX: 100 更直覺,另外 x: 100 也可相容運用,不過新舊寫法只能選一種,都放的話只會有一種設定。

See the Pen GSAP-3-全新的動畫交錯屬性-更貼近web開發使用者屬性-1 by Jimmy_Wu (@Jimmy_Wu) on CodePen.light

直接使用 css 屬性值 translateX: 50 vw 撰寫

以 css 方式撰寫程式,需要在屬性值外包 '' 成字串型態。

See the Pen GSAP-3-全新的動畫交錯屬性-更貼近web開發使用者屬性-2 by Jimmy_Wu (@Jimmy_Wu) on CodePen.light

直接使用 css 屬性值 rotate: 360_ccw (逆時轉) 與 rotate: 360_cw (順時轉)

透過 rotate: 360_ccw (逆時轉) 與 r otate: 360_cw (順時轉) 來設定屬性。

See the Pen GSAP-3-全新的動畫交錯屬性-更貼近web開發使用者屬性-逆順時針旋轉 by Jimmy_Wu (@Jimmy_Wu) on CodePen.light

因為使用 css rotate 旋轉只會轉一圈,主要的圈數是 * 360 下去計算,例如二圈就是 360*2=720


新的動畫輔助工具

參考資料:GSAP3-Update-10-Tips/10-Utility-Methods.html

gsap 官方另外提供了一些工具程式可用來方便開發使用。
目前使用到的部份如下

  • snap() -> 攔截數值或是陣列中最接近的數值
  • mapRange() -> 設定一個數字範圍及相對應換算值,將數字範圍換算成相對應換算值回傳
  • interpolate() -> 相似類型的任意兩個值具有多個屬性的對象製作之間線性插值,介於 0 和 1 之間 (數字,顏色,字串,數組,具有多組嵌入數字的複雜字符串)
  • pipe() -> 將多個函式調用組合,將結果傳遞到下一個函式。

未使用 gsap 工具的基本頁面功能,將滑鼠的移動座標傳向網頁畫面

以下部份只有處理透過事件監聽讓滑鼠的座標, handMoveVal() 做為聽讓滑鼠的座標的函式,裡面使用 e (event) 的事件,透過結構賦序的方式一層層賦於 x 變數上,透過事件將取得的 x 滑鼠座標,透過 handText 箭頭函式傳向畫面做渲染,更新畫面上的座標字串。

See the Pen GSAP-3-全新的動畫交錯屬性-新的動畫輔助工具-1 by Jimmy_Wu (@Jimmy_Wu) on CodePen.light

snap() 攔截數值或是陣列中最接近的數值

snap 翻中文折斷。
官網文件上說明 snap() 用法:
Snap a value to either an increment (ex: snap(5, 13) –> 15) or to the closest value in an array (ex: snap([0, 5, 10], 7) –> 5).

snap() 是用來給予泛圍值。
gsap.utils.snap(50); 先將使用數值 50 做為一個泛圍值的基數。
將透過事件的 x 座標值,透過 snap() 執行,在畫面上更新坐標時會是以 50 為基數更新。
在滑鼠移動時到 25 時畫面上還不會更新,而如果到了 26 之後畫面上就會更新到 50,以定義的基本數值的一半判斷超過後才更新畫面。

See the Pen GSAP-3-全新的動畫交錯屬性-新的動畫輔助工具-2-snap() 攔截數值或是陣列中最接近的數值 by Jimmy_Wu (@Jimmy_Wu) on CodePen.light

snap() 事件監聽只取 window 設定泛圍內數值,泛圍外不取

接著將原本的 gsap.utils.snap() 所使用的數值參數,改成使用物件 { values: [0, window.innerWidth], radius: 100 } 操作多個設定。
values: [0, window.innerWidth] 陣列中的 0 是視窗列左方,而 window.innerWidt 最右方座標,這也是視窗總寬度與起始結數包在陣列中。
radius: 100 指的是以中心點的前後方都扣除 100 數值做不感應,也就是前後扣除各 100,總寬度減 200

window 與元素寬度參考資料:

See the Pen GSAP-3-全新的動畫交錯屬性-新的動畫輔助工具-3-事件監聽只取 window 設定泛圍內數值,泛圍外不取 by Jimmy_Wu (@Jimmy_Wu) on CodePen.light

mapRange() 設定一個數字範圍及相對應換算值,將數字範圍換算成相對應換算值回傳

透過所設定的數值,轉換成一個計算範圍數值。
mapRange() 中的四個參數:
1. 0 為視窗寬度
2. window.innerWidth 視窗最右方,也就是水平座標的結位
3. 換算開始數值。
4. 換算結果最大值,設定為最右方結尾處。

在滑鼠右左二邊 (二邊綠色) 的 100 泛圍中間的藍色區塊才會有效果成。

See the Pen GSAP-3-全新的動畫交錯屬性-新的動畫輔助工具-4-mapRange() 設定一個數字範圍及相對應換算值,將數字範圍換算成相對應換算值回傳 by Jimmy_Wu (@Jimmy_Wu) on CodePen.light

interpolate() 相似類型的任意兩個值具有多個屬性的對象製作之間線性插值,介於 0 和 1 之間

透過 .interpolate() 方法,可以將二個使用色票參數,用來換算成 0 ( '#c00' 紅色) 和 1 ( '#00c' 藍色) 的區塊,來操作色彩做變化的運算。

透過 interpolate() 執行 widthRange(snapRadius(x)) 二層的操作方法,將二個藍紅色色票所轉換的數值 0~1,透過滑鼠在水平移動時產生變化。

See the Pen GSAP-3-全新的動畫交錯屬性-新的動畫輔助工具-05-interpolate() 相似類型的任意兩個值具有多個屬性的對象製作之間線性插值,介於0和1之間 by Jimmy_Wu (@Jimmy_Wu) on CodePen.light

pipe() 將多個函式調用組合,將結果傳遞到下一個函式

gsap.utils 工具類函式下,使用 pipe() 來串接先前所用的方法,以包多層的 interpolate(widthRange(snapRadius(x))) 執行函式部份,透過 pipe() 方法調用其他 gsap.utils 組合的函式,讓程式碼可達更直觀與更優化。

See the Pen GSAP-3-全新的動畫交錯屬性-新的動畫輔助工具-06-pipe() 將多個函式調用組合,將結果傳遞到下一個函式 by Jimmy_Wu (@Jimmy_Wu) on CodePen.light


其他備註

關於基本語法中的屬性值,如果是遇到有連字號 ( -) 的樣式屬性,則需要使用 JavaScript 的「駝峰式大小寫命名法 (Camel Case)」,例如 backgroundSize、backgroundImage、clipPath 等。

GSAP 動畫函式庫,主要是用來操作補間動畫 (Tween animation),透過 GSAP 官方文件介紹,主要以 Tweens 與 Timelines 二個方法操作補間動畫。


相關資源