動態字體排印
材質填字
大字以程序生成的材質填滿(木紋、拉絲金屬、紙張噪點、大理石、鐳射箔),自動輪播或滑過時交叉淡接切換並掃過一道高光,不載入任何外部材質圖。
把標題文字當成一塊材料來呈現。文字本身透明,底下疊著五種以 CSS 漸層與內嵌 SVG feTurbulence 噪點即時生成的材質層——木紋、拉絲金屬、紙張、大理石、鐳射箔——透過 background-clip: text 只露出字形。切換時新材質交叉淡入、紋理同時往前滑一小段,再掃過一道斜向高光,像燈光掠過實物表面。可自動輪播、滑過切換,或交給受控的 material 決定;換一個 seed 就換一組紋理。
把這個效果裝進你的專案
在專案資料夾執行指令,CLI 會加入原始碼與依賴套件,再依下方使用範例引用元件。
npx webberui@latest add material-fill-textPlayground
即時調整 props、程式碼片段同步更新——直接試出你要的樣子再複製。
2200
7
編輯中的呼叫預設屬性
<MaterialFillText/>
完整範例包含預覽的排版與資料。先安裝元件,再把範例檔貼入你的專案。
安裝
npx webberui@latest add https://webberui.com/r/material-fill-text.json或在 components.json 設定 registries 後,改用 @webberui/material-fill-text 安裝。
使用
import { MaterialFillText } from "@/components/ui/material-fill-text";
// 自動輪播五種材質
<MaterialFillText className="text-8xl font-black tracking-tight">
質地
</MaterialFillText>
// 滑過切換下一種,只用其中三種材質
<MaterialFillText mode="hover" materials={["metal", "foil", "wood"]}>
CRAFT
</MaterialFillText>
// 受控:由外部按鈕決定材質
const [material, setMaterial] = React.useState<MaterialFillKind>("marble");
<MaterialFillText mode="manual" material={material} onMaterialChange={setMaterial}>
石與木
</MaterialFillText>Props
| Prop | 型別 | 預設值 | 說明 |
|---|---|---|---|
children | string | — | 要以材質填滿的文字(純字串;每一層材質都會疊一份同樣的字) |
materials | MaterialFillKind[] | ["wood", "metal", "paper", "marble", "foil"] | 參與輪播的材質與順序;第一個也是減少動態效果時停留的材質 |
material | MaterialFillKind | — | 受控模式的目前材質;未提供時由元件內部管理(非受控) |
defaultMaterial | MaterialFillKind | materials[0] | 非受控模式的初始材質 |
onMaterialChange | (material: MaterialFillKind) => void | — | 材質切換時回呼(自動輪播與 hover 切換都會觸發) |
mode | "auto" | "hover" | "manual" | "auto" | auto 定時輪播、hover 滑入時切下一個、manual 只依受控 material 切換 |
interval | number | 2200 | auto 模式的輪播間隔(毫秒);未提供時讀取 --wb-material-fill-interval |
sheen | boolean | true | 切換時讓一道斜向高光帶掃過文字一次(600ms) |
seed | number | 7 | 程序噪點的亂數種子,換一個數字就換一組紋理 |
as | "h1" | "h2" | "p" | "span" | "h2" | 根元素標籤 |
className | string | — | 透傳到根元素;字級、字重由這裡決定(預設 text-6xl font-black tracking-tight) |
MaterialFillKind
| 欄位 | 型別 | 預設值 | 說明 |
|---|---|---|---|
"wood" | string | — | 木紋:多層不同角度的棕色條紋,加上拉長的 feTurbulence 噪點 |
"metal" | string | — | 拉絲金屬:1px 灰階細紋與斜向高光帶 |
"paper" | string | — | 紙張:紙色底加 fractalNoise 細噪點 |
"marble" | string | — | 大理石:turbulence 噪點經 feColorMatrix 轉成脈紋 |
"foil" | string | — | 鐳射箔:多彩 conic-gradient,滑過時色光位移 |
細節
- 結構:一層透明的真文字負責排版、選取與朗讀,上方每種材質各疊一層同樣的字(
absolute對齊、aria-hidden),目前材質的層opacity: 1、其他為 0。 - 節奏可用 CSS 變數覆寫:
--wb-material-fill-duration(交叉淡接,預設450ms)與--wb-material-fill-interval(輪播間隔,預設2200ms;intervalprop 優先)。 - 噪點以
data:image/svg+xml字串在元件內組出,不引用任何外部網址;字串組合是確定性的,伺服器與瀏覽器輸出一致。 - 每種材質都有亮、暗兩組配色:亮底用較深的版本(深木、深鋼、牛皮紙、黑大理石),暗色模式(
dark:)改用提亮的版本,確保字與背景有足夠對比。 - 文字捲出視窗時自動暫停輪播;受控的
auto模式會等父層回寫material後才排下一次切換。 - 材質字是為大標設計的視覺效果,請只用在大字級的標題;內文與小字請維持一般文字顏色。
可及性
- 真文字層保留在 DOM 中,可正常選取、複製,並由螢幕閱讀器朗讀一次;所有材質層與高光層都設
aria-hidden,不會重複朗讀 - 強制色彩模式(Windows 高對比)下材質層隱藏,真文字改用系統文字色,內容不會消失
- 動態切換屬於裝飾效果,不承載資訊;若材質名稱有意義,請像示範一樣在旁邊以文字顯示
- 使用者系統開啟「減少動態效果」時,停在第一種材質,不輪播、不掃高光,
mode="hover"也不切換;manual受控模式仍會顯示指定材質,但直接切換、不做淡接