Dotted Grid
vault-hyperiux/dotted-gridFreeComponent
Canvas 2D fullscreen dot grid that autonomously cycles through five geometric shapes (star, square, circle ring, plus, triangle). Mouse cursor creates a dark shrinking head effect and leaves a glowing blue trail that lingers and fades.
Install it
npx shadcn@latest add https://vault.hyperiux.com/r/dotted-grid.jsonSource
1// Built using Hyperiux Vault: https://vault.hyperiux.com23"use client";45import { useEffect, useRef, useSyncExternalStore } from "react";6import { createSuspendedRaf } from "./createSuspendedRaf";78const REDUCED_MOTION_QUERY = "(prefers-reduced-motion: reduce)";910function subscribeToReducedMotion(callback: () => void) {11 if (typeof window === "undefined") return () => {};12 const mediaQueryList = window.matchMedia(REDUCED_MOTION_QUERY);13 mediaQueryList.addEventListener("change", callback);14 return () => mediaQueryList.removeEventListener("change", callback);15}1617function getReducedMotionSnapshot(): boolean {18 return window.matchMedia?.(REDUCED_MOTION_QUERY)?.matches ?? false;19}2021function getServerReducedMotionSnapshot(): boolean {22 return false;23}2425// React hook form, for JSX output that depends on the preference (not just26// the imperative reduceMotion flag already used inside the draw loop below).27// Safe to call during render - returns false on the server.28function usePrefersReducedMotion() {29 return useSyncExternalStore(30 subscribeToReducedMotion,31 getReducedMotionSnapshot,32 getServerReducedMotionSnapshot33 );34}353637const DEFAULT_SPACING = 24;38const DEFAULT_BASE_RADIUS = 7.2;39const DEFAULT_MOUSE_RADIUS = 380;40const DEFAULT_TRAIL_LENGTH = 456;41const DEFAULT_TRAIL_RADIUS = 230;42const DEFAULT_TRAIL_FADE_MS = 1200;4344const RANDOM_TIME = 0.6;45const COLLECT_TIME = 1.1;46const SHAPE_HOLD_TIME = 1.2;47const GRAY_DISPERSE_TIME = 0.9; // trail lingers ~2s4849const TOTAL_CYCLE_TIME = RANDOM_TIME + COLLECT_TIME + SHAPE_HOLD_TIME + GRAY_DISPERSE_TIME;50const TOTAL_SHAPES = 5;515253const lerp = (a: number, b: number, t: number): number => a + (b - a) * t;54const clamp01 = (v: number): number => Math.max(0, Math.min(1, v));55const smoothstep = (e0: number, e1: number, v: number): number => {56 const t = clamp01((v - e0) / (e1 - e0));57 return t * t * (3 - 2 * t);58};5960const getStarStrength = (x: number, y: number, time: number, width: number, height: number): number => {61 const cx = width / 2;62 const cy = height / 2;63 const scale = Math.min(width, height) * 0.28;6465 const nx = (x - cx) / scale;66 const ny = (y - cy) / scale;6768 const r = Math.sqrt(nx * nx + ny * ny);69 const angle = Math.atan2(ny, nx);7071 const spikes = 5;72 const star = Math.cos(spikes * angle);73 const radius = 0.55 + 0.25 * star;7475 return clamp01(1 - smoothstep(radius - 0.05, radius + 0.05, r));76};7778const getSquareStrength = (x: number, y: number, width: number, height: number): number => {79// … truncated
More from vault-hyperiux
All 120 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| 3D Portfolio Slider3d-portfolio-slider | vault-hyperiux | Components | Free | 3 deps | |
| Animated FAQanimated-faq | vault-hyperiux | Components | Free | 2 deps | |
| Animated Formanimated-form | vault-hyperiux | Components | Free | 1 dep | |
| Animated Modalanimated-modal | vault-hyperiux | Components | Free | 1 dep | |
| Tabsanimated-tabs | vault-hyperiux | Components | Free | 1 dep | |
| Animated Toggleanimated-toggle | vault-hyperiux | Components | Free | no deps | |
| Aperture Transitionaperture-transition | vault-hyperiux | Components | Free | 2 deps | |
| Arrow Fill Buttonarrow-fill-button | vault-hyperiux | Components | Free | 1 dep |
