"use client"; import { useEffect, useRef } from "react"; import { cls } from "@/lib/utils"; import { animate } from "motion/react"; const spread = 40; const proximity = 64; const borderWidth = 1.5; const BorderGlow = ({ className }: { className?: string }) => { const ref = useRef(null); const rafRef = useRef(0); useEffect(() => { const el = ref.current; if (!el) return; const onPointerMove = (e: PointerEvent) => { if (rafRef.current) cancelAnimationFrame(rafRef.current); rafRef.current = requestAnimationFrame(() => { const { left, top, width, height } = el.getBoundingClientRect(); const { clientX: x, clientY: y } = e; const isActive = x > left - proximity && x < left + width + proximity && y > top - proximity && y < top + height + proximity; el.style.setProperty("--active", isActive ? "1" : "0"); if (!isActive) return; const centerX = left + width / 2; const centerY = top + height / 2; const currentAngle = parseFloat(el.style.getPropertyValue("--start")) || 0; const targetAngle = (Math.atan2(y - centerY, x - centerX) * 180) / Math.PI + 90; const angleDiff = ((targetAngle - currentAngle + 180) % 360) - 180; animate(currentAngle, currentAngle + angleDiff, { duration: 2, ease: [0.16, 1, 0.3, 1], onUpdate: (v) => el.style.setProperty("--start", String(v)), }); }); }; document.body.addEventListener("pointermove", onPointerMove, { passive: true }); return () => { if (rafRef.current) cancelAnimationFrame(rafRef.current); document.body.removeEventListener("pointermove", onPointerMove); }; }, []); const gradient = `radial-gradient(circle, var(--color-accent) 10%, transparent 20%), radial-gradient(circle at 40% 40%, var(--color-background-accent) 5%, transparent 15%), repeating-conic-gradient(from 236.84deg at 50% 50%, var(--color-accent) 0%, var(--color-background-accent) 5%, var(--color-accent) 10%)`; return (
); }; export default BorderGlow;