Card Spotlight Component
This interactive component features a dynamic spotlight that follows the user's cursor, highlighting elements on the card. It's built using the CardSpotlight
component in your Next.js application, leveraging React for reactive features and TailwindCSS for seamless styling.
Card Content
Usage
To use the CardSpotlight
component in your project, simply import it from where it is defined:
import CardSpotlight from "@/app/components/CardSpotlight";
function MyApp() {
return <CardSpotlight />;
}
Source Code
Create the CardSpotlight
component in @/app/components/CardSpotlight.tsx
with the following structure:
"use client";
import type React from "react";
import { useRef, useState, useCallback } from "react";
interface Position {
x: number;
y: number;
}
const CardSpotlight: React.FC = () => {
const divRef = useRef<HTMLDivElement>(null);
const [isFocused, setIsFocused] = useState(false);
const [position, setPosition] = useState<Position>({ x: 0, y: 0 });
const [opacity, setOpacity] = useState(0);
const handleMouseMove = useCallback(
(e: React.MouseEvent<HTMLDivElement>) => {
if (!divRef.current || isFocused) return;
const rect = divRef.current.getBoundingClientRect();
setPosition({
x: e.clientX - rect.left,
y: e.clientY - rect.top,
});
},
[isFocused]
);
const handleFocus = useCallback(() => {
setIsFocused(true);
setOpacity(1);
}, []);
const handleBlur = useCallback(() => {
setIsFocused(false);
setOpacity(0);
}, []);
const handleMouseEnter = useCallback(() => setOpacity(1), []);
const handleMouseLeave = useCallback(() => setOpacity(0), []);
return (
<div
ref={divRef}
onMouseMove={handleMouseMove}
onFocus={handleFocus}
onBlur={handleBlur}
onMouseEnter={handleMouseEnter}
onMouseLeave={handleMouseLeave}
className="relative flex h-48 w-48 items-center justify-center overflow-hidden rounded-xl border border-zinc-800 bg-gradient-to-r from-black to-zinc-950 px-8 py-16 shadow-2xl"
>
<div
className="pointer-events-none absolute -inset-px opacity-0 transition duration-300"
style={{
opacity,
background: `radial-gradient(600px circle at ${position.x}px ${position.y}px, rgba(255,255,255,0.2), transparent 40%)`,
}}
/>
<p className="text-sm text-zinc-200">Card Content</p>
</div>
);
};
export default CardSpotlight;