ComponentsMagneticBeamsBackground
MagneticBeamsBackground
Add grid beams that follow the pointer.
On this page
Use this component from the local workspace package. Follow the setup guide first. A public npm package and registry are not available yet.
View registry filesImport the component into your page or component file.
import { MagneticBeamsBackground } from "@dethink/components";Try the examples, then open the code to use them in your app. The background fills its container; these previews bound it with a height utility.
Hero composition
Move the pointer over the preview: beams converge toward it along their rails, and resume their traversal from that point when the pointer leaves.
A hero that leans in when you do
The beams spring toward your pointer while it hovers, then pick their traversal back up from wherever they are when it leaves.
Show sourceexamples/magnetic-beams-background/basic.tsx
"use client";
import { Badge, Button, MagneticBeamsBackground } from "@dethink/components";
export function MagneticBeamsBackgroundBasic() {
return (
<MagneticBeamsBackground
className="border-border h-[24rem] rounded-lg border"
tone="primary"
>
<div className="flex h-[24rem] flex-col items-center justify-center gap-4 px-6 text-center">
<Badge tone="primary" variant="soft">
Move your pointer
</Badge>
<h2 className="text-foreground max-w-xl text-3xl font-semibold tracking-tight">
A hero that leans in when you do
</h2>
<p className="text-muted-foreground max-w-md text-sm leading-6">
The beams spring toward your pointer while it hovers, then pick their
traversal back up from wherever they are when it leaves.
</p>
<div className="flex gap-3">
<Button>Get started</Button>
<Button variant="outline">View docs</Button>
</div>
</div>
</MagneticBeamsBackground>
);
}Modes, variants, and interactive={false}
Every visual axis is a literal token-backed variant. mode switches how beams approach the pointer: magnetic springs onto it, follow travels there at the normal loop speed. interactive={false} keeps the plain traversal loop.
Show sourceexamples/magnetic-beams-background/variants.tsx
"use client";
import { MagneticBeamsBackground } from "@dethink/components";
export function MagneticBeamsBackgroundVariants() {
return (
<div className="grid gap-4 sm:grid-cols-2">
<MagneticBeamsBackground
className="border-border h-48 rounded-lg border"
density="dense"
seed={3}
speed="fast"
tone="foreground"
>
<div className="flex h-48 items-end p-4">
<span className="text-muted-foreground text-xs font-medium">
tone="foreground" · dense · fast · magnetic
</span>
</div>
</MagneticBeamsBackground>
<MagneticBeamsBackground
className="border-border h-48 rounded-lg border"
mode="follow"
seed={7}
tone="primary"
>
<div className="flex h-48 items-end p-4">
<span className="text-muted-foreground text-xs font-medium">
mode="follow" · beams travel to the pointer at loop speed
</span>
</div>
</MagneticBeamsBackground>
<MagneticBeamsBackground
className="border-border h-48 rounded-lg border"
interactive={false}
seed={5}
tone="muted"
>
<div className="flex h-48 items-end p-4">
<span className="text-muted-foreground text-xs font-medium">
interactive={false} · plain traversal
</span>
</div>
</MagneticBeamsBackground>
<MagneticBeamsBackground
className="border-border h-48 rounded-lg border"
density="sparse"
intensity="bold"
seed={9}
speed="slow"
tone="primary"
>
<div className="flex h-48 items-end p-4">
<span className="text-muted-foreground text-xs font-medium">
tone="primary" · sparse · bold · slow
</span>
</div>
</MagneticBeamsBackground>
</div>
);
}Static frame
animate={false} — and any user with a reduced-motion preference — gets this composition: no loops or attraction mounted, still designed.
Designed at rest
animate={false} renders the same frame reduced-motion users see: the grid plus two frozen beam segments, no loops or pointer attraction mounted.
Show sourceexamples/magnetic-beams-background/static.tsx
"use client";
import { MagneticBeamsBackground } from "@dethink/components";
export function MagneticBeamsBackgroundStatic() {
return (
<MagneticBeamsBackground
animate={false}
className="border-border h-56 rounded-lg border"
tone="primary"
>
<div className="flex h-56 flex-col items-center justify-center gap-2 px-6 text-center">
<h3 className="text-foreground text-xl font-semibold">
Designed at rest
</h3>
<p className="text-muted-foreground max-w-sm text-sm leading-6">
animate={"{false}"} renders the same frame reduced-motion users see:
the grid plus two frozen beam segments, no loops or pointer
attraction mounted.
</p>
</div>
</MagneticBeamsBackground>
);
}MagneticBeamsBackground accepts div props plus the shared background contract — animate, density, intensity, speed, tone, and seed — and adds interactive and mode for the pointer attraction.
| Prop | What it does | Default |
|---|---|---|
animateboolean | Set to false to force the static composition regardless of OS motion preference: the grid plus two frozen beam segments, with no animation loops or pointer attraction mounted. | true |
interactiveboolean | Enables pointer attraction: while the pointer hovers the component, each beam springs along its rail toward the pointer (horizontal beams track x, vertical beams track y); on leave, each beam resumes its traversal from its current position. Set to false to keep the plain traversal loop. | true |
mode"magnetic" | "follow" | How beams approach the pointer. magnetic springs each beam onto the pointer's projection with velocity-preserving physics; follow travels there linearly at the beam's normal traversal speed, so the chase reads as steady motion instead of a snap. | "magnetic" |
density"sparse" | "normal" | "dense" | Grid cell size (96/56/32px) and beam count (3/5/7). Denser grids suit tighter, more technical compositions. | "normal" |
intensity"faint" | "subtle" | "bold" | Opacity tier for the grid pattern. Keep faint or subtle under body copy; bold is for short hero statements. | "subtle" |
speed"slow" | "normal" | "fast" | Beam traversal duration (9/6/3.5s per sweep), also used when a beam finishes its pass after the pointer leaves. Loops pause automatically while the background is offscreen. | "normal" |
tone"foreground" | "muted" | "primary" | Semantic token driving the grid and beam color via currentColor, so light and dark mode adapt automatically. | "muted" |
seednumber | Drives all pseudo-random beam placement deterministically. The same seed renders the same layout on the server and every client, so markup is SSR-stable; change it to reshuffle the beams. | 1 |
childrenReactNode | Hero content rendered in the content slot above the aria-hidden decorative layer. The layer is pointer-events-none, so children stay fully interactive while pointer moves are tracked on the root. | Not set |
getMagneticBeamsBackgroundMotionConfig / getMagneticBeamsBackgroundGeometry / getMagneticBeamsBackgroundPointerProgress / getMagneticBeamsBackgroundFollowDuration / *ClassNames helpers(speed, reducedMotion) => config, (seed, density) => beams, (pointerFraction) => progress, (current, target, beamDuration) => seconds, ({ className }) => string | Open-code escape hatches: read the resolved loop and attraction transitions, reuse the seeded beam geometry, map a pointer position to a beam's pass progress, or apply the root, layer, and content class recipes to custom elements. | Not set |