WebberUI

Text Morph

兩段文字間的平滑變形過渡——相同字元滑移到新位置,不同字元淡出淡入,支援自動輪播與受控切換。

載入預覽⋯

Playground

即時調整 props、程式碼片段同步更新——直接試出你要的樣子再複製。

3
0.5
10
<TextMorph />

安裝

npx shadcn@latest add https://webberui.com/r/text-morph.json

或在 components.json 設定 registries 後,改用 @webberui/text-morph 安裝。

安裝依賴後,從 registry JSON(/r/text-morph.jsonfiles[0].content)複製 text-morph.tsx 原始碼到你的 components/ui/ 目錄:

npm install motion clsx tailwind-merge

使用

import { TextMorph } from "@/components/ui/text-morph";

// 自動輪播(預設每 3 秒)
<TextMorph
  texts={["Build faster.", "Ship sooner."]}
  className="text-4xl font-bold"
/>

// 受控模式:由外部狀態決定顯示哪一段
const [index, setIndex] = useState(0);
<TextMorph texts={plans} index={index} interval={0} />

Props

Prop型別預設值說明
textsstring[]要循環變形的文字清單(至少一項)
indexnumber受控模式:目前顯示的文字索引(自動對長度取模)
defaultIndexnumber0非受控模式的初始索引
onIndexChange(index: number) => void索引即將變化時回呼(自動輪播與受控切換皆觸發)
intervalnumber3自動輪播間隔(秒);設為 0 停用
durationnumber0.5單次變形動畫時長(秒)
ynumber10新舊字元進出場的垂直位移(px)
blurbooleantrue進出場是否附帶模糊
caseSensitivebooleanfalse字元比對是否區分大小寫;falseH 會滑移成 h
pauseOnHoverbooleantrue滑鼠懸停時暫停自動輪播

細節

  • 字元比對:每個字素依「字元 + 第 n 次出現」產生穩定 key,新舊文字共有的字元由 Motion layout 動畫平滑滑移到新位置,其餘字元向上飄出、自下方進場,形成「變形」而非整段換頁的效果
  • 字素切割:以 Intl.Segmenter 切割 grapheme,emoji、旗幟、中文組合字不會被拆壞
  • 受控/非受控雙模式:傳入 index 即為受控;自動輪播在兩種模式下都會透過 onIndexChange 通知下一個索引,受控端可自行決定是否採納
  • 計時器管理:輪播計時器在 unmount、hover 暫停與參數變更時皆正確清理,不會殘留

可及性

  • 使用者系統開啟「減少動態效果」時,文字照常輪替但直接切換,不做變形動畫
  • 動畫層對輔助科技隱藏(aria-hidden),另以 sr-only 提供目前完整文字,朗讀時是完整句子而非零碎字元
  • 預設 pauseOnHover 讓使用者能停下輪播閱讀;若內容重要,建議搭配受控模式提供明確的切換控制

On this page