Untitled
unknown
plain_text
a year ago
5.4 kB
6
Indexable
export type Player = { /// Plays the animation play: () => void; /// Sets the direction of play setDirection: (direction: "forward" | "reverse") => void; /// Pauses the animation pause: () => void; /// Stops animation playback stop: () => void; }; export const useAnimation = () => { const lottieRef = useRef<Player | null>(null); const play = () => { lottieRef.current?.play(); }; const setDirection = (direction: "forward" | "reverse") => { console.log("setDirection in useAnimation"); lottieRef.current?.setDirection(direction); }; const pause = () => { lottieRef.current?.pause(); }; const stop = () => { lottieRef.current?.stop(); }; lottieRef.current = { pause, play, setDirection, stop, }; return { control: lottieRef, pause, play, setDirection, stop, }; }; export const Animation = ({ animateOnViewportEnter, aspectRatio, delay = 0, height = "auto", loop = false, maxHeight, maxWidth, name, width = "100%", control, }: AnimationProps) => { const ref = useRef<HTMLDivElement | null>(null); const internalLottieRef = useRef<LottiePlayer | null>(null); const handleViewEnter = (inView: boolean) => { if (inView) { internalLottieRef.current?.play(); } }; useImperativeHandle( control, () => { return { pause: () => { internalLottieRef.current?.pause(); }, play: () => { internalLottieRef.current?.play(); }, setDirection: (direction: "forward" | "reverse") => { console.log("setDirection in Animation"); internalLottieRef.current?.setDirection(direction === "forward" ? 1 : -1); }, stop: () => { internalLottieRef.current?.stop(); }, }; }, [], ); useEffect(() => { const loadLottie = async () => { const { default: lottie } = await import( /* webpackChunkName: "lottie-web" */ "lottie-web/build/player/lottie_light" ); lottie.setLocationHref(window.location.href); if (!ref.current) { return; } ref.current.innerHTML = ""; internalLottieRef.current = lottie; const data = await import(`@ds/assets/animations/${name}.json`); internalLottieRef.current.loadAnimation({ animationData: data, autoplay: false, container: ref.current, loop, renderer: "svg", }); const play = () => internalLottieRef.current?.play(); if (delay) { setTimeout(play, delay); } if (!animateOnViewportEnter && !control) { play(); } }; loadLottie(); }, [animateOnViewportEnter, delay, control, loop, name]); const containerStyles: SxProps = { aspectRatio, maxHeight, maxWidth, svg: { height: `${typeof height === "number" ? `${height}px` : height} !important`, width: `${typeof width === "number" ? `${width}px` : width} !important`, }, }; const content = <Box aria-hidden={true} display="flex" ref={ref} sx={containerStyles} />; if (!animateOnViewportEnter) { return content; } return ( <InView onChange={handleViewEnter} triggerOnce={true}> {content} </InView> ); }; export const Face = ({ name, onClick, children }: FaceProps) => { const { control, play, setDirection, pause } = useAnimation(); const handleMouseEnter = () => { console.log("handleMouseEnter") setDirection("forward"); play(); }; const handleMouseLeave = () => { pause(); setDirection("reverse"); play(); }; const handleClick = () => { onClick?.(); }; return ( <BoxRipple alignItems="center" display="flex" flexDirection="column" gap="space12" onClick={handleClick} onMouseEnter={handleMouseEnter} onMouseLeave={handleMouseLeave} width={56} > <Animation control={control} height={48} name={`AnimationSurvey${name}HoverOn48x48`} width={48} /> <Text variant="standard-bold">{children}</Text> </BoxRipple> ); }; jak używam powyzszego komponentu Face, w ten sposób to dostaje błąd Uncaught RangeError: Maximum call stack size exceeded at Object.setDirection i w konsoli widzę że "setDirection in useAnimation" zostało wywołane kilka tysięcy razy, skąd ten błąd? bo z kolei "handleMouseEnter" zostało zalogowane raz
Editor is loading...
Leave a Comment