Aurora Backdrop
loomui/aurora-backdropFreeComponent
A wash of blurred colour that drifts behind content on cycles that never line up.
Live preview
live · rendered by the registry
Rendered by loomui on their own page — this is the component running, not a screenshot of it.Install it
npx shadcn@latest add https://loomui.design/r/aurora-backdrop.jsonSource
1"use client"23import * as React from "react"45import { cn } from "@/lib/utils"6import { useInViewport } from "@/registry/lib/use-in-viewport"78export interface AuroraBackdropProps extends React.ComponentProps<"div"> {9 /** Colours of the drifting blobs. One blob is drawn per colour. */10 colors?: string[]11 /** Blur applied to the whole wash, as a CSS length. */12 blur?: string13 /** Seconds for one full drift of a single blob. */14 duration?: number15 /** Opacity of the layer, from `0` to `1`. */16 intensity?: number17 /** Changes where the blobs sit. Same seed, same layout, every render. */18 seed?: number19 /** Render the wash static. */20 disabled?: boolean21}2223const DEFAULT_COLORS = ["#2dd4bf", "#38bdf8", "#3b82f6", "#a78bfa"]2425/** Mulberry32. Deterministic so the server and the client agree. */26function createRandom(seed: number) {27 let state = seed >>> 028 return () => {29 state = (state + 0x6d2b79f5) >>> 030 let t = state31 t = Math.imul(t ^ (t >>> 15), t | 1)32 t ^= t + Math.imul(t ^ (t >>> 7), t | 61)33 return ((t ^ (t >>> 14)) >>> 0) / 429496729634 }35}3637export function AuroraBackdrop({38 colors = DEFAULT_COLORS,39 blur = "72px",40 duration = 18,41 intensity = 0.5,42 seed = 1,43 disabled = false,44 className,45 style,46 ...props47}: AuroraBackdropProps) {48 const blobs = React.useMemo(() => {49 const palette = colors.length > 0 ? colors : DEFAULT_COLORS50 const random = createRandom(seed)5152 return palette.map((color, index) => ({53 key: index,54 color,55 // Well under the container, so the drift is a blob crossing the frame56 // rather than a full-bleed wash shifting a few percent.57 size: 38 + random() * 32,58 x: random() * 100,59 y: random() * 100,60 // Every blob runs the same keyframes at a different length and phase.61 // Cycles that never line up are what stops the wash reading as a loop.62 duration: duration * (0.75 + random() * 0.6),63 delay: -random() * duration,64 }))65 }, [colors, seed, duration])6667 const root = React.useRef<HTMLDivElement>(null)68 // Large blurred gradients are the most expensive thing here to keep drifting69 // for a viewport nobody is looking at.70 const onScreen = useInViewport(root)7172 return (73 <div74 ref={root}75 data-slot="aurora-backdrop"76 aria-hidden="true"77 className={cn(78 "pointer-events-none absolute inset-0 overflow-hidden",79 className80 )}81 style={{ opacity: intensity, ...style }}82 {...props}83// … truncated
What it pulls in
Other registry items
Files it writes
More from loomui
All 91 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Bento Gridbento-grid | loomui | Components | Free | no deps | |
| Card Stackcard-stack | loomui | Components | Free | no deps | |
| Compare Slidercompare-slider | loomui | Components | Free | no deps | |
| Confetti Buttonconfetti-button | loomui | Components | Free | no deps | |
| Count Upcount-up | loomui | Components | Free | no deps | |
| Credit Cardcredit-card | loomui | Components | Free | no deps | |
| Drawerdrawer | loomui | Components | Free | 1 dep | |
| Elastic Tabselastic-tabs | loomui | Components | Free | no deps |
