39 lines
1.2 KiB
TypeScript
39 lines
1.2 KiB
TypeScript
import { useLayoutEffect, useRef, useState } from "react";
|
|
|
|
export function useActionBarAnimation(combatantCount: number) {
|
|
const wasEmptyRef = useRef(combatantCount === 0);
|
|
const [settling, setSettling] = useState(false);
|
|
const [rising, setRising] = useState(false);
|
|
const [topBarExiting, setTopBarExiting] = useState(false);
|
|
|
|
useLayoutEffect(() => {
|
|
const nowEmpty = combatantCount === 0;
|
|
if (wasEmptyRef.current && !nowEmpty) {
|
|
setSettling(true);
|
|
} else if (!wasEmptyRef.current && nowEmpty) {
|
|
setRising(true);
|
|
setTopBarExiting(true);
|
|
}
|
|
wasEmptyRef.current = nowEmpty;
|
|
}, [combatantCount]);
|
|
|
|
const empty = combatantCount === 0;
|
|
const risingClass = rising ? "animate-rise-to-center" : "";
|
|
const settlingClass = settling ? "animate-settle-to-bottom" : "";
|
|
const exitingClass = topBarExiting
|
|
? "absolute inset-x-0 top-0 z-10 px-4 animate-slide-up-out"
|
|
: "";
|
|
const topBarClass = settling ? "animate-slide-down-in" : exitingClass;
|
|
const showTopBar = !empty || topBarExiting;
|
|
|
|
return {
|
|
risingClass,
|
|
settlingClass,
|
|
topBarClass,
|
|
showTopBar,
|
|
onSettleEnd: () => setSettling(false),
|
|
onRiseEnd: () => setRising(false),
|
|
onTopBarExitEnd: () => setTopBarExiting(false),
|
|
};
|
|
}
|