32 lines
1.2 KiB
TypeScript
32 lines
1.2 KiB
TypeScript
import { useEffect, useRef, useState } from "react";
|
|
import type { ViewportState } from "@editor/state";
|
|
import type { BottomControlsAction } from "./BottomControlsIsland";
|
|
|
|
export type ViewportActivityIslandState = {
|
|
visible: boolean;
|
|
action: BottomControlsAction;
|
|
};
|
|
|
|
export function useViewportActivityIsland(viewport: ViewportState): ViewportActivityIslandState {
|
|
const [visible, setVisible] = useState(false);
|
|
const [action, setAction] = useState<BottomControlsAction>("zoom");
|
|
const previousViewport = useRef({ zoom: viewport.zoom, center: viewport.center });
|
|
|
|
useEffect(() => {
|
|
const previous = previousViewport.current;
|
|
const zoomChanged = previous.zoom !== viewport.zoom;
|
|
const centerChanged = previous.center.x !== viewport.center.x || previous.center.y !== viewport.center.y;
|
|
|
|
if (!zoomChanged && !centerChanged) return;
|
|
|
|
previousViewport.current = { zoom: viewport.zoom, center: viewport.center };
|
|
setAction(zoomChanged ? "zoom" : "pan");
|
|
setVisible(true);
|
|
|
|
const timeout = window.setTimeout(() => setVisible(false), 1200);
|
|
return () => window.clearTimeout(timeout);
|
|
}, [viewport.center, viewport.zoom]);
|
|
|
|
return { visible, action };
|
|
}
|