37 lines
1.0 KiB
TypeScript
37 lines
1.0 KiB
TypeScript
"use client";
|
|
|
|
import { useEffect, useRef } from "react";
|
|
|
|
export default function Cursor() {
|
|
const dotRef = useRef<HTMLDivElement>(null);
|
|
|
|
useEffect(() => {
|
|
// Skip on touchscreens — pointer:fine === false there
|
|
if (!window.matchMedia("(pointer: fine)").matches) return;
|
|
|
|
const el = dotRef.current;
|
|
if (!el) return;
|
|
|
|
const move = (e: MouseEvent) => {
|
|
// Two translates: first moves to cursor coords, second re-centers the dot
|
|
el.style.transform = `translate(${e.clientX}px, ${e.clientY}px) translate(-50%, -50%)`;
|
|
};
|
|
|
|
window.addEventListener("mousemove", move);
|
|
return () => window.removeEventListener("mousemove", move);
|
|
}, []);
|
|
|
|
return (
|
|
<div
|
|
ref={dotRef}
|
|
aria-hidden
|
|
// Initial inline transform parks it off-screen until the first mousemove
|
|
style={{ transform: "translate(-100px, -100px)" }}
|
|
className="
|
|
pointer-events-none fixed left-0 top-0 z-[100]
|
|
size-3 rounded-full bg-white mix-blend-difference
|
|
"
|
|
/>
|
|
);
|
|
}
|