GSAP (GreenSock Animation Platform):綠襪子動畫平台簡介
- GreenSock 英文官網,英文文件:(V2)、(V3)
- GreenSock 中文官網 (V2),中文文件 (V2):TweenMax中文手册 與 TimelineMax中文手册
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
下主要分為:
- TweenLite 與 TweenMax:方法上基本上差不多,TweenLite 的部份以精簡為主,少了些 TweenMax 獨有方法,可見 TweenMax中文手冊/TweenLite中文手冊。
- TimelineLite 與 TimelineMax:TimelineLite 同樣少了一些方法以簡易輕巧為主,可見 TweenMax中文手冊/TweenLite中文手冊
舊 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 主要說明幾個方來源如下:
- Download
- Install helper
- CDN (easiest & fastest load)
- NPM
- GitHub (includes prior versions)
- CodePen (use bonus plugins on CodePen free anytime!)
比較有效率的方式是直接使用 CDN 的方式引入函式庫,另外也可以透過 GSAP 3 Install Helper 的部份去選取使用到的函式庫與相關資源,而基本上一定要引入本函式庫核心 GSAP 同時也會引入 Tween 與 Timeline)。
1 | <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.6.0/gsap.min.js"></script> |
GSAP 3 物件與舊版 (TweenMax) 物件實體化方式與寫法差異
參考資料:MikeOnlineCourse / GSAP3-Update-10-Tips
舊版在 TweenMax.to() 的方法中,使用三個參數,其中第二個參數是直接指定時間數值,可讀性不高。
1 2 3 4 | /** 舊版基礎語法 * TweenMax.to("<對象>", <執行時間(duration)>, { <屬性名>: <屬性值>, }); */ TweenMax.to(".box-100", 1, {x: 200}); |
新版直接將 TweenLite、TimelinLite、TimelineMax、TweenMax 的相關應用函式庫,都整合到 gsap 物件中來使用。
將 <duration (執行時間)> 整合到第二個參數裡的 {} 物件中,一樣是以物件屬性與值的方式,提示可讀性。
1 2 3 4 | /** * gsap.to("<對象>", { <duration (執行時間)>: <時間數值>, <屬性名>: <屬性值>, }); */ gsap.to(".box-100", 1, {x: 200}); |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | /** 新舊版寫法差別: * 不再區分TweenLite,TimelineLite和TimelineMax,以全部合併gsap物件! * 雖然新版本仍然相容舊寫法,但是新寫法提供較好的可讀性。 */ const oldBtn = document.getElementById("oldBtn"); const newBtn = document.getElementById("newBtn"); oldBtn.addEventListener("click", () => { // OLD TweenMax.to(".box-100", 1, { x: 200, ease: "elastic" }); }); newBtn.addEventListener("click", () => { //NEW gsap.to(".box-100", { duration: 1, x: 400, ease: "elastic" }); }); |
新舊版的寫法相容,可直接使用舊版的寫法來使用,不過可讀性有差,在官方文件中也較推新的寫法。
See the Pen GSAP-3-新的撰寫風格 by Jimmy_Wu (@Jimmy_Wu) on CodePen.
時間軸預設值 (Timeline-defaults) 使用方式
參考資料:GSAP3-Update-10-Tips/02-Timeline-defaults.html
使用時間軸 .timeline() 方法
- 動畫中主要分為二段動畫,先動紅色區塊後接動藍色,這部份就需要使用到 .timeline() 時間軸功能進行動畫設計。
- 使用 gsap 物件下的 .timeline() 方法,二段藍紅色動畫分別使用 .to() 法方加入動畫時間軸中,第一個參數設定對象 .cube1 紅色與 .cube2 藍色。
- 二段動畫都有用到 ease: "elastic", duration: 1, 設定,但不同的地方只有 x: 100 與 y: 100。
1 2 3 4 5 6 7 | const btn = document.getElementById("btn"); btn.addEventListener("click", () => { gsap .timeline() .to(".cube1", { ease: "elastic", duration: 1, x: 100 }) .to(".cube2", { ease: "elastic", duration: 1, y: 100 }); }); |
See the Pen GSAP-3-時間軸預設值 (Timeline-defaults)-1 by Jimmy_Wu (@Jimmy_Wu) on CodePen.
將後方的方法鍊裡重覆的設定屬性,移入時間軸預設值 defaults: {} 中
接續上面的部份,處理重覆的設定,透過 .timeline() 方法中,加入 {} 物件再包著 defaults: 設定,值的部份也是使用 {} 物件包著,將下方 .to() 中的參數設定,加入到 .timeline({ defaults: { <共用設定一>, <共用設定二> } })
1 2 3 4 5 6 7 8 | const btn = document.getElementById("btn"); btn.addEventListener("click", () => { gsap // .timeline({ defaults: { <共用設定一>, <共用設定二> } }) .timeline({ defaults: { ease: "elastic", duration: 1 } }) .to(".cube1", { x: 100 }) .to(".cube2", { y: 100 }); }); |
See the Pen GSAP-3-時間軸預設值 (Timeline-defaults)-2 by Jimmy_Wu (@Jimmy_Wu) on CodePen.
在 gsap 新的寫法,可使用 defaults: {} 設定將共用的設定屬性加入,如果後方的方法鍊有很多的話,就都可以透過這樣的方式都使用到一樣的設定。
全新的動畫交錯屬性
參考資料:GSAP3-Update-10-Tips/03-staggers.html
針對下面的元素透過按鈕觸發,操作執行交錯動畫。
1 2 3 4 | <button id="btn">click</button> <div class="cube box-100 bg-red"></div> <div class="cube box-100 bg-blue"></div> <div class="cube box-100 bg-yellowgreen"></div> |
原舊寫法的使用與缺點
舊寫法主要是使用 staggerTo、 staggerFrom、 staggerFromTo 方法來處理交錯的效果,但在新版中被捨棄。
同樣的,將舊的寫法 TweenMax.staggerTo() 應用於新版中撰寫應用,同樣也可以相容。
透過 x:"+=100" 設定,將對象在每次點按的 x 座標加總 100,每點按都會更往右移。
交錯動效也是由 0.5 秒接續後執行。
1 2 3 4 5 | const btn = document.getElementById("btn"); btn.addEventListener("click", () => { //OLD TweenMax.staggerTo(".cube", 0.5, {x:"+=100"}, 0.5); }); |
See the Pen GSAP-3-全新的動畫交錯屬性-舊寫法 by Jimmy_Wu (@Jimmy_Wu) on CodePen.
新寫法使用與優點
透過新的寫法,在第二個參數 {} 物件裡,一樣與 duration: 屬性概念一樣,讓可讀性提示成為屬性設定。
1 2 3 4 5 | const btn = document.getElementById("btn"); btn.addEventListener("click", () => { //NEW gsap.to(".cube", {duration: 1, x:"+=100", stagger: 0.5}); }); |
See the Pen GSAP-3-全新的動畫交錯屬性-新寫法 by Jimmy_Wu (@Jimmy_Wu) on CodePen.
新的寫法上更直觀,可以直接使用 stagger: 屬性進行設定,比較有類別的方式,不用另外在透過方法的部份來撰寫。
新的亂數函式功能
透過按鈕點按後,可透過設定泛圍隨機的值。
以操作 x 軸的座標值來說,透過 random(<起始數值>, <最大數值>) 的方法進行動態亂數產生座標數值。
需特別注意 random(<起始數值>, <最大數值>) 方法外面要使用 "" 字串包起來,這樣 gsap 才會認出是專屬新的方法,進行運作產生亂數。
透過 random() 設定,在每點按按鈕後就會有不同座標產生。
1 2 3 4 5 6 7 8 9 10 | const btn = document.getElementById("btn"); btn.addEventListener("click", () => { // 提供新的random方法,可以再100~500之間隨機取値 gsap.to(".cube", { duration: 0.5, stagger: 0.5, x: "random(100, 500)", y: "random(20, 50)", }); }); |
See the Pen GSAP-3-全新的動畫交錯屬性-新的亂數函式功能 by Jimmy_Wu (@Jimmy_Wu) on CodePen.
動畫影格功能
參考資料: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.
寬高的自動擴展
參考資料:GSAP3-Update-10-Tips/06-width-height-auto.html
gsap 透過原本元素的高寬度 (h100, y100),在點按按鈕後讓高寬度的屬性變數 auto,轉按後在元素對象變化中,原本的 CSS 直接修改 auto 是直接變化容器,但使用 gsap 操作的話,會在變化的過程中加入動畫。
1 2 3 4 5 6 7 8 9 10 11 | <button id="btn">click</button> <div id="app"> <div class="box-100 bg-red pd20"> <p>1</p> <p>1</p> <p>1</p> <p>1</p> <p>1</p> <p>1</p> </div> </div> |
1 2 3 4 5 6 7 8 9 10 | const btn = document.getElementById("btn"); btn.addEventListener("click", () => { //NEW gsap.to(".box-100", { duration: 1, width: "auto", height: "auto", ease: "elastic" }); }); |
See the Pen GSAP-3-全新的動畫交錯屬性-寬高的自動擴展 by Jimmy_Wu (@Jimmy_Wu) on CodePen.
新的repeatRefresh設定(亂數定位接續)
參考資料:GSAP3-Update-10-Tips/07-new-repeatRefresh.html
相關的元素結構如下,動畫的部份主要希望使用 repeat: 5, 與 x: "random(100, 500)", 進行重新執行動畫 5 次,每一次重新執行都在原本亂數座標中接續於下一個新的亂數座標。
1 2 3 4 | <button id="btn">click</button> <div class="cube box-100 bg-red"></div> <div class="cube box-100 bg-blue"></div> <div class="cube box-100 bg-yellowgreen"></div> |
不使用 repeatRefresh: true 屬性設定,讓亂數定位會在重新都由原定位點開始
repeatRefresh: true 沒加入屬性設定,所有的亂數定位都會被由原本的起始位置跑起。
1 2 3 4 5 6 7 8 9 10 11 | const btn = document.getElementById("btn"); btn.addEventListener("click", () => { gsap.to(".cube", { duration: 1, x: "random(100, 500)", y: "+=50", stagger: 1, repeat: 5, // repeatRefresh: true // 不使用此屬性設定,會直接將定位歸 0 在重執行 }); }); |
See the Pen GSAP-3-全新的動畫交錯屬性-repeatRefresh設定(亂數定位接續)-1 by Jimmy_Wu (@Jimmy_Wu) on CodePen.
使用 repeatRefresh: true 屬性設定,讓亂數定位接續定位點開始
新的 repeatRefresh 功能會再repeat執行時,記錄當前狀態然後再執行,而不會整個重新開始。
repeatRefresh: true 沒加入屬性設定,所有的亂數定位都會被由原本的起始位置跑起。
1 2 3 4 5 6 7 8 9 10 11 | const btn = document.getElementById("btn"); btn.addEventListener("click", () => { gsap.to(".cube", { duration: 1, x: "random(100, 500)", y: "+=50", stagger: 1, repeat: 5, repeatRefresh: true }); }); |
See the Pen GSAP-3-全新的動畫交錯屬性-repeatRefresh設定(亂數定位接續)-2 by Jimmy_Wu (@Jimmy_Wu) on CodePen.
全域動畫設定
參考資料:GSAP3-Update-10-Tips/08-global-timeline.html
1 2 3 4 | <button id="stop">global stop</button> <button id="play">global play</button> <div class="cube1 box-100 bg-red"></div> <div class="cube2 box-100 bg-blue"></div> |
全局的動畫控制 & 設定如下:
- 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.
gsap.globalTimeline.timeScale() 調整全局動畫播放速度
gsap.globalTimeline.timeScale() 主要用來操作 gsap 全局動畫的方法,數值 1 會是正常播放,但如果是使用 0.5 會是慢速 0.5 倍慢播動畫,如果是設定成 0.1 時就是以 1/10 的速度播放。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | const stopbtn = document.getElementById("stop"); const playbtn = document.getElementById("play"); gsap.globalTimeline.timeScale(0.1); gsap.globalTimeline.pause(); gsap.globalTimeline.timeScale(0.1); // 全局播放速率 1 (正常播放) / 0.5 (0.5 倍數播放) gsap .timeline({ defaults: { ease: "elastic", duration: 2 } }) .to(".cube1", { x: 100 }) .to(".cube2", { y: 100 }); playbtn.addEventListener("click", () => { gsap.globalTimeline.play(); }); stopbtn.addEventListener("click", () => { gsap.globalTimeline.pause(); }); |
See the Pen GSAP-3-全新的動畫交錯屬性-全域動畫設定-2 by Jimmy_Wu (@Jimmy_Wu) on CodePen.
gsap.globalTimeline.timeScale() 主要針對的是全局動畫的速度,但如果單一的話就不要使用,
gsap.globalTimeline.paused() 檢測動畫狀態
透過 gsap.globalTimeline.paused(); 查看動畫播放的狀態, false 是播放而 true 是停止播放。
一開始可正當取得對象與播放動畫,所以使用 console.log(gsap.globalTimeline.paused()) 會回 false。
另外在停止按鈕的地方對加上 console.log(gsap.globalTimeline.paused()),當點按後會出現 <code>true。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | const stopbtn = document.getElementById("stop"); const playbtn = document.getElementById("play"); console.log(gsap.globalTimeline.paused()) gsap.globalTimeline.timeScale(0.1); gsap.globalTimeline.pause(); gsap.globalTimeline.timeScale(0.1); // 全局播放速率 1 (正常播放) / 0.5 (0.5 倍數播放) gsap .timeline({ defaults: { ease: "elastic", duration: 2 } }) .to(".cube1", { x: 100 }) .to(".cube2", { y: 100 }); playbtn.addEventListener("click", () => { gsap.globalTimeline.play(); console.log(gsap.globalTimeline.paused()) }); stopbtn.addEventListener("click", () => { gsap.globalTimeline.pause(); console.log(gsap.globalTimeline.paused()) }); |
See the Pen GSAP-3-全新的動畫交錯屬性-全域動畫設定-3 by Jimmy_Wu (@Jimmy_Wu) on CodePen.
更貼近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 也可相容運用,不過新舊寫法只能選一種,都放的話只會有一種設定。
1 2 3 4 5 6 7 8 | const btn = document.getElementById("btn"); btn.addEventListener("click", () => { gsap.to(".box-100", { duration: 1, translateX: 100, // x: 100, }); }); |
See the Pen GSAP-3-全新的動畫交錯屬性-更貼近web開發使用者屬性-1 by Jimmy_Wu (@Jimmy_Wu) on CodePen.
直接使用 css 屬性值 translateX: 50 vw 撰寫
以 css 方式撰寫程式,需要在屬性值外包 '' 成字串型態。
1 2 3 4 5 6 7 | const btn = document.getElementById("btn"); btn.addEventListener("click", () => { gsap.to(".box-100", { duration: 1, translateX: '50vw', }); }); |
See the Pen GSAP-3-全新的動畫交錯屬性-更貼近web開發使用者屬性-2 by Jimmy_Wu (@Jimmy_Wu) on CodePen.
直接使用 css 屬性值 rotate: 360_ccw (逆時轉) 與 rotate: 360_cw (順時轉)
透過 rotate: 360_ccw (逆時轉) 與 r otate: 360_cw (順時轉) 來設定屬性。
1 2 3 4 5 | <button id="rotate360_cwBtn">rotate360_cw click</button> <div class="box-100 bg-red rotate360_cw"></div> <hr> <button id="rotate360_ccwBtn">rotate360_ccw click</button> <div class="box-100 bg-red rotate360_ccw"></div> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | document.getElementById("rotate360_cwBtn") .addEventListener("click", () => { new gsap.to(".rotate360_cw", { duration: 1, rotate: "360_cw", // 順時針旋轉 }); }); document.getElementById("rotate360_ccwBtn") .addEventListener("click", () => { new gsap.to(".rotate360_ccw", { duration: 1, rotate: "360_ccw", // 逆時針旋轉 // rotation:"360_ccw", }); }); |
See the Pen GSAP-3-全新的動畫交錯屬性-更貼近web開發使用者屬性-逆順時針旋轉 by Jimmy_Wu (@Jimmy_Wu) on CodePen.
因為使用 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 箭頭函式傳向畫面做渲染,更新畫面上的座標字串。
1 2 3 4 5 6 7 8 9 10 11 12 13 | const body = document.body; const Xtxt = document.querySelector('.xTxt'); const mid = document.querySelector('.mid'); const handMoveVal = (e) => { const {x} = {pageX} = e; console.log('e => x', x); handText(x) }; const handText = (x) => { Xtxt.innerText = `X: ${x}`; } body.addEventListener('mousemove', handMoveVal); |
See the Pen GSAP-3-全新的動畫交錯屬性-新的動畫輔助工具-1 by Jimmy_Wu (@Jimmy_Wu) on CodePen.
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,以定義的基本數值的一半判斷超過後才更新畫面。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | const body = document.body; const Xtxt = document.querySelector(".xTxt"); const mid = document.querySelector(".mid"); const snap50 = gsap.utils.snap(50); // 定義 50 為數值基數 const handMoveVal = (e) => { const { x } = ({ pageX } = e); console.log("e => x", x); handText(snap50(x)); // 當傳入的 x 數值大於基數的一次就更新畫面上的數字 }; const handText = (x) => { Xtxt.innerText = `X: ${x}`; }; body.addEventListener("mousemove", handMoveVal); |
See the Pen GSAP-3-全新的動畫交錯屬性-新的動畫輔助工具-2-snap() 攔截數值或是陣列中最接近的數值 by Jimmy_Wu (@Jimmy_Wu) on CodePen.
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.
mapRange() 設定一個數字範圍及相對應換算值,將數字範圍換算成相對應換算值回傳
透過所設定的數值,轉換成一個計算範圍數值。
mapRange() 中的四個參數:
1. 0 為視窗寬度
2. window.innerWidth 視窗最右方,也就是水平座標的結位
3. 換算開始數值。
4. 換算結果最大值,設定為最右方結尾處。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | const snapRadius = gsap.utils.snap({ values: [0, window.innerWidth], radius: 100 }); const widthRange = gsap.utils.mapRange(0, window.innerWidth, 0, 1); const handMoveVal = (e) => { const { x } = ({ pageX } = e); console.log('e => x', x); handText( widthRange( snapRadius(x) ) ); }; const handText = (x) => { Xtxt.innerText = `X: ${x}`; }; body.addEventListener('mousemove', handMoveVal); |
在滑鼠右左二邊 (二邊綠色) 的 100 泛圍中間的藍色區塊才會有效果成。
See the Pen GSAP-3-全新的動畫交錯屬性-新的動畫輔助工具-4-mapRange() 設定一個數字範圍及相對應換算值,將數字範圍換算成相對應換算值回傳 by Jimmy_Wu (@Jimmy_Wu) on CodePen.
interpolate() 相似類型的任意兩個值具有多個屬性的對象製作之間線性插值,介於 0 和 1 之間
透過 .interpolate() 方法,可以將二個使用色票參數,用來換算成 0 ( '#c00' 紅色) 和 1 ( '#00c' 藍色) 的區塊,來操作色彩做變化的運算。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | const snapRadius = gsap.utils.snap({ values: [0, window.innerWidth], radius: 100 }); const widthRange = gsap.utils.mapRange(0, window.innerWidth, 0, 1); const interpolate = gsap.utils.interpolate('#c00', '#00c'); const handMoveVal = (e) => { const { x } = ({ pageX } = e); console.log('e => x', x); handText( widthRange(snapRadius(x)), // 保持 Xtxt 畫面顯示 interpolate(widthRange(snapRadius(x))) // 另外獨立用來操作指定對象 mid 的背景色彩 ); }; const handText = (x, color) => { Xtxt.innerText = `X: ${x}`; mid.style.backgroundColor = color; }; body.addEventListener('mousemove', handMoveVal); |
透過 interpolate() 執行 widthRange(snapRadius(x)) 二層的操作方法,將二個藍紅色色票所轉換的數值 0~1,透過滑鼠在水平移動時產生變化。
See the Pen GSAP-3-全新的動畫交錯屬性-新的動畫輔助工具-05-interpolate() 相似類型的任意兩個值具有多個屬性的對象製作之間線性插值,介於0和1之間 by Jimmy_Wu (@Jimmy_Wu) on CodePen.
pipe() 將多個函式調用組合,將結果傳遞到下一個函式
在 gsap.utils 工具類函式下,使用 pipe() 來串接先前所用的方法,以包多層的 interpolate(widthRange(snapRadius(x))) 執行函式部份,透過 pipe() 方法調用其他 gsap.utils 組合的函式,讓程式碼可達更直觀與更優化。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | const snapRadius = gsap.utils.snap({ values: [0, window.innerWidth], radius: 100 }); const widthRange = gsap.utils.mapRange(0, window.innerWidth, 0, 1); const interpolate = gsap.utils.interpolate('#c00', '#00c'); const pipe = gsap.utils.pipe( snapRadius, widthRange, interpolate ); // pipe 串接前三個方法,調用後帶入參數連續執行 const handMoveVal = (e) => { const { x } = ({ pageX } = e); console.log('e => x', x); handText( widthRange(snapRadius(x)), // interpolate(widthRange(snapRadius(x))) pipe(x) // pipe() 方法將傳入的 x 一入傳到底,將調用多接的三個方法一路貫穿執行 ); }; const handText = (x, color) => { Xtxt.innerText = `X: ${x}`; mid.style.backgroundColor = color; }; body.addEventListener('mousemove', handMoveVal); |
See the Pen GSAP-3-全新的動畫交錯屬性-新的動畫輔助工具-06-pipe() 將多個函式調用組合,將結果傳遞到下一個函式 by Jimmy_Wu (@Jimmy_Wu) on CodePen.
其他備註
關於基本語法中的屬性值,如果是遇到有連字號 ( -) 的樣式屬性,則需要使用 JavaScript 的「駝峰式大小寫命名法 (Camel Case)」,例如 backgroundSize、backgroundImage、clipPath 等。
GSAP 動畫函式庫,主要是用來操作補間動畫 (Tween animation),透過 GSAP 官方文件介紹,主要以 Tweens 與 Timelines 二個方法操作補間動畫。
相關資源
- Mike Cheng Youtube
- 竹白記事本:GSAP3-專門處理動畫與特效的 JS 套件