HalftoneBloom
neon-ui/halftone-bloomFreeComponent
Halftone ring field revealed by soft drifting color blooms: teal and amber light behind a punched-metal screen.
Install it
npx shadcn@latest add https://ui.neon.com/r/halftone-bloom.jsonSource
1"use client";23/*4 * HalftoneBloom: a punched-metal halftone screen revealed by soft5 * drifting color lights. The default rig recreates the heritage6 * background (cool teal left, warm amber right overexposing toward7 * cream); pass a custom lights array to recreate any of the neon.com8 * pattern strips or your own rig. Transparent outside the lit rings,9 * so it works over dark and light surfaces alike. Static single frame10 * under reduced motion. The GLSL lives in halftone-bloom-shader.ts.11 */1213import { useEffect, useMemo, useRef } from "react";14import type { ComponentProps } from "react";1516import { cn } from "@/lib/utils";1718import { BLOOM_FRAGMENT, BLOOM_VERTEX } from "./halftone-bloom-shader";1920export interface BloomLight {21 /** Light color. */22 color: string;23 /** 0-1 anchor across the width. */24 x: number;25 /** 0-1 anchor up from the bottom. */26 y: number;27 /** Light radius as a share of the width. */28 radius?: number;29 /** Brightness gain. */30 intensity?: number;31 /** 0-1 pull toward the highlight color at the hottest cells. */32 overexpose?: number;33}3435export type HalftoneBloomProps = Omit<ComponentProps<"canvas">, "children"> & {36 /** Light drift speed multiplier; 0 freezes the field. */37 speed?: number;38 /** Cell pitch in CSS pixels. */39 gap?: number;40 /** 0-1 punched-hole radius as a share of the cell. */41 holeSize?: number;42 /** Hole offset from the cell center, in cell units. */43 holeOffset?: [number, number];44 /** Overall brightness multiplier. */45 intensity?: number;46 /** 0-1 how far lights wander from their anchors. */47 drift?: number;48 /** The overexposed highlight color. */49 highlight?: string;50 /** The light rig, up to 6 lights. */51 lights?: BloomLight[];52};5354const MAX_LIGHTS = 6;5556const DEFAULT_HOLE_OFFSET: [number, number] = [-0.09, -0.09];5758const DEFAULT_LIGHTS: BloomLight[] = [59 { color: "#1d5e57", radius: 0.25, x: 0.06, y: 0.9 },60 { color: "#1d5e57", intensity: 0.95, radius: 0.21, x: 0.42, y: 0.05 },61 {62 color: "#c4692e",63 intensity: 1.6,64 overexpose: 1,65 radius: 0.27,66 x: 0.92,67 y: 0.45,68 },69 {70 color: "#c4692e",71 intensity: 1.1,72 overexpose: 1,73 radius: 0.19,74 x: 0.78,75 y: 0.08,76 },77];7879/**80 * Seconds for a dial change to close ~63% of its gap — uniforms ease81 * toward their targets each frame, so a dragged slider glides82 * instead of snapping.83 */84const SMOOTH_TAU = 0.12;8586const parseColor = (css: string): [number, number, number] => {87// … 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 |
