F16▸A007▸framer-motion
Typewriter
打字機效果
難度 ★★★★★標籤 文字 · 打字 · setInterval2 min read
效果簡述
文字一個字一個字「打」出來,像終端機。Hero 區放一句 catchphrase 很對味。 JS 一個 setInterval 就解決,不用裝額外套件。
Claude Code Prompt
參考:A007 typewriter
技術:useState + setInterval 切片顯示
具體行為:
- const [shown, setShown] = useState('')
- setInterval 每 50~70ms 把 i+=1,shown = text.slice(0, i)
- 結尾停下,清掉 interval
- 文字尾巴加閃爍 caret(一個 span animate-pulse)
限制:
- 速度 50~70ms 最像打字機,再快變胡亂
- 中文字寬度比英文大,要留高度避免 layout shift
- 不要長句(超過 30 字會嫌煩)完整程式碼
'use client'
import { useEffect, useState } from 'react'
const text = '你好,我用 Next.js 做網站。'
export function Typewriter() {
const [shown, setShown] = useState('')
useEffect(() => {
let i = 0
const id = setInterval(() => {
i += 1
setShown(text.slice(0, i))
if (i >= text.length) clearInterval(id)
}, 55)
return () => clearInterval(id)
}, [])
return (
<p className="font-mono text-lg">
{shown}
<span className="ml-0.5 inline-block h-5 w-[2px] animate-pulse bg-current align-middle" />
</p>
)
}何時用
- ✅ Hero 區短句
- ✅ 終端機風格 demo
- ✅ AI 對話介面(mock loading)
何時別用
- ❌ 重要 SEO 文字(爬蟲拿到空字串)
- ❌ 長段落(讀者不耐煩)
- ❌ 多語切換頻繁的站(i18n 換字會重打)
我踩過的坑
-
沒 cleanup setInterval 切頁會 leak:return () => clearInterval(id) 一定要。
-
沒預留高度 layout shift:第一個 frame 是空字串,整段高度突然 撐開。用 min-height 預留。
-
中英混排 caret 對不齊:caret 高度抓字級的 1em 左右,
align-middle看起來最穩。
相關效果
- F15 Char Reveal — 整段一起淡入,不打字