Spotlight Dots
Dot pattern that lights up in color around the cursor.
Move your cursor
The dot field lights up wherever you go.
components/ui/spotlight-dots.tsx
"use client";
import { motion, useMotionTemplate, useMotionValue } from "motion/react";
import type { ReactNode } from "react";
type SpotlightDotsProps = {
children?: ReactNode;
className?: string;
/** Dot color of the highlighted area */
highlight?: string;
};
export function SpotlightDots({ children, className = "", highlight = "#2563eb" }: SpotlightDotsProps) {
const x = useMotionValue(-500);
const y = useMotionValue(-500);
const mask = useMotionTemplate`radial-gradient(220px circle at ${x}px ${y}px, black, transparent)`;
return (
<div
onMouseMove={(e) => {
const rect = e.currentTarget.getBoundingClientRect();
x.set(e.clientX - rect.left);
y.set(e.clientY - rect.top);
}}
onMouseLeave={() => {
x.set(-500);
y.set(-500);
}}
className={`group relative isolate overflow-hidden bg-white ${className}`}
>
<div
aria-hidden
className="absolute inset-0 -z-10"
style={{ backgroundImage: "radial-gradient(#d4d4d8 1px, transparent 1px)", backgroundSize: "18px 18px" }}
/>
<motion.div
aria-hidden
className="absolute inset-0 -z-10"
style={{
backgroundImage: `radial-gradient(${highlight} 1.4px, transparent 1.4px)`,
backgroundSize: "18px 18px",
maskImage: mask,
WebkitMaskImage: mask,
}}
/>
{children}
</div>
);
}
export default function Demo() {
return (
<SpotlightDots className="grid h-80 w-full max-w-4xl place-items-center rounded-3xl border border-zinc-200">
<div className="rounded-2xl bg-white/80 px-8 py-6 text-center backdrop-blur-sm">
<h3 className="text-3xl font-semibold tracking-tight text-zinc-900">Move your cursor</h3>
<p className="mt-2 text-zinc-500">The dot field lights up wherever you go.</p>
</div>
</SpotlightDots>
);
}
Installation
Install the dependencies
$ npm i motion lucide-reactCopy the source into
components/ui/spotlight-dots.tsxcomponents/ui/spotlight-dots.tsx"use client"; import { motion, useMotionTemplate, useMotionValue } from "motion/react"; import type { ReactNode } from "react"; type SpotlightDotsProps = { children?: ReactNode; className?: string; /** Dot color of the highlighted area */ highlight?: string; }; export function SpotlightDots({ children, className = "", highlight = "#2563eb" }: SpotlightDotsProps) { const x = useMotionValue(-500); const y = useMotionValue(-500); const mask = useMotionTemplate`radial-gradient(220px circle at ${x}px ${y}px, black, transparent)`; return ( <div onMouseMove={(e) => { const rect = e.currentTarget.getBoundingClientRect(); x.set(e.clientX - rect.left); y.set(e.clientY - rect.top); }} onMouseLeave={() => { x.set(-500); y.set(-500); }} className={`group relative isolate overflow-hidden bg-white ${className}`} > <div aria-hidden className="absolute inset-0 -z-10" style={{ backgroundImage: "radial-gradient(#d4d4d8 1px, transparent 1px)", backgroundSize: "18px 18px" }} /> <motion.div aria-hidden className="absolute inset-0 -z-10" style={{ backgroundImage: `radial-gradient(${highlight} 1.4px, transparent 1.4px)`, backgroundSize: "18px 18px", maskImage: mask, WebkitMaskImage: mask, }} /> {children} </div> ); } export default function Demo() { return ( <SpotlightDots className="grid h-80 w-full max-w-4xl place-items-center rounded-3xl border border-zinc-200"> <div className="rounded-2xl bg-white/80 px-8 py-6 text-center backdrop-blur-sm"> <h3 className="text-3xl font-semibold tracking-tight text-zinc-900">Move your cursor</h3> <p className="mt-2 text-zinc-500">The dot field lights up wherever you go.</p> </div> </SpotlightDots> ); }Use it
The file exports the component and a
Demoshowing typical usage. Import whichever you need.