55 lines
1.5 KiB
TypeScript
55 lines
1.5 KiB
TypeScript
import React, { useRef, useEffect, useState } from "react";
|
|
|
|
const MouseTrackingGlowEffect: React.FC = () => {
|
|
const [position, setPosition] = useState({ x: 0, y: 0 });
|
|
const [isHovered, setIsHovered] = useState(false);
|
|
const containerRef = useRef<HTMLDivElement>(null);
|
|
|
|
useEffect(() => {
|
|
const handleMouseMove = (event: MouseEvent) => {
|
|
setPosition({ x: event.clientX, y: event.clientY });
|
|
};
|
|
|
|
const handleMouseEnter = () => {
|
|
setIsHovered(true);
|
|
};
|
|
|
|
const handleMouseLeave = () => {
|
|
setIsHovered(false);
|
|
};
|
|
|
|
const container = containerRef.current;
|
|
|
|
if (container) {
|
|
container.addEventListener("mousemove", handleMouseMove);
|
|
container.addEventListener("mouseenter", handleMouseEnter);
|
|
container.addEventListener("mouseleave", handleMouseLeave);
|
|
}
|
|
|
|
return () => {
|
|
if (container) {
|
|
container.removeEventListener("mousemove", handleMouseMove);
|
|
container.removeEventListener("mouseenter", handleMouseEnter);
|
|
container.removeEventListener("mouseleave", handleMouseLeave);
|
|
}
|
|
};
|
|
}, []);
|
|
|
|
return (
|
|
<div
|
|
ref={containerRef}
|
|
className="relative w-screen h-screen overflow-hidden"
|
|
>
|
|
<div
|
|
className={`absolute top-0 left-0 w-64 h-64 bg-blue-500 rounded-full filter ${
|
|
isHovered ? "blur-xl" : "blur-none"
|
|
}`}
|
|
style={{
|
|
transform: `translate(${position.x - 32}px, ${position.y - 32}px)`,
|
|
}}
|
|
></div>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default MouseTrackingGlowEffect;
|