G05▸A105▸gsap
Timeline Sequence
時間軸序列動畫
難度 ★★★★★標籤 timeline · sequence · gsap3 min read
效果簡述
多個元素「按順序、有重疊地」進場,是 GSAP 最招牌的用法。Framer 用 variants 也行,但要編排複雜順序時 GSAP timeline 簡單太多。
標題:時間軸進場
副標題接著出現
CTA
Claude Code Prompt
參考:A105 timeline sequence
技術:gsap.timeline()
具體行為:
- const tl = gsap.timeline()
- tl.from('.a', { y: 20, opacity: 0, duration: 0.5 })
- .from('.b', { y: 20, opacity: 0, duration: 0.5 }, '-=0.2') // 重疊 0.2 秒
- .from('.bar', { width: 0, duration: 0.8 }, '-=0.3')
- 用 gsap.context cleanup
限制:
- 用 .from 比 .to 直觀(最終狀態用 CSS 寫好)
- position 參數用 '-=0.2' 比寫絕對時間清晰
- 一條 timeline 不要超過 8 個動作完整程式碼
'use client'
import gsap from 'gsap'
import { useEffect, useRef } from 'react'
export function TimelineSequence() {
const root = useRef<HTMLDivElement>(null)
useEffect(() => {
const ctx = gsap.context(() => {
const tl = gsap.timeline()
tl.from('.tl-1', { y: 20, opacity: 0, duration: 0.5 })
.from('.tl-2', { y: 20, opacity: 0, duration: 0.5 }, '-=0.2')
.from('.tl-3', { scale: 0.8, opacity: 0, duration: 0.5 }, '-=0.2')
.from('.tl-bar', { width: 0, duration: 0.8, ease: 'power2.out' }, '-=0.3')
}, root)
return () => ctx.revert()
}, [])
return (
<div ref={root}>
<h2 className="tl-1">標題</h2>
<p className="tl-2">副標</p>
<button className="tl-3">CTA</button>
<div className="tl-bar h-1 w-full bg-orange-600" />
</div>
)
}何時用
- ✅ Hero 區複合進場(多個元素有節奏)
- ✅ Onboarding 步驟動畫
- ✅ Modal 開啟序列
何時別用
- ❌ 只有 1~2 個元素(殺雞用牛刀)
- ❌ 每個都要不同條件 / 互動觸發(用獨立 tween)
- ❌ 進場後就不會再播的小元素(CSS 就夠)
我踩過的坑
-
沒 ctx.revert() 在 React 重新 mount 會疊加:第二次 mount 會有兩條 timeline,動畫疊加變鬼影。
-
-=0.2跟0.2意思差很多:前者重疊 0.2 秒,後者是絕對 時間點 0.2 秒。最常搞混。 -
.from 動畫初始狀態會閃:第一個 frame 是「最終狀態」。 用
immediateRender: false或 set 初始狀態。
相關效果
- G09 SplitText Char by Char — 用 stagger 達成 sequence
- F04 Staggered List — Framer 版的 stagger