文字動畫

Handwriting Text

以 SVG pathLength 逐筆描繪的手寫文字動畫,內建單線字型,也支援自訂簽名路徑。

這是 WebberUI Pro 元件

下方的安裝指令需要授權才能執行,未授權時會回 401。

怎麼安裝 Pro 元件 →查看方案 →

把這個效果裝進你的專案

在專案資料夾執行指令,CLI 會加入原始碼與依賴套件,再依下方使用範例引用元件。

npx webberui@latest add "https://webberui.com/r/handwriting-text.json?t=<安裝 token>"

還沒有專案,或安裝遇到問題?看快速開始 →

Playground

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

0.7
0.18
5
0
編輯中的呼叫預設屬性
<HandwritingText/>

完整範例包含預覽的排版與資料。先安裝元件,再把範例檔貼入你的專案。

安裝

npx webberui@latest add "https://webberui.com/r/handwriting-text.json?t=<安裝 token>"

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

使用

傳入 text,會以內建單線字型逐筆描繪(文字自動轉為大寫):

import { HandwritingText } from "@/components/ui/handwriting-text";

<HandwritingText text="Webber" className="text-5xl font-medium" />

若要描繪簽名或花體,改傳 paths(SVG 路徑 d 陣列)並搭配 viewBox:

<HandwritingText
  paths={["M10 66 C 24 20 40 22 42 60 …", "M6 90 C 90 76 200 76 262 88"]}
  viewBox="0 0 272 100"
  label="手寫簽名"
/>

節奏與手動觸發

totalDuration 指定整段描繪的總長,元件會把 duration 與 stagger 等比縮放,筆畫之間的相對快慢不變;easing 可傳 cubic-bezier() 字串、四元數組或 motion 具名緩動。trigger="manual" 時由 play 控制開始,搭配遞增 key 就能做出「重播」:

const [play, setPlay] = React.useState(false);
const [replayKey, setReplayKey] = React.useState(0);

<button type="button" onClick={() => setPlay(true)}>
  <HandwritingText
    key={replayKey}
    text="Hello"
    trigger="manual"
    play={play}
    totalDuration={2.8}
    easing="cubic-bezier(0.2,0.2,0.8,0.9)"
    delay={0.2}
    onComplete={() => console.log("done")}
  />
</button>
<button type="button" onClick={() => setReplayKey((k) => k + 1)}>重播</button>

Props

Prop型別預設值說明
textstring—要描繪的文字,以內建單線字型渲染(自動轉大寫);與 paths 二擇一
pathsstring[]—自訂 SVG 路徑(d 字串陣列),提供時取代 text
viewBoxstring"0 0 100 100"paths 模式的 viewBox;text 模式會自動計算
labelstring—paths 模式提供給輔助科技的文字說明
durationnumber0.7單一筆畫描繪時長(秒)
staggernumber0.18相鄰筆畫開始的間隔(秒)
delaynumber0整體開始前的延遲(秒)
easing[number, number, number, number] | "cubic-bezier(…)" | "linear" | "easeIn" | "easeOut" | "easeInOut"[0.22, 1, 0.36, 1]筆畫緩動;建議的手寫節奏為 "cubic-bezier(0.2,0.2,0.8,0.9)",字串無法解析時退回預設
totalDurationnumber—整段描繪的總時長(秒),依 duration/stagger 比例等比縮放;建議 2.8。不傳則各筆畫照 duration 計時
playbooleanfalsetrigger 為 manual 時是否描繪;true 開始、false 收回
onComplete() => void—最後一筆畫描繪完成時呼叫;loop 時不觸發
strokeWidthnumber5線寬(viewBox 單位)
fillbooleanfalse描繪完成後淡入填色,適合封閉路徑;loop 時忽略
loopbooleanfalse是否循環重繪
trigger"view" | "hover" | "mount" | "manual""view"觸發時機;manual 由 play 控制
oncebooleantruetrigger 為 view 時,只在第一次進入視口播放
classNamestring—外層容器;text 模式以 font-size 控制尺寸,paths 模式以寬度控制
svgClassNamestring—直接套用到 <svg>,可覆寫預設尺寸類別

細節

  • 尺寸:text 模式的 <svg> 高度為 1em,用 text-5xl 之類的字級類別即可縮放;paths 模式寬度撐滿容器,用外層寬度控制大小。
  • 顏色:描邊使用 currentColor,直接用 text-neutral-* 等文字色類別上色即可,深淺色主題各自設定。
  • 單線字型:內建 A–Z、0–9 與常見標點,字母皆為大寫;每個字符拆成數筆畫並依書寫順序描繪。未收錄的字符會以空白間距處理。
  • 循環:loop 開啟時各筆畫共用相同週期,重繪時仍保持原本的錯位順序,不會亂序閃動。
  • 觸發:trigger="hover" 時容器可聚焦(tabIndex=0),滑鼠移入或鍵盤 focus 都會重新描繪。
  • pathLength 標準化:每條路徑的 pathLength 都被標準化為 1,虛線長度以 0–1 計算、與路徑實際長度無關,因此長短不一的筆畫能共用同一組時間參數。
  • 總時長:totalDuration 只縮放時間,不改變筆畫順序與錯位比例;delay 不計入總時長。

可及性

  • trigger="manual" 不綁任何按鍵;要「按空白鍵開始」時,把元件放在原生 <button> 裡,空白鍵與 Enter 會由瀏覽器觸發 click。
  • text 模式下容器帶 role="img" 與 aria-label,並保留一份 sr-only 文字供螢幕報讀。
  • paths 模式請透過 label 提供文字說明;未提供 text 也未提供 label 時,整體以 aria-hidden 對輔助科技隱藏。
  • 使用者系統開啟「減少動態效果」時,直接顯示描繪完成的靜態成品,不播放動畫。