Grid Beams
Precise grid lines with beams of light travelling along them.
Built on solid foundations
A precise grid with light that travels along it.
components/ui/grid-beams.tsx
"use client";
import { motion } from "motion/react";
import type { ReactNode } from "react";
type GridBeamsProps = {
children?: ReactNode;
className?: string;
/** Size of each grid cell in pixels */
cell?: number;
};
const beams = [
{ row: 2, delay: 0, duration: 5, dir: "x" },
{ row: 5, delay: 1.8, duration: 6, dir: "x" },
{ row: 3, delay: 0.9, duration: 5.5, dir: "y" },
{ row: 9, delay: 2.6, duration: 6.5, dir: "y" },
] as const;
export function GridBeams({ children, className = "", cell = 48 }: GridBeamsProps) {
return (
<div className={`relative isolate overflow-hidden bg-white ${className}`}>
<div
aria-hidden
className="absolute inset-0 -z-10 [mask-image:radial-gradient(ellipse_at_center,black_40%,transparent_80%)]"
style={{
backgroundImage:
"linear-gradient(to right, #e4e4e7 1px, transparent 1px), linear-gradient(to bottom, #e4e4e7 1px, transparent 1px)",
backgroundSize: `${cell}px ${cell}px`,
}}
>
{beams.map((b, i) =>
b.dir === "x" ? (
<motion.span
key={i}
className="absolute h-px w-32 bg-gradient-to-r from-transparent via-blue-500 to-transparent"
style={{ top: b.row * cell }}
initial={{ left: "-10%" }}
animate={{ left: "110%" }}
transition={{ duration: b.duration, delay: b.delay, repeat: Infinity, ease: "linear" }}
/>
) : (
<motion.span
key={i}
className="absolute h-32 w-px bg-gradient-to-b from-transparent via-violet-500 to-transparent"
style={{ left: b.row * cell }}
initial={{ top: "-20%" }}
animate={{ top: "120%" }}
transition={{ duration: b.duration, delay: b.delay, repeat: Infinity, ease: "linear" }}
/>
),
)}
</div>
{children}
</div>
);
}
export default function Demo() {
return (
<GridBeams className="grid h-80 w-full max-w-4xl place-items-center rounded-3xl border border-zinc-200">
<div className="text-center">
<h3 className="text-3xl font-semibold tracking-tight text-zinc-900">Built on solid foundations</h3>
<p className="mt-2 text-zinc-500">A precise grid with light that travels along it.</p>
</div>
</GridBeams>
);
}
Installation
Install the dependencies
$ npm i motion lucide-reactCopy the source into
components/ui/grid-beams.tsxcomponents/ui/grid-beams.tsx"use client"; import { motion } from "motion/react"; import type { ReactNode } from "react"; type GridBeamsProps = { children?: ReactNode; className?: string; /** Size of each grid cell in pixels */ cell?: number; }; const beams = [ { row: 2, delay: 0, duration: 5, dir: "x" }, { row: 5, delay: 1.8, duration: 6, dir: "x" }, { row: 3, delay: 0.9, duration: 5.5, dir: "y" }, { row: 9, delay: 2.6, duration: 6.5, dir: "y" }, ] as const; export function GridBeams({ children, className = "", cell = 48 }: GridBeamsProps) { return ( <div className={`relative isolate overflow-hidden bg-white ${className}`}> <div aria-hidden className="absolute inset-0 -z-10 [mask-image:radial-gradient(ellipse_at_center,black_40%,transparent_80%)]" style={{ backgroundImage: "linear-gradient(to right, #e4e4e7 1px, transparent 1px), linear-gradient(to bottom, #e4e4e7 1px, transparent 1px)", backgroundSize: `${cell}px ${cell}px`, }} > {beams.map((b, i) => b.dir === "x" ? ( <motion.span key={i} className="absolute h-px w-32 bg-gradient-to-r from-transparent via-blue-500 to-transparent" style={{ top: b.row * cell }} initial={{ left: "-10%" }} animate={{ left: "110%" }} transition={{ duration: b.duration, delay: b.delay, repeat: Infinity, ease: "linear" }} /> ) : ( <motion.span key={i} className="absolute h-32 w-px bg-gradient-to-b from-transparent via-violet-500 to-transparent" style={{ left: b.row * cell }} initial={{ top: "-20%" }} animate={{ top: "120%" }} transition={{ duration: b.duration, delay: b.delay, repeat: Infinity, ease: "linear" }} /> ), )} </div> {children} </div> ); } export default function Demo() { return ( <GridBeams className="grid h-80 w-full max-w-4xl place-items-center rounded-3xl border border-zinc-200"> <div className="text-center"> <h3 className="text-3xl font-semibold tracking-tight text-zinc-900">Built on solid foundations</h3> <p className="mt-2 text-zinc-500">A precise grid with light that travels along it.</p> </div> </GridBeams> ); }Use it
The file exports the component and a
Demoshowing typical usage. Import whichever you need.