DotMatrixWave
neon-ui/dot-matrix-waveFreeComponent
Field of dots breathing in a drifting noise wave, colored by currentColor. The RegionSelect dot-map aesthetic as a background surface.
Install it
npx shadcn@latest add https://ui.neon.com/r/dot-matrix-wave.jsonSource
1"use client";23/*4 * DotMatrixWave: a field of dots breathing in a smooth noise wave,5 * the RegionSelect dot-map aesthetic, generalized into a background6 * surface. Color comes from currentColor at mount (same contract as7 * NeonLoader and AnimatedWash), so a text-primary ancestor or the8 * theme drives it with zero props; pass a colors array for a9 * left-to-right gradient fade instead, like the neon.com green-to-10 * blue type treatment. Static single frame under reduced motion.11 * The GLSL lives in dot-matrix-wave-shader.ts.12 */1314import { useEffect, useMemo, useRef } from "react";15import type { ComponentProps } from "react";1617import { cn } from "@/lib/utils";1819import { DOT_FRAGMENT, DOT_VERTEX } from "./dot-matrix-wave-shader";2021export type DotMatrixWaveProps = Omit<ComponentProps<"canvas">, "children"> & {22 /** Wave drift speed multiplier; 0 freezes the field. */23 speed?: number;24 /** Dot pitch in CSS pixels. */25 gap?: number;26 /** 0-1 dot radius as a share of the pitch. */27 dotSize?: number;28 /** 0-1 how hard the wave swells the dots. */29 amplitude?: number;30 /** 0-1 minimum brightness of resting dots. */31 floor?: number;32 /**33 * Gradient stops spread evenly left to right, up to 6. Omit to34 * paint the whole field with currentColor.35 */36 colors?: string[];37};3839const MAX_STOPS = 6;4041/**42 * Seconds for a dial change to close ~63% of its gap — uniforms ease43 * toward their targets each frame, so a dragged slider glides44 * instead of snapping.45 */46const SMOOTH_TAU = 0.12;4748const parseColor = (css: string): [number, number, number] => {49 const probe = document.createElement("canvas");50 probe.width = 1;51 probe.height = 1;52 const context = probe.getContext("2d");5354 if (!context) {55 return [0, 0.9, 0.6];56 }5758 context.fillStyle = css;59 context.fillRect(0, 0, 1, 1);60 const [r, g, b] = context.getImageData(0, 0, 1, 1).data;61 return [(r ?? 0) / 255, (g ?? 0) / 255, (b ?? 0) / 255];62};6364const warnDev = (message: string) => {65 if (typeof process !== "undefined" && process.env.NODE_ENV !== "production") {66 console.warn(message);67 }68};6970const compile = (71 gl: WebGLRenderingContext,72 type: number,73 source: string74): WebGLShader | null => {75 const shader = gl.createShader(type);7677 if (!shader) {78 return null;79 }8081 gl.shaderSource(shader, source);82 gl.compileShader(shader);8384 if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {85 warnDev(86// … truncated
What it pulls in
Other registry items
Files it writes
More from neon-ui
All 77 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| ActivityFeedactivity-feed | neon-ui | Components | Free | 2 deps | |
| AgentChatagent-chat | neon-ui | Components | Free | 6 deps | |
| AnimatedWashanimated-wash | neon-ui | Components | Free | no deps · 2 files | |
| ApiKeyListapi-key-list | neon-ui | Components | Free | 2 deps | |
| AppCardapp-card | neon-ui | Components | Free | 2 deps | |
| AppCreatorapp-creator | neon-ui | Components | Free | 2 deps | |
| AuthFormauth-form | neon-ui | Components | Free | no deps | |
| AutoscaleChartautoscale-chart | neon-ui | Components | Free | 1 dep |
