Untitled
unknown
plain_text
a year ago
3.6 kB
4
Indexable
import React, { RefObject, useEffect, useImperativeHandle, useRef } from "react"; import { AnimationName } from "@ds/assets/animations"; import { SxProps } from "@mui/material"; import { AnimationItem } from "lottie-web/build/player/lottie_light"; import { InView } from "react-intersection-observer"; import { Box } from "../box"; import { Player } from "./use-animation"; export type AnimationProps = { animateOnViewportEnter?: boolean; aspectRatio?: string; delay?: number; height?: number | string; maxHeight?: number | string; name: AnimationName; width?: number | string; maxWidth?: number | string; loop?: boolean; control?: RefObject<Player>; onAnimationComplete?: () => void; }; export const Animation = ({ animateOnViewportEnter, aspectRatio, delay = 0, height = "auto", loop = false, maxHeight, maxWidth, name, width = "100%", control, onAnimationComplete, }: AnimationProps) => { const ref = useRef<HTMLDivElement | null>(null); const internalLottieRef = useRef<AnimationItem | 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") => { 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 = ""; const data = await import(`@ds/assets/animations/${name}.json`); internalLottieRef.current = lottie.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> ); };
Editor is loading...
Leave a Comment