A wrapper component that tracks the cursor moving within it
useMousePosition
import { useEffect } from "react"; export function useMousePosition( ref: React.RefObject<HTMLElement>, callback?: ({ x, y }: { x: number; y: number }) => void, ) { useEffect(() => { const handleMouseMove = (event: MouseEvent) => { const { clientX, clientY } = event; const { top, left } = ref.current?.getBoundingClientRect() || { top: 0, left: 0, }; callback?.({ x: clientX - left, y: clientY - top }); }; ref.current?.addEventListener("mousemove", handleMouseMove); const nodeRef = ref.current; return () => { nodeRef?.removeEventListener("mousemove", handleMouseMove); }; }, [ref, callback]); }
It will create a new file cursor-tracker.tsx inside the components/animata/container directory.
cursor-tracker.tsx
components/animata/container
mkdir -p components/animata/container && touch components/animata/container/cursor-tracker.tsx
Open the newly created file and paste the following code:
import { useCallback, useRef } from "react"; import { useMousePosition } from "@/hooks/use-mouse-position"; export default function CursorTracker() { const divRef = useRef<HTMLDivElement>(null); const infoRef = useRef<HTMLDivElement>(null); const update = useCallback(({ x, y }: { x: number; y: number }) => { // We need to offset the position to center the info div const offsetX = (infoRef.current?.offsetWidth || 0) / 2; const offsetY = (infoRef.current?.offsetHeight || 0) / 2; // Use CSS variables to position the info div instead of state to avoid re-renders infoRef.current?.style.setProperty("--x", `${x - offsetX}px`); infoRef.current?.style.setProperty("--y", `${y - offsetY}px`); }, []); useMousePosition(divRef, update); return ( <div ref={divRef} className="group relative w-64 cursor-none rounded-3xl bg-violet-50 p-6 text-violet-800" > {/* Actual content */} <h1 className="mb-4 text-3xl font-semibold leading-none"> Elevate your design with <span className="underline decoration-wavy">Animata</span> </h1> <div className="mb-8"> Move your mouse over the box to reveal the text and the cursor position. </div> {/* Cursor tracker */} <div ref={infoRef} style={{ transform: "translate(var(--x), var(--y))", }} className="0 pointer-events-none absolute left-0 top-0 z-50 rounded-full bg-blue-800/80 px-4 py-2 text-sm font-bold text-white opacity-0 duration-0 group-hover:opacity-100" > Read more → </div> </div> ); }
Built by hari