43 lines
1.2 KiB
TypeScript
43 lines
1.2 KiB
TypeScript
import { useCallback, useEffect, useRef, useState } from 'react';
|
|
|
|
export function Ellipse() {
|
|
const ref = useRef<HTMLDivElement>(null);
|
|
const requestRef = useRef<number>();
|
|
const x = useRef(0);
|
|
const y = useRef(0);
|
|
const [mousePos, setMousePos] = useState([0, 0]);
|
|
|
|
const handleMouseMove = useCallback((e: MouseEvent) => {
|
|
x.current = e.clientX;
|
|
y.current = e.clientY;
|
|
}, []);
|
|
|
|
const animate = useCallback(() => {
|
|
if (ref.current) {
|
|
setMousePos(([prevX, prevY]) => [
|
|
prevX + (x.current - prevX) / 10,
|
|
prevY + (y.current - prevY) / 10,
|
|
]);
|
|
}
|
|
requestRef.current = requestAnimationFrame(animate);
|
|
}, []);
|
|
|
|
useEffect(() => {
|
|
document.body?.addEventListener('mousemove', handleMouseMove);
|
|
animate();
|
|
|
|
return () => {
|
|
cancelAnimationFrame(requestRef.current!);
|
|
document.body?.removeEventListener('mousemove', handleMouseMove);
|
|
};
|
|
}, [animate, handleMouseMove]);
|
|
|
|
return (
|
|
<div
|
|
ref={ref}
|
|
style={{ top: mousePos[1], left: mousePos[0] }}
|
|
className="fixed -z-[9] -translate-y-[50%] -translate-x-[50%] max-w-[10vw] w-full aspect-[348.85/262.77] [-webkit-filter:blur(25px)] [box-shadow:3px_3px_#5545AC,3px_3px_#5545AC] bg-[#5545AC] rounded-full"
|
|
/>
|
|
);
|
|
}
|