文字動畫
Scramble Text
亂碼快速輪轉、由左至右逐字定型的解密文字動畫,支援視口與 hover 觸發。
把這個效果裝進你的專案
在專案資料夾執行指令,CLI 會加入原始碼與依賴套件,再依下方使用範例引用元件。
npx webberui@latest add scramble-textPlayground
即時調整 props、程式碼片段同步更新——直接試出你要的樣子再複製。
0.05
編輯中的呼叫預設屬性
<ScrambleText/>
完整範例包含預覽的排版與資料。先安裝元件,再把範例檔貼入你的專案。
安裝
npx webberui@latest add https://webberui.com/r/scramble-text.json或在 components.json 設定 registries 後,改用 @webberui/scramble-text 安裝。
使用
import { ScrambleText } from "@/components/ui/scramble-text";
<ScrambleText
text="WEBBERUI DECRYPTED"
className="font-mono text-4xl font-bold"
/>hover 重播模式,中英混合也沒問題:
<ScrambleText text="Hover 我:解密動畫" trigger="hover" duration={0.04} />自訂亂碼字元集(例如駭客風的 0 和 1):
<ScrambleText text="BINARY MODE" charset="01" className="font-mono" />首屏就是亂碼(SSR 安全),文字更新時讓讀屏播報真文字:
<ScrambleText text={status} initialScrambled live="polite" />Props
| Prop | 型別 | 預設值 | 說明 |
|---|---|---|---|
text | string | — | 目標文字,中文與 emoji 皆可 |
duration | number | 0.05 | 每個字元定型的間隔(秒),越小解密越快 |
charset | string | 英數+符號 | 亂碼輪轉使用的字元集 |
trigger | "view" | "hover" | "view" | 進入視口自動播放,或滑鼠懸停時重播 |
once | boolean | true | trigger="view" 時,只在第一次進入視口播放 |
initialScrambled | boolean | false | 首次渲染(含 SSR)就顯示確定性 hash 亂碼而非答案,伺服器與瀏覽器輸出一致 |
live | "off" | "polite" | "assertive" | "off" | 讀屏用真文字的 aria-live 等級;off 不加 aria-live |
細節
- 核心是單一
requestAnimationFrame迴圈:依經過時間計算已定型的字元數(由左至右每duration秒多鎖定一個),未定型位置每 2 幀從charset抽一個新亂碼,避免逐幀閃爍太刺眼。動畫直接寫入 DOM 文字節點,不觸發 React re-render;unmount 或重播時都會取消前一個 rAF - 以
Intl.Segmenter做字素切割,中文、emoji、組合字都算一個單位;定型時直接鎖定原始字元,所以中文目標文字一樣正常運作,亂碼輪轉則一律使用charset - 空白字元不參與亂碼,行寬與斷行在動畫過程中保持穩定
- 字寬抖動:亂碼輪轉時各字元寬度不同,畫面會左右跳動。建議搭配
font-mono(等寬字型),或至少在數字為主的場景加上tabular-nums;目標文字含中文時,中英字寬差異讓抖動更明顯,等寬字型效果最好 - 可及性:完整文字放在
sr-only,動畫層標記aria-hidden,螢幕閱讀器永遠讀到完整句子而不是亂碼;使用者系統開啟「減少動態效果」時直接顯示最終文字,不播動畫 initialScrambled:預設首次渲染輸出的是答案本身(trigger="view"時以透明度隱藏到進入視口)。開啟後首次渲染改輸出亂碼,亂碼由「字素內容+位置」算 FNV-1a hash 對應到charset,不用Math.random,所以伺服器與瀏覽器產生同一串字、不會 hydration 不一致;首屏已是亂碼、不會洩漏答案,因此 view 模式也不再先隱藏。搭配trigger="hover"時文字會維持亂碼直到第一次滑鼠移入live:真文字放在sr-only層,live="polite"或"assertive"會在該層加上aria-live,text變更時讀屏只播報一次完整的新文字,亂碼層維持aria-hidden不會被念出once={false}搭配trigger="view"時,離開視口再進入會重播;trigger="hover"則是靜態顯示文字,每次滑鼠移入都重新解密一次