Shader Waves
流體波動背景:以逐像素的多層正弦波場(軟體著色器)算出流動漸層,可選滑鼠跟隨、噪點與多款配色。
載入預覽⋯
Playground
即時調整 props、程式碼片段同步更新——直接試出你要的樣子再複製。
1
1
128
<ShaderWaves />
安裝
npx shadcn@latest add https://webberui.com/r/shader-waves.json或在 components.json 設定 registries 後,改用 @webberui/shader-waves 安裝。
安裝依賴後,打開 shader-waves.json,把 files[0].content 的內容複製到你的 components/ui/shader-waves.tsx:
npm install motion clsx tailwind-merge使用
前景內容直接放進 children,佈局(如置中、高度)寫在 className 上:
import { ShaderWaves } from "@/components/ui/shader-waves";
<ShaderWaves className="flex min-h-[400px] items-center justify-center">
<h1 className="text-4xl font-bold text-white">Hero 標題</h1>
</ShaderWaves>切換配色款式、開啟滑鼠跟隨與噪點,並放慢流動:
<ShaderWaves
variant="sunset"
interactive
grain
speed={0.6}
className="flex h-[320px] items-center justify-center rounded-2xl"
>
<p className="text-lg text-white">暖色系流體</p>
</ShaderWaves>以自訂色停覆蓋內建配色(由暗到亮排列效果最佳):
<ShaderWaves
colors={["#0b1120", "#6366f1", "#ec4899", "#f9a8d4"]}
scale={1.4}
/>Props
| Prop | 型別 | 預設值 | 說明 |
|---|---|---|---|
variant | "aurora" | "sunset" | "ocean" | "mono" | "aurora" | 內建配色款式 |
colors | string[] | — | 自訂漸層色停(2 色以上),指定後覆蓋 variant |
speed | number | 1 | 流動速度倍率;0 或負值回退為 1 |
scale | number | 1 | 波紋尺度,越大波形越舒展、數量越少 |
resolution | number | 128 | 內部運算緩衝的長邊像素數,越低越柔和、效能越好(24–240) |
interactive | boolean | false | 波場輕微跟隨滑鼠(僅滑鼠指標生效,觸控不作用) |
grain | boolean | false | 疊加低透明度噪點,減少大面積漸層的色帶感 |
children | React.ReactNode | — | 前景內容,疊在波動之上 |
className | string | — | 附加到最外層容器的 class |
細節
- 軟體著色器:逐像素波場。 在一張長邊僅
resolution像素的離屏緩衝上,用多層正弦波加上座標域扭曲(domain warping)逐像素算出流動場,再以imageSmoothing平滑放大貼回主畫布——低解析度運算搭配放大插值,天然形成柔化的流體感,成本可控 - 波動場映射到一張 256 階的 RGB 查找表(由
variant或colors的色停烘焙),逐像素上色時只需一次陣列查找,避免每格重算漸層 - 主畫布依
devicePixelRatio(上限 2×)配置背板尺寸,ResizeObserver監看容器尺寸變化即時重新配置緩衝 - 背景層整層
pointer-events-none並以-z-10沉到內容之下(容器有isolate建立獨立堆疊上下文),前景互動完全不受影響 - 噪點是內嵌
feTurbulenceSVG 的 data URI,無額外網路請求,以 180px 平鋪、低透明度疊在波動之上 - 未使用 WebGL 或任何第三方套件,僅以 Canvas 2D 逐像素運算實現,安裝後零額外相依
可及性
- 背景為裝飾性內容,容器背景層帶
aria-hidden,不干擾輔助科技朗讀 interactive開啟時,游標位置正規化為 -1 ~ 1,經每幀插值平滑後輕微偏移波場;只在pointerType === "mouse"時作用,觸控裝置不受影響- 使用者系統開啟「減少動態效果」時,停止
requestAnimationFrame迴圈與滑鼠跟隨,只渲染單一幀靜態波紋,DOM 結構不變