agency-web/app/components/Cursor.tsx

49 lines
1.5 KiB
TypeScript

"use client";
import { useEffect, useRef } from "react";
import { gsap } from "gsap";
export default function Cursor() {
const dot = useRef<HTMLDivElement>(null);
const ring = useRef<HTMLDivElement>(null);
useEffect(() => {
if (window.matchMedia("(pointer: coarse)").matches) return;
if (!dot.current || !ring.current) return;
const xD = gsap.quickTo(dot.current, "x", { duration: 0.15, ease: "power3" });
const yD = gsap.quickTo(dot.current, "y", { duration: 0.15, ease: "power3" });
const xR = gsap.quickTo(ring.current, "x", { duration: 0.5, ease: "power3" });
const yR = gsap.quickTo(ring.current, "y", { duration: 0.5, ease: "power3" });
const move = (e: MouseEvent) => {
xD(e.clientX);
yD(e.clientY);
xR(e.clientX);
yR(e.clientY);
};
const over = (e: Event) => {
if ((e.target as HTMLElement).closest("a,button,.hoverable")) {
ring.current?.classList.add("cursor-ring--big");
}
};
const out = () => ring.current?.classList.remove("cursor-ring--big");
window.addEventListener("mousemove", move);
document.addEventListener("mouseover", over);
document.addEventListener("mouseout", out);
return () => {
window.removeEventListener("mousemove", move);
document.removeEventListener("mouseover", over);
document.removeEventListener("mouseout", out);
};
}, []);
return (
<>
<div ref={ring} className="cursor-ring" aria-hidden />
<div ref={dot} className="cursor-dot" aria-hidden />
</>
);
}