G08▸T101▸gsap
Page Transition
頁面轉場
難度 ★★★★★標籤 transition · page · overlay3 min read
效果簡述
切頁時用色塊從下方掃上來覆蓋舊頁、再掃出去揭示新頁。Next App Router + view transitions API 也能做,但 GSAP 的好處是可完全自訂時間。
Home 頁
Claude Code Prompt
參考:T101 page transition
技術:fixed overlay 元素 + gsap timeline
具體行為:
- overlay div fixed inset-0,預設 translateY 100%
- click 切頁:tl.to(overlay, { y: '0%', duration: 0.4 }).add(() => router.push(href)).to(overlay, { y: '-100%', delay: 0.05 }).set(overlay, { y: '100%' })
- 用 ease: 'power3.inOut'
限制:
- Next 13+ 用 router.push 不會自動 fade
- 一定要 set 回 100% 不然下次看不到
- overlay 蓋住 click target,要 pointer-events-none 預設完整程式碼
'use client'
import gsap from 'gsap'
import { useRef } from 'react'
export function PageTransition() {
const overlay = useRef<HTMLDivElement>(null)
function transition(after: () => void) {
const el = overlay.current
if (!el) return
const tl = gsap.timeline()
tl.set(el, { y: '100%' })
.to(el, { y: '0%', duration: 0.4, ease: 'power3.inOut' })
.add(after)
.to(el, { y: '-100%', duration: 0.4, ease: 'power3.inOut', delay: 0.05 })
.set(el, { y: '100%' })
}
return (
<>
<button onClick={() => transition(() => console.log('switch'))}>Go</button>
<div ref={overlay} className="pointer-events-none fixed inset-0 z-50 bg-orange-600" style={{ transform: 'translateY(100%)' }} />
</>
)
}何時用
- ✅ 品牌站 / 作品集切頁
- ✅ Hero → 內頁 大型轉場
- ✅ Modal 開啟的進場感
何時別用
- ❌ 高頻切頁(內容站、後台)
- ❌ 已經有 view transitions API 在用的站
- ❌ 必須立刻看到內容的頁(會延遲 0.5 秒)
我踩過的坑
-
沒 pointer-events-none 蓋住底下 click:transition 結束後 overlay 還在 layout 裡,但要設 pointer-events-none 不擋互動。
-
沒 reset y: 100% 第二次看不到:tl 結束時必須回到出發位置。
-
跟 router transition 衝突:Next 16 / App Router 已經有自己的 navigation events。確保 GSAP 的 timing 跟 router.push 同步。
相關效果
- G12 Flip Layout — 同頁內變換的另一選擇