36 lines
1.2 KiB
TypeScript
36 lines
1.2 KiB
TypeScript
import { useState, useEffect, RefObject } from "react";
|
|
|
|
export const useParallax = (ref: RefObject<HTMLElement>, options?: { maxRotate?: number }) => {
|
|
const [transform, setTransform] = useState("rotateX(0deg) rotateY(0deg) scale3d(1, 1, 1)");
|
|
const maxRotate = options?.maxRotate || 5;
|
|
|
|
useEffect(() => {
|
|
const element = ref.current;
|
|
if (!element) return;
|
|
|
|
const handleMouseMove = (e: MouseEvent) => {
|
|
const { left, top, width, height } = element.getBoundingClientRect();
|
|
const x = e.clientX - left;
|
|
const y = e.clientY - top;
|
|
|
|
const rotateX = ((y / height) - 0.5) * -maxRotate * 2;
|
|
const rotateY = ((x / width) - 0.5) * maxRotate * 2;
|
|
|
|
setTransform(`rotateX(${rotateX}deg) rotateY(${rotateY}deg) scale3d(1.05, 1.05, 1.05)`);
|
|
};
|
|
|
|
const handleMouseLeave = () => {
|
|
setTransform("rotateX(0deg) rotateY(0deg) scale3d(1, 1, 1)");
|
|
};
|
|
|
|
element.addEventListener("mousemove", handleMouseMove);
|
|
element.addEventListener("mouseleave", handleMouseLeave);
|
|
|
|
return () => {
|
|
element.removeEventListener("mousemove", handleMouseMove);
|
|
element.removeEventListener("mouseleave", handleMouseLeave);
|
|
};
|
|
}, [ref, maxRotate]);
|
|
|
|
return transform;
|
|
}; |