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.

Installation

  1. Install the dependencies

    $ npm i motion lucide-react
  2. Copy the source into components/ui/grid-beams.tsx

    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>
      );
    }
    
  3. Use it

    The file exports the component and a Demo showing typical usage. Import whichever you need.