F24▸A009▸framer-motion
Flip Words
句中單字輪替
難度 ★★★★★標籤 文字 · AnimatePresence · 輪替3 min read
效果簡述
句子中有一個關鍵字會輪替成不同詞彙。「我用 [設計 / 工程 / 故事] 說話。」
Aceternity / Magic UI 都有的招牌。靠 AnimatePresence + mode="wait"
做進退場。
用設計說話。
Claude Code Prompt
參考:A009 flip words
技術:framer-motion AnimatePresence mode="wait"
具體行為:
- setInterval 1.5~2 秒輪 i
- <AnimatePresence mode="wait"> 內裝 motion.span key={words[i]}
- initial y: 24, opacity 0, filter blur(8px) → animate 0/1/blur(0) → exit y: -24
- 父層 inline-block + min-width 避免 layout shift
限制:
- 詞長度差太多會抖(中文還算穩)
- 一句中最多 1 個 flip word
- duration 0.4 ~ 0.5 太快讀不到、太慢拖完整程式碼
'use client'
import { AnimatePresence, motion } from 'framer-motion'
import { useEffect, useState } from 'react'
const words = ['設計', '工程', '動畫', '故事']
export function FlipWords() {
const [i, setI] = useState(0)
useEffect(() => {
const id = setInterval(() => setI((v) => (v + 1) % words.length), 1800)
return () => clearInterval(id)
}, [])
return (
<div className="flex gap-2 text-3xl">
<span>用</span>
<span className="relative inline-block min-w-[3.5em]">
<AnimatePresence mode="wait">
<motion.span
key={words[i]}
initial={{ y: 24, opacity: 0, filter: 'blur(8px)' }}
animate={{ y: 0, opacity: 1, filter: 'blur(0px)' }}
exit={{ y: -24, opacity: 0, filter: 'blur(8px)' }}
transition={{ duration: 0.45 }}
className="absolute left-0"
>
{words[i]}
</motion.span>
</AnimatePresence>
</span>
<span>說話。</span>
</div>
)
}何時用
- ✅ Hero tagline 多面向品牌
- ✅ 顧客類型輪播(給 X / 給 Y / 給 Z)
- ✅ 功能輪換展示
何時別用
- ❌ 重要資訊(會錯過)
- ❌ SEO 必要關鍵字(爬蟲只抓第一個)
- ❌ 詞長度差很多(layout 跳動)
我踩過的坑
-
沒 min-width 句子寬度跳:英文詞長度差更大。設個 min-width 給最寬的詞用。
-
mode="wait" 必須:不寫的話新舊詞重疊出現,看起來像 bug。
-
filter blur 行動裝置喘:可移除 filter,僅留 y + opacity。
相關效果
- F16 Typewriter — 打字機式漸進
- F17 Blur to Clear — blur 進場