"use client";
import { useRef, useState } from "react";
import { motion, useMotionValue, useSpring } from "framer-motion";
interface EagleVisionProps {
/** Zoom factor. Default: 2.5 */
zoom?: number;
/** Lens size in px. Default: 180 */
lensSize?: number;
children?: React.ReactNode;
className?: string;
}
export function EagleVision({ zoom = 2.5, lensSize = 180, children, className = "" }: EagleVisionProps) {
const containerRef = useRef<HTMLDivElement>(null);
const [visible, setVisible] = useState(false);
const rawX = useMotionValue(0);
const rawY = useMotionValue(0);
const lensX = useSpring(rawX, { stiffness: 400, damping: 40 });
const lensY = useSpring(rawY, { stiffness: 400, damping: 40 });
const handleMouseMove = (e: React.MouseEvent<HTMLDivElement>) => {
const rect = containerRef.current?.getBoundingClientRect();
if (!rect) return;
rawX.set(e.clientX - rect.left);
rawY.set(e.clientY - rect.top);
};
return (
<div
ref={containerRef}
onMouseMove={handleMouseMove}
onMouseEnter={() => setVisible(true)}
onMouseLeave={() => setVisible(false)}
className={`relative overflow-hidden cursor-none select-none ${className}`}
>
{children}
{/* Lens */}
<motion.div
style={{
x: lensX,
y: lensY,
width: lensSize,
height: lensSize,
translateX: "-50%",
translateY: "-50%",
opacity: visible ? 1 : 0,
}}
className="absolute top-0 left-0 rounded-full pointer-events-none overflow-hidden border-2 border-white/30 shadow-[0_0_0_4px_rgba(0,0,0,0.4),0_0_30px_rgba(99,102,241,0.3)] backdrop-blur-none z-20"
>
{/* Zoomed content */}
<motion.div
style={{
x: lensX,
y: lensY,
translateX: "-50%",
translateY: "-50%",
scale: zoom,
width: "100%",
height: "100%",
transformOrigin: "center",
}}
className="absolute top-0 left-0 w-full h-full"
>
<div className="w-full h-full bg-zinc-950/80 flex items-center justify-center">
<span className="text-indigo-400 text-xs font-mono">×{zoom}</span>
</div>
</motion.div>
{/* Crosshair */}
<div className="absolute inset-0 flex items-center justify-center pointer-events-none">
<div className="w-3 h-px bg-indigo-400/60" />
<div className="absolute w-px h-3 bg-indigo-400/60" />
</div>
</motion.div>
</div>
);
}