WebberUI

Interactive Dot Grid

互動點陣背景:滿版規則點陣,游標附近的點放大並被斥力推開,離開後平滑回位。

載入預覽⋯

Playground

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

28
1.5
120
<InteractiveDotGrid />

安裝

npx shadcn@latest add https://webberui.com/r/interactive-dot-grid.json

或在 components.json 設定 registries 後,改用 @webberui/interactive-dot-grid 安裝。

安裝依賴後,打開 interactive-dot-grid.json,把 files[0].content 的內容複製到你的 components/ui/interactive-dot-grid.tsx

npm install motion clsx tailwind-merge

使用

元件會填滿具尺寸的父層,前景內容以絕對定位疊在其上;讓覆蓋層帶 pointer-events-none,游標事件才會落到點陣上:

import { InteractiveDotGrid } from "@/components/ui/interactive-dot-grid";

<div className="relative h-[400px] overflow-hidden rounded-2xl">
  <InteractiveDotGrid />
  <div className="pointer-events-none absolute inset-0 flex items-center justify-center">
    <h2 className="text-2xl font-semibold">移動游標看點陣互動</h2>
  </div>
</div>

調整密度、影響範圍與顏色:

<InteractiveDotGrid gap={36} dotRadius={2} influence={160} color="#38bdf8" />

Props

Prop型別預設值說明
gapnumber28點與點的間距(px),同時決定點的密度
dotRadiusnumber1.5靜止時每個點的半徑(px)
influencenumber120游標影響半徑(px):此範圍內的點才會放大並被推開
colorstring淺色 neutral-400 / 深色 neutral-600點的顏色;未指定時隨主題切換
classNamestring附加到最外層容器的 class

細節

  • 單一 canvas 繪製。 整個點陣畫在一張 <canvas> 上,ResizeObserver 取容器尺寸並依 devicePixelRatio(上限 2×)調整背景緩衝區,避免高解析度螢幕模糊
  • 斥力越近越強。 每幀對每個點計算與游標的距離,落在 influence 內時取 1 - dist / influence 為強度,據此沿反向推開(最多約 influence 的 35%)並放大半徑
  • 平滑回位。 游標座標與整體影響強度都以插值追隨目標,游標離開容器後強度衰減回 0,點陣自然回到基準位置
  • 閒置省能。 動畫靜止且點陣回到基準後,rAF 迴圈只保留輕量插值計算而略過繪製,游標再次進入時自動喚醒
  • 顏色隨主題。 未指定 color 時,canvas 以 currentColortext-neutral-400 dark:text-neutral-600)取色,並用 MutationObserver 監看 <html> 的 class 變化,深淺主題切換即時重繪
  • 只有滑鼠指標(pointerType === "mouse")會觸發互動,觸控不作用

可及性

  • 點陣為純裝飾背景,最外層帶 aria-hidden,不干擾輔助科技朗讀前景內容
  • 使用者系統開啟「減少動態效果」時,只繪製靜態點陣、不啟動動畫迴圈、不回應游標
  • 元件卸載時清理 rAF、ResizeObserverMutationObserver,不留下背景計時器

On this page