53 lines
1.5 KiB
TypeScript
53 lines
1.5 KiB
TypeScript
import { useEffect, useRef, useState } from "react";
|
|
|
|
interface Depth3DAnimationOptions {
|
|
rotationX?: number;
|
|
rotationY?: number;
|
|
rotationZ?: number;
|
|
perspective?: number;
|
|
duration?: number;
|
|
}
|
|
|
|
interface AnimationState {
|
|
transform: string;
|
|
transition: string;
|
|
itemRefs?: React.MutableRefObject<(HTMLElement | null)[]>;
|
|
containerRef?: React.MutableRefObject<HTMLDivElement | null>;
|
|
perspectiveRef?: React.MutableRefObject<HTMLDivElement | null>;
|
|
bottomContentRef?: React.MutableRefObject<HTMLDivElement | null>;
|
|
}
|
|
|
|
export const useCardAnimation = (
|
|
options: Depth3DAnimationOptions = {}
|
|
): AnimationState => {
|
|
const [state, setState] = useState<AnimationState>({
|
|
transform: "", transition: ""});
|
|
|
|
const itemRefs = useRef<(HTMLElement | null)[]>([]);
|
|
const containerRef = useRef<HTMLDivElement | null>(null);
|
|
const perspectiveRef = useRef<HTMLDivElement | null>(null);
|
|
const bottomContentRef = useRef<HTMLDivElement | null>(null);
|
|
|
|
const {
|
|
rotationX = 0,
|
|
rotationY = 0,
|
|
rotationZ = 0,
|
|
perspective = 1000,
|
|
duration = 0.3,
|
|
} = options;
|
|
|
|
useEffect(() => {
|
|
const transform = `perspective(${perspective}px) rotateX(${rotationX}deg) rotateY(${rotationY}deg) rotateZ(${rotationZ}deg)`;
|
|
setState({
|
|
transform,
|
|
transition: `transform ${duration}s ease-out`,
|
|
itemRefs,
|
|
containerRef,
|
|
perspectiveRef,
|
|
bottomContentRef,
|
|
});
|
|
}, [rotationX, rotationY, rotationZ, perspective, duration]);
|
|
|
|
return state;
|
|
};
|