import { Footer } from "@excalidraw/excalidraw/index"; import { getCommonBounds, getSelectedElements, getVisibleSceneBounds, } from "@excalidraw/element"; import React, { useCallback, useState } from "react"; import type { ExcalidrawImperativeAPI, ScrollConstraints, } from "@excalidraw/excalidraw/types"; import { isExcalidrawPlusSignedUser } from "../app_constants"; import { DebugFooter, isVisualDebuggerEnabled } from "./DebugCanvas"; import { EncryptedIcon } from "./EncryptedIcon"; type ScrollConstraintOptions = Pick< ScrollConstraints, "lockZoom" | "overscrollAllowance" | "viewportZoomFactor" >; const ScrollConstraintsDebugFooter = ({ excalidrawAPI, }: { excalidrawAPI: ExcalidrawImperativeAPI | null; }) => { const [activeLock, setActiveLock] = useState(null); const [options, setOptions] = useState({ lockZoom: false, overscrollAllowance: 0.2, viewportZoomFactor: 0.2, }); const setLock = useCallback( (nextLock: ScrollConstraints) => { excalidrawAPI?.setScrollConstraints(nextLock); setActiveLock(nextLock); }, [excalidrawAPI], ); const toggleScrollLock = useCallback(() => { if (!excalidrawAPI) { return; } if (activeLock) { excalidrawAPI.setScrollConstraints(null); setActiveLock(null); return; } const selectedElements = getSelectedElements( excalidrawAPI.getSceneElements(), excalidrawAPI.getAppState(), { includeBoundTextElement: true, includeElementsInFrames: true, }, ); const [x1, y1, x2, y2] = selectedElements.length ? getCommonBounds( selectedElements, excalidrawAPI.getSceneElementsMapIncludingDeleted(), ) : getVisibleSceneBounds(excalidrawAPI.getAppState()); setLock({ x: x1, y: y1, width: x2 - x1, height: y2 - y1, ...options, }); }, [activeLock, excalidrawAPI, options, setLock]); const updateOptions = useCallback( (nextOptions: ScrollConstraintOptions) => { setOptions(nextOptions); if (activeLock) { setLock({ ...activeLock, ...nextOptions }); } }, [activeLock, setLock], ); const updateNumberOption = useCallback( (option: "overscrollAllowance" | "viewportZoomFactor", value: string) => { updateOptions({ ...options, [option]: value === "" ? undefined : Number(value), }); }, [options, updateOptions], ); const updateBooleanOption = useCallback( (option: "lockZoom", value: boolean) => { updateOptions({ ...options, [option]: value, }); }, [options, updateOptions], ); return (
); }; export const AppFooter = React.memo( ({ excalidrawAPI, onChange, }: { excalidrawAPI: ExcalidrawImperativeAPI | null; onChange: () => void; }) => { return ( ); }, );