Remove <AnimateChildren />

This commit is contained in:
Sam Becker 2024-02-12 00:23:01 -06:00
parent d8c44fb7f1
commit 2e0549c35e

View File

@ -1,125 +0,0 @@
'use client';
import { Children, ReactNode, useRef } from 'react';
import { Variant, motion } from 'framer-motion';
import { useAppState } from '@/state/AppState';
import usePrefersReducedMotion from '@/utility/usePrefersReducedMotion';
export type AnimationType = 'none' | 'scale' | 'left' | 'right' | 'bottom';
export interface AnimationConfig {
type?: AnimationType
duration?: number
staggerDelay?: number
scaleOffset?: number
distanceOffset?: number
}
interface Props extends AnimationConfig {
children: ReactNode
className?: string
classNameItem?: string
animateFromAppState?: boolean
animateOnFirstLoadOnly?: boolean
staggerOnFirstLoadOnly?: boolean
}
export default function AnimateChildren({
children,
className,
classNameItem,
type = 'scale',
duration = 0.6,
staggerDelay = 0.1,
scaleOffset = 0.9,
distanceOffset = 20,
animateFromAppState,
animateOnFirstLoadOnly,
staggerOnFirstLoadOnly,
}: Props) {
const {
hasLoaded,
nextPhotoAnimation,
clearNextPhotoAnimation,
} = useAppState();
const prefersReducedMotion = usePrefersReducedMotion();
const hasLoadedInitial = useRef(hasLoaded);
const nextPhotoAnimationInitial = useRef(nextPhotoAnimation);
const shouldAnimate = type !== 'none' &&
!prefersReducedMotion &&
!(animateOnFirstLoadOnly && hasLoadedInitial.current);
const shouldStagger =
!(staggerOnFirstLoadOnly && hasLoadedInitial.current);
const typeResolved = animateFromAppState
? (nextPhotoAnimationInitial.current?.type ?? type)
: type;
const durationResolved = animateFromAppState
? (nextPhotoAnimationInitial.current?.duration ?? duration)
: duration;
const getInitialVariant = (): Variant => {
switch (typeResolved) {
case 'left': return {
opacity: 0,
transform: `translateX(${distanceOffset}px)`,
};
case 'right': return {
opacity: 0,
transform: `translateX(${-distanceOffset}px)`,
};
case 'bottom': return {
opacity: 0,
transform: `translateY(${distanceOffset}px)`,
};
default: return {
opacity: 0,
transform: `translateY(${distanceOffset}px) scale(${scaleOffset})`,
};
}
};
return (
<motion.div
className={className}
initial={shouldAnimate ? 'hidden' : false}
animate="show"
variants={shouldStagger
? {
show: {
transition: {
staggerChildren: staggerDelay,
},
},
} : undefined}
onAnimationComplete={() => {
if (animateFromAppState) {
clearNextPhotoAnimation?.();
}
}}
>
{Children.toArray(children).map((item, index) =>
<motion.div
key={index}
className={classNameItem}
variants={{
hidden: getInitialVariant(),
show: {
opacity: 1,
transform: 'translateX(0) translateY(0) scale(1)',
},
}}
transition={{
duration: durationResolved,
easing: 'easeOut',
}}
>
{item}
</motion.div>)}
</motion.div>
);
};