ERP-node/frontend/components/animations/AnimatedComponent.tsx

155 lines
4.4 KiB
TypeScript

"use client";
import React, { useState, useEffect } from "react";
import { animations, animationCombos, AnimationConfig } from "@/lib/animations/animations";
interface AnimatedComponentProps {
children: React.ReactNode;
animation?: keyof typeof animations;
combo?: keyof typeof animationCombos;
config?: AnimationConfig;
trigger?: "mount" | "hover" | "click" | "visible";
delay?: number;
className?: string;
style?: React.CSSProperties;
}
export const AnimatedComponent: React.FC<AnimatedComponentProps> = ({
children,
animation = "fadeIn",
combo,
config = {},
trigger = "mount",
delay = 0,
className = "",
style = {},
}) => {
const [isVisible, setIsVisible] = useState(false);
const [isAnimating, setIsAnimating] = useState(false);
useEffect(() => {
if (trigger === "mount") {
const timer = setTimeout(() => {
setIsVisible(true);
setIsAnimating(true);
}, delay);
return () => clearTimeout(timer);
}
}, [trigger, delay]);
const handleMouseEnter = () => {
if (trigger === "hover") {
setIsAnimating(true);
}
};
const handleMouseLeave = () => {
if (trigger === "hover") {
setIsAnimating(false);
}
};
const handleClick = () => {
if (trigger === "click") {
setIsAnimating(true);
setTimeout(() => setIsAnimating(false), config.duration || 300);
}
};
const getAnimationStyle = () => {
if (combo) {
return animationCombos[combo]();
}
if (animation) {
return animations[animation](config);
}
return {};
};
const animationStyle = isAnimating ? getAnimationStyle() : {};
return (
<div
className={className}
style={{
...style,
...animationStyle,
}}
onMouseEnter={handleMouseEnter}
onMouseLeave={handleMouseLeave}
onClick={handleClick}
>
{children}
</div>
);
};
// 특화된 애니메이션 컴포넌트들
export const FadeIn: React.FC<Omit<AnimatedComponentProps, "animation">> = (props) => (
<AnimatedComponent {...props} animation="fadeIn" />
);
export const SlideInFromLeft: React.FC<Omit<AnimatedComponentProps, "animation">> = (props) => (
<AnimatedComponent {...props} animation="slideInFromLeft" />
);
export const SlideInFromRight: React.FC<Omit<AnimatedComponentProps, "animation">> = (props) => (
<AnimatedComponent {...props} animation="slideInFromRight" />
);
export const SlideInFromTop: React.FC<Omit<AnimatedComponentProps, "animation">> = (props) => (
<AnimatedComponent {...props} animation="slideInFromTop" />
);
export const SlideInFromBottom: React.FC<Omit<AnimatedComponentProps, "animation">> = (props) => (
<AnimatedComponent {...props} animation="slideInFromBottom" />
);
export const ScaleIn: React.FC<Omit<AnimatedComponentProps, "animation">> = (props) => (
<AnimatedComponent {...props} animation="scaleIn" />
);
export const Bounce: React.FC<Omit<AnimatedComponentProps, "animation">> = (props) => (
<AnimatedComponent {...props} animation="bounce" />
);
export const Pulse: React.FC<Omit<AnimatedComponentProps, "animation">> = (props) => (
<AnimatedComponent {...props} animation="pulse" />
);
export const Glow: React.FC<Omit<AnimatedComponentProps, "animation">> = (props) => (
<AnimatedComponent {...props} animation="glow" />
);
// 조합 애니메이션 컴포넌트들
export const PageTransition: React.FC<Omit<AnimatedComponentProps, "combo"> & { direction?: "left" | "right" | "up" | "down" }> = ({ direction, ...props }) => (
<AnimatedComponent {...props} combo="pageTransition" />
);
export const ModalEnter: React.FC<Omit<AnimatedComponentProps, "combo">> = (props) => (
<AnimatedComponent {...props} combo="modalEnter" />
);
export const ModalExit: React.FC<Omit<AnimatedComponentProps, "combo">> = (props) => (
<AnimatedComponent {...props} combo="modalExit" />
);
export const ButtonClick: React.FC<Omit<AnimatedComponentProps, "combo">> = (props) => (
<AnimatedComponent {...props} combo="buttonClick" trigger="click" />
);
export const SuccessNotification: React.FC<Omit<AnimatedComponentProps, "combo">> = (props) => (
<AnimatedComponent {...props} combo="successNotification" />
);
export const LoadingSpinner: React.FC<Omit<AnimatedComponentProps, "combo">> = (props) => (
<AnimatedComponent {...props} combo="loadingSpinner" />
);
export const HoverLift: React.FC<Omit<AnimatedComponentProps, "combo">> = (props) => (
<AnimatedComponent {...props} combo="hoverLift" trigger="hover" />
);