GSAP3:專門處理動畫與特效的 JS 套件
本站不會更新了
新家網址:https://chupai.github.io/
文章:https://chupai.github.io/posts/200229_gsap3/
這週是 w3HexSchool 第四週,之前沒碰過 TweenMax,但 gsap 已經升級 GSAP3,就簡單研究一下 GSAP3。
GSAP3
GSAP 是 GreenSock Animation Platform 的簡稱,是一套專門處理動畫與特效的 JS 套件。
GSAP 採用模塊化與插件式的結構,保持了核心引擎的輕量。有四個核心 API,TweenLite、TimelinLite、TimelineMax、TweenMax,而 TweenMax 是所有 API 與 Plugin 的集合。
但 2019年底 GSAP 從 GSAP2 升級到 GSAP3,不再區分 TweenLite、TimelinLite、TimelineMax、TweenMax,全部合並為 gsap 物件。
GSAP3 的優點:
- 檔案大小為 TweenMax 的一半,但新增了 50多個功能。
- 全部合並為 gsap 物件,不用在區分 TweenLite 和 TimelineMax 物件。
- 新版本相容舊版本寫法,所以可以沿用,新寫法提供更好的可讀性。
官網:
下載安裝
npm install gsap
// or
yarn add gsap
CDN
https://cdnjs.cloudflare.com/ajax/libs/gsap/3.1.1/gsap.min.js
版本差異
1. gsap 物件
原本須要用 Tweens(補間),就要使用 TweenLite/TweenMax 物件。要用到 Timelines(時間軸),就要使用 TimelineLite/TimelineMax 物件。
GSAP3 統一使用 gsap 物件。gsap 物件,具有各種方法和屬性,可用來創建 Tweens(補間)和 Timelines(時間軸)。
舊的 Tween 的創建方式:
TweenMax.method('selector', {});
// or
TweenLite.method('selector',{});
現在統一使用 gsap 物件:
gsap.method('selector', {});
舊的 Timeline 的創建方式:
const tl = new TimelineMax();
tl.method('selector', {});
// or
const tl = new TimelineLite();
tl.method('selector', {});
現在 Timeline 一樣也只需要使用 gsap 物件:
const tl = gsap.timeline();
tl.method('selector', {});
2. duration
參數
原來的寫法 duration
為方法的參數:
TweenMax.to('.box', 1, { x: 100 });
新寫法被整合到了 vars
物件中了:
gsap.to('.box', {
duration: 1,
x: 100,
});
擁有更佳的可讀性。
3. Timeline 預設值
原本的 Timeline 寫法:
const t = new TimelineMax();
t.to('.box1', 1, {
x: 100,
ease: 'elastic'
}).to('.box2', 1, {
y: 100,
ease: 'elastic'
});
使用新的寫法,如有有相同的參數,可以設定預設值:
const t = gsap.timeline({
defaults: {
duration: 1,
ease: 'elastic'
}
});
t.to('.box1', { x: 100 })
.to('.box2', { y: 100 });
4. 交錯屬性
原本交錯動畫,要使用到額外的方法創建 Tween 實體,例如staggerTo()
、staggerFrom()
、staggerFromTo()
:
TweenMax.staggerTo('.box', 1, {rotation:360, x:100}, 0.5);
現在只需要設置 stagger
屬性即可:
gsap.to('.box', {
duration: 1,
stagger: 0.5,
rotation: 360,
x: 100
});
5. 全新的亂數功能
1 ~ 400 之間:
gsap.to('.box', {
x: 'random(100, 400)',
});
隨機選擇一個數字,可以使用陣列表示:
gsap.to('.box', {
x: 'random([0,100,400,500])',
});
6. 全新的影格功能 Keyframes
大家一定都知道 CSS 動畫的 keyframes
。那 GSAP 中的 keyframes
是什麼?
原本要建立一連串的動畫(例如,先移動,再下移,最後旋轉),需要為每個動作建立 Tween 或使用 Timeline。而 keyframes
可以在同一個 Tween 內完成。
gsap.to('.box', {
keyframes: [
{ duration: 1, x: 100, },
{ duration: 1, y: 100 },
{ duration: 1, rotation: 360 },
]
});
7. 全新的 repeatRefresh
開啟 repeatRefresh: true
,會在重複執行時(設定 repeat
),紀錄當前狀態再執行,而不會回到初始狀態。
gsap.to('.box', {
duration: 1,
repeat: 5,
repeatRefresh: true,
x: 'random(100, 400)',
});
8. 全新的全域動畫
Global timeline 可以控制全部的動畫實體。
gsap.globalTimeline.timeScale(0.1); // 控制所有動畫的速率 0 ~ 1
gsap.globalTimeline.pause(); // 停止目前所有動畫
gsap.globalTimeline.play(); // 播放目前所有動畫
gsap.globalTimeline.paused(); // 回傳目前動畫狀態 true:暫停 / false:播放
9. 新的動畫輔助工具
gsap.utils.checkPrefix()
gsap.utils.clamp()
gsap.utils.distribute()
gsap.utils.getUnit()
gsap.utils.interpolate()
gsap.utils.mapRange()
gsap.utils.normalize()
gsap.utils.pipe()
gsap.utils.random()
gsap.utils.snap()
gsap.utils.splitColor()
gsap.utils.toArray()
gsap.utils.unitize()
gsap.utils.wrap()
gsap.utils.wrapYoyo()
10. 相對動畫時間
原本會需要標籤來添加相對動畫時間:
gsap.timeline()
.add('s')
.to('.box1', { ... }, 's')
.to('.box2', { ... }, 's')
.to('.box3', { ... }, 's+=0.8')
.to('.box4', { ... }, 's+=0.8');
GSAP3 新增了最近的動畫時間:
-
>
:最近添加的動畫的開始時間 -
<
:最近添加的動畫的結束時間
gsap.timeline()
.to('.box1', { ... })
.to('.box2', { ... }, '<')
.to('.box3', { ... }, '<0.8')
.to('.box4', { ... }, '<');
補間動畫 Tween
補間是 flash 時代的專業詞彙,意思是在起始狀態和終點狀態之間補全中間過程。
包含四個要素:
- 動畫目標(target)
- 起始狀態
- 終點狀態
- 補間效果
1. 創建 Tween
創建 Tween 的常用方法(所有這些方法都會回傳 Tween 實體):
參數說明:
-
target
:需要動畫的元素-
target
使用document.querySelectorAll()
,所有符合的 CSS 選擇器都會是設置動畫的對象。 - 如果有多個元素對象,則使用陣列
[element1, element2]
-
-
vars
:設置補間效果及屬性狀態
Timeline
Timeline 就是「時間軸」,可以用來控制、管理一連串的動畫。
- 控制多段動畫 / 序列動畫
- 自由與重疊排序
- 添加 Tag 掌握動畫片段
舉例來說,我們要對多個元素作一連串的動畫,需要建立多個 Tween 並用 delay
設置延遲時間,非常麻煩:
gsap.to('.box1', { duration: 1, x: 100, });
gsap.to('.box2', { delay: 1, duration: 1, y: 100 });
gsap.to('.box1', { delay: 2, duration: 1, rotation: 360 });
而且還無法對這一連串的動畫做控制。點我看範例。
這時候可以使用 Timeline,建立一個時間軸,來管理這些動畫。
const t1 = gsap.timeline();
t1.to('.box1', { duration: 1, x: 100, })
.to('.box2', { duration: 1, y: 100 })
.to('.box1', { duration: 1, rotation: 360 });
如果有相同動畫狀態,可以設定預設值,使程式碼更簡潔:
const t1 = gsap.timeline({
defaults: {
duration: 1,
},
});
t1.to('.box1', { x: 100, })
.to('.box2', { y: 100, })
.to('.box1', { rotation: 360, });
1. 在時間軸中放置動畫
在時間軸建立動畫:
to()
from
fromTo
set()
const tl = gsap.timeline();
tl.to(element, {duration: 1, x: 100, opacity: 0.5});
Timeline 可以鏈式呼叫:
const tl = gsap.timeline();
tl.from(element, {duration: 1, x: -100})
.to(element, {duration: 1, y: 50});
在時間軸中,加入一段已建立的動畫,使用 add()
:
const tween = tween = gsap.to(element, {duration: 1, x: 100, opacity: 0.5});
const tl = gsap.timeline();
tl.add(tween);
Timeline 許多方法都多 position
參數,可用來控制動畫插入點:
- 無設置:時間軸末尾
-
1
:絕對時間,指定時間處 -
'+=1'
、-=1
:相對時間,相對於時間軸的結尾 -
'someLabel'
:指定標籤處(建立標籤使用addLabel()
) -
‵someLabel+=1'
、‵someLabel-=1'
:相對於指定標籤 -
<
:最近動畫的開頭 -
>
:最近動畫的結尾 -
<1
、<-1
:相對於最近動畫的開頭 -
>1
、>-1
:相對於最近動畫的結尾
// 插入至時間軸末尾
tl.to(element, 1, {});
// 插入至時間軸2秒處
tl.to(element, 1, {}, 2);
// 在時間軸結束後2秒鐘插入
tl.to(element, 1, {}, '+=2');
// 在時間軸結束前2秒鐘插入
tl.to(element, 1, {}, '-=2');
// 在3秒處建立spin標籤
t1.addLabel('spin', 3);
// 在spin標籤處插入動畫
tl.to(element, 1, {}, 'spin');
// 在spin標籤處前三秒入動畫
tl.to(element, 1, {}, 'spin+=3');
// 在最近一次動畫的開頭插入
tl.to(element, {x: 100}, '<');
// 在最近一次動畫的開始後1秒插入
tl.to(element, {x: 100}, '<1');
基本用法
1. 數字動畫 0~100
最基本的用法,對物件的屬性去做變化。
2. CSS 動畫
3. 動畫控制
-
.play()
:播放動畫 -
.pause()
:暫停動畫播放 -
.paused()
:獲取或設置動畫暫停狀態-
myAnimation.paused(!myAnimation.paused())
暫停動畫切換
-
-
.resume()
:繼續動畫播放 -
.restart()
:重新開始動畫 -
.reverse()
:反轉播放動畫 -
.reversed()
:獲取或設置動畫反轉狀態-
myAnimation.reversed( !myAnimation.reversed() )
動畫撥放方向切換。
-
-
.seek()
:不改變狀態下,跳至動畫某個時間點
4. 重複撥放、來回撥放
repeat: 10, // 設置動畫重複次數
repeatDelay: 0.5, // 設置重複的間隔時間(秒)
yoyo: true, // 設為true時,動畫會反轉重複
5. 錯開動畫
stagger: 0.5, // 設置錯開時間
6. 週期
GSAP2 的 cycle
屬性,被 GSAP3 的 gsap.utils.wrap()
給取代,而且更加靈活。