Joseph Chen
你有沒有注意到,打開我的個人網頁時,頁面上的元素不是「突然出現」,而是從下方滑入、逐漸淡出?滾動到某個區塊時,卡片一張一張延遲出現?
這些全都來自 Framer Motion。它的設計哲學很簡單:把動畫寫成 props,不是 CSS keyframes。
這篇帶你從基礎到實際用法,全部都是我的網頁裡真實出現的動畫。
1. motion 元件 — 最基本的概念
Framer Motion 的用法是把原本的 HTML 元素換成 motion. 版本:
換成 motion.div 之後,原本 div 的所有行為都保留,只是多了動畫 props 可以用。
import { motion } from 'framer-motion';2. initial + animate — 進場動畫
initial 是元件出現前的狀態,animate 是最終狀態。Framer Motion 自動補間兩者之間的動畫。
淡入(fade in)
效果預覽(重新整理頁面可看到)
從下方滑入(最常用)
效果預覽(可點「重播」)
從左方滑入
| 常用屬性 | 說明 | 典型值 |
|---|---|---|
| opacity | 透明度 | 0 → 1 |
| y | 垂直位移(正 = 往下) | 20 → 0 或 -20 → 0 |
| x | 水平位移(正 = 往右) | -30 → 0 或 30 → 0 |
| scale | 縮放 | 0.8 → 1 |
| rotate | 旋轉角度 | 90 → 0 |
3. transition — 控制動畫節奏
transition 控制動畫的時間、緩動和延遲:
delay 的妙用:讓元素「逐一出現」
我的 blog/page.tsx 裡的每個系列卡片,用 index × 0.1 製造錯開效果,讓卡片一張一張依序出現,而不是全部同時跳出:
4. whileInView — 滾動觸發動畫
animate 是頁面載入時立刻播放。但我更常用 whileInView:等到元素滾動進入視窗時才觸發動畫。
這讓使用者滾動到任何區塊都有「內容飛入」的感覺,而不是一開始全部動完之後就靜止了。
- once: true — 滾動到時播放一次,往上捲再回來不重播(推薦)
- once: false(預設) — 每次進出視窗都重播,通常太吵
我的每一篇文章頁面都大量使用 whileInView,讓讀者越往下滾、內容越活躍:
5. whileHover / whileTap — 互動反饋
除了進場動畫,Framer Motion 還能處理 hover 和點擊的微互動,讓按鈕、卡片有「按下去」的手感:
試試看 — 滑鼠移上去、點一下
type: "spring" 是彈簧緩動,比一般 easeOut 更有彈性、更自然。stiffness(彈簧硬度)越高越快,damping(阻尼)越高越少回彈。stiffness: 400, damping: 17 是我最喜歡的組合,快速且稍微回彈一下。6. AnimatePresence — 離場動畫
正常的 React 元件消失時是瞬間消失的。AnimatePresence 讓元件可以有「離場動畫」,等動畫播完才真正從 DOM 移除:
展開/收起 demo
完整案例:我的首頁動畫架構
把以上學到的全部組合起來,這是我的首頁 Hero 區塊的完整動畫寫法: