in blocks/main/latest-news/mascot/index.tsx [53:113]
function MascotContent({ className, onFinish }: MascotProps & { onFinish: () => void }) {
const mascotNode = useRef<HTMLSpanElement>(null);
const { ref: inViewRef, inView } = useInView();
useEffect(() => {
const node = mascotNode.current;
let animation: AnimationItem;
let play: ReturnType<typeof createAnimation>[1];
let wasOnceStarted = false;
function done() {
if (wasOnceStarted) onFinish();
}
let skipInactiveHook: (body: () => Promise<void>) => ReturnType<typeof body> = (body) => body();
async function playAnimation() {
const [lottie, initialData] = await Promise.all([
import('lottie-web/build/player/lottie_light').then((l) => l.default),
import('./option3.json'),
sleep(ANIMATION_INITIAL_DELAY),
]);
await skipInactiveHook(async function initialPlay() {
[animation, play] = createAnimation(lottie, node, initialData);
wasOnceStarted = true;
await play();
});
let afterData: Parameters<typeof createAnimation>[2];
await skipInactiveHook(async function afterPrepare() {
[afterData] = await Promise.all([import('./option4.json'), sleep(ANIMATION_AFTER_DELAY)]);
});
await skipInactiveHook(async function afterPlay() {
[animation, play] = createAnimation(lottie, node, afterData);
await play();
});
done();
}
if (node && inView) {
playAnimation();
return function playCleanup() {
skipInactiveHook = noop;
animation?.destroy();
done();
};
}
}, [mascotNode.current, inView]);
return (
<div aria-hidden="true" ref={inViewRef} className={cn(styles.container, className)}>
<span ref={mascotNode} className={styles.animation} />
</div>
);
}