Gsap-常見的基本方法

懶人包。

gsap.to()

設定動畫結束時的屬性。也就是說開始時的屬性會以原本 CSS 設定的屬性為主,例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import { useEffect } from 'react'
import { gsap } from 'gsap'

function App() {
useEffect(() => {
// 選到 .square 這個元素
gsap.to('.square', {
x: 300, // translateX(300px)
duration: 1
})
}, [])

return (
<div className='App'>
<div className='wrapper'>
<div className='square'></div>
</div>
</div>
)
}

export default App

example1gsap.to

如果我想自己控制動畫的播放/暫停之類的話怎麼辦?

基本上 gsap 大部分的 API 都會回傳一個「Tween」,直翻的話會翻成「補間動畫」,但我自己是理解成這段動畫的 instance,覺得這樣比較好懂一點。

所以剛剛的範例可以改寫成這樣:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import { useEffect } from 'react'
import { gsap } from 'gsap'

function App() {
useEffect(() => {
// 把 instance 存起來
const tween = gsap.to('.square', {
x: 300,
duration: 1,
paused: true // 用暫停來取消自動播放
})

// 透過按鈕 + 監聽器來控制動畫的播放與倒放
document.querySelector('.play-btn')!.addEventListener('click', () => {
tween.play()
})
document.querySelector('.reverse-btn')!.addEventListener('click', () => {
tween.reverse()
})
}, [])

return (
<div className='App'>
<div className='wrapper'>
<div className='square'></div>
</div>
<button className='btn play-btn'>Start</button>
<button className='btn reverse-btn'>Reverse</button>
</div>
)
}

export default App

example1-use-tween

我想要「按照順序」來播放動畫

如果單用 gsap.to() 的話可以透過 delay 來設定延遲時間,不過當動畫很複雜的時候也許你會想用 timeline 來處理,這個後面會在介紹,先不用太在意。

假設我們想實現這個效果:

附註:先往右邊移動後再往下移動。

example1-delay

那就能這樣子設定:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import { useEffect } from 'react'
import { gsap } from 'gsap'

function App() {
function demo() {
gsap.to('.square', {
x: 300,
duration: 1
})
gsap.to('.square', {
y: 300,
delay: 1,
duration: 1
})
}

return (
<div className='App'>
<div className='wrapper'>
<div className='square'></div>
</div>
<button className='btn' onClick={demo}>
Start
</button>
</div>
)
}

export default App

gsap.from()

gsap.to 反過來的意思,這邊是決定動畫開始時的屬性,動畫結束時會回到原本在 CSS 設定的屬性。

example2-gsap-from

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import { useEffect } from 'react'
import { gsap } from 'gsap'

function App() {
function demo() {
gsap.from('.square', {
x: 300,
duration: 1
})
}

return (
<div className='App'>
<div className='wrapper'>
<div className='square'></div>
</div>
<button className='btn' onClick={demo}>
Start
</button>
</div>
)
}

export default App

gsap.fromTo()

當你不想要依據原本的 CSS 屬性來做動畫時,就可以直接用 gsap.fromTo() 來決定動畫開始與結束時的屬性:

example3-gsap-fromTo

附註:注意原本的位置在最前面,但按下 Start 後是動畫會從我們設定的位置開始,而不是原本 CSS 給的位置。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import { gsap } from 'gsap'

function App() {
function demo() {
gsap.fromTo(
'.square',
{
x: 300,
duration: 1
},
{
x: 600,
duration: 1
}
)
}

return (
<div className='App'>
<div className='wrapper'>
<div className='square'></div>
</div>
<button className='btn' onClick={demo}>
Start
</button>
</div>
)
}

export default App

gsap.timeline()

gsap.timeline() 會回傳一個自動幫你處理「順序」的時間軸物件。

舉例來說如果想實作這樣的效果:

example4-sequence

一個比較直覺的做法是透過 delay 來設定延遲時間,來實現「等 A 跑完後再跑 B」的效果,所以這邊 code 會長這樣:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import { gsap } from 'gsap'

function App() {
function demo() {
gsap.to('.square1', {
x: 300,
duration: 1,
ease: 'none'
})
gsap.to('.square2', {
x: 300,
duration: 1,
delay: 1, // delay 1 秒後才執行
ease: 'none'
})
}

return (
<div className='App'>
<div className='wrapper'>
<div className='square square1'></div>
<div className='square square2'></div>
</div>
<button className='btn' onClick={demo}>
Start
</button>
</div>
)
}
export default App

老實說這樣的做法沒什麼問題,唯一的缺點就是要計算每一個動畫的延遲時間還蠻麻煩的而已。

但如果用 gsap.timeline 來改寫的話會輕鬆許多:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import { gsap } from 'gsap'

function App() {
function demo() {
// new 一個時間軸的 instance(只是一種修飾法,不是真的 new)
const timeline = gsap.timeline()
timeline
// 第一段動畫
.to('.square1', {
duration: 1,
x: 300,
ease: 'none'
})
// 第二段動畫
.to('.square2', {
duration: 1,
x: 300,
ease: 'none'
})
}

return (
<div className='App'>
<div className='wrapper'>
<div className='square square1'></div>
<div className='square square2'></div>
</div>
<button className='btn' onClick={demo}>
Start
</button>
</div>
)
}

export default App

出來的結果是一模一樣的:

example4-sequence

用時間軸的好處很明顯,就是你只要把按照順序去 call 對應的 function 就好,timeline 會自動幫我們搞定好延遲的問題。

位置參數(position parameter)

想要更精確的控制時間軸的話,可以加上第三個參數來做控制。詳細的部分可以參考 官方文件

1. 在時間軸的起始位置插入秒數(也可以想成時延遲秒數的意思)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import { gsap } from 'gsap'

function App() {
function demo() {
const timeline = gsap.timeline()
timeline.to(
'.square1',
{
duration: 1,
x: 300,
ease: 'none'
},
2 // 插入 2 秒
)
}

return (
<div className='App'>
<div className='wrapper'>
<div className='square square1'></div>
</div>
<button className='btn' onClick={demo}>
Start
</button>
</div>
)
}

export default App
jk

example5-timeline-position-parameter

2. 插入到前一個時間軸的起始點,換句話說就是「跟上一個時間軸同步」

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import { gsap } from 'gsap'

function App() {
function demo() {
const timeline = gsap.timeline()
timeline.to('.square1', {
duration: 1,
x: 300,
ease: 'none'
}),
timeline.to(
'.square2',
{
duration: 1,
x: 300,
ease: 'none'
},
'<' // 插入到前一個時間軸的起始點
)
}

return (
<div className='App'>
<div className='wrapper'>
<div className='square square1'></div>
<div className='square square2'></div>
</div>
<button className='btn' onClick={demo}>
Start
</button>
</div>
)
}

export default App

example6-timeline-position-parameter

3. 插入到前一個時間軸的終點,其實就跟預設值一樣,會「依照順序」來執行。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import { gsap } from 'gsap'

function App() {
function demo() {
const timeline = gsap.timeline()
timeline.to('.square1', {
duration: 1,
x: 300,
ease: 'none'
}),
timeline.to(
'.square2',
{
duration: 1,
x: 300,
ease: 'none'
},
'>' // 插入到前一個時間軸的終點
)
}

return (
<div className='App'>
<div className='wrapper'>
<div className='square square1'></div>
<div className='square square2'></div>
</div>
<button className='btn' onClick={demo}>
Start
</button>
</div>
)
}

export default App

example7-timeline-position-parameter

Gsap-ScrollTrigger Gsap-context 與 revert(寫 React 的必備知識)
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×