import React from "react"; import { RoughCanvas } from "roughjs/bin/canvas"; import { ActionManager } from "../actions/manager"; import { ExcalidrawElement, NonDeletedExcalidrawElement } from "../element/types"; import History from "../history"; import Scene from "../scene/Scene"; import { AppClassProperties, AppProps, AppState, ExcalidrawImperativeAPI, BinaryFiles, LibraryItems, SceneData, Device } from "../types"; import { FileSystemHandle } from "../data/filesystem"; export declare const useDevice: () => Readonly<{ isSmScreen: boolean; isMobile: boolean; isTouchScreen: boolean; canDeviceFitSidebar: boolean; }>; export declare const useExcalidrawContainer: () => { container: HTMLDivElement | null; id: string | null; }; declare class App extends React.Component { canvas: AppClassProperties["canvas"]; rc: RoughCanvas | null; unmounted: boolean; actionManager: ActionManager; device: Device; detachIsMobileMqHandler?: () => void; private excalidrawContainerRef; static defaultProps: Partial; scene: Scene; private resizeObserver; private nearestScrollableContainer; library: AppClassProperties["library"]; libraryItemsFromStorage: LibraryItems | undefined; private id; private history; private excalidrawContainerValue; files: BinaryFiles; imageCache: AppClassProperties["imageCache"]; hitLinkElement?: NonDeletedExcalidrawElement; lastPointerDown: React.PointerEvent | null; lastPointerUp: React.PointerEvent | PointerEvent | null; contextMenuOpen: boolean; lastScenePointer: { x: number; y: number; } | null; constructor(props: AppProps); private renderCanvas; render(): JSX.Element; focusContainer: AppClassProperties["focusContainer"]; getSceneElementsIncludingDeleted: () => readonly ExcalidrawElement[]; getSceneElements: () => readonly NonDeletedExcalidrawElement[]; private resetAllElements; private syncActionResult; private onBlur; private onUnload; private disableEvent; private onFontLoaded; private resetHistory; private undoOnce; private redoOnce; private writeDataElements; private saveAsJsonBlob; /** * Resets scene & history. * ! Do not use to clear scene user action ! */ private resetScene; private initializeScene; private refreshDeviceState; componentDidMount(): Promise; componentWillUnmount(): void; private onResize; private removeEventListeners; private addEventListeners; componentDidUpdate(prevProps: AppProps, prevState: AppState): void; private updateOffsetTopLeft; private onScroll; private onResizeUpdateOffsetTopLeft; /** 添加防抖函数,防止居中后的画布,dom 变化带有延迟动画(最好不超过 500ms,否则就到外部使用防抖或 setTimeout ),画布位置没有固定就开始刷新 updateOffsetTopLeft */ refresh: { (): void; flush(): void; cancel(): void; }; private onCut; private onCopy; private cutAll; private copyAll; private static resetTapTwice; private onTapStart; private onTapEnd; private pasteFromClipboard; private addElementsFromPasteOrLibrary; private addTextFromPaste; setAppState: (obj: any) => void; removePointer: (event: React.PointerEvent | PointerEvent) => void; toggleLock: (source?: "keyboard" | "ui") => void; setStrokeColor: (color: string) => void; setStrokeWidth: (strokeWidth: number) => void; togglePenMode: () => void; toggleZenMode: () => void; scrollToContent: (target?: ExcalidrawElement | readonly ExcalidrawElement[]) => void; clearToast: () => void; setToastMessage: (toastMessage: string) => void; restoreFileFromShare: () => Promise; /** adds supplied files to existing files in the appState */ addFiles: ExcalidrawImperativeAPI["addFiles"]; updateScene: (sceneData: { elements?: SceneData["elements"]; appState?: Pick | null | undefined; collaborators?: SceneData["collaborators"]; commitToHistory?: SceneData["commitToHistory"]; }) => void; private onSceneUpdated; private updateCurrentCursorPosition; private onKeyDown; private onKeyUp; private setActiveTool; private setCursor; private resetCursor; /** * returns whether user is making a gesture with >= 2 fingers (points) * on o touch screen (not on a trackpad). Currently only relates to Darwin * (iOS/iPadOS,MacOS), but may work on other devices in the future if * GestureEvent is standardized. */ private isTouchScreenMultiTouchGesture; private onGestureStart; private onGestureChange; private onGestureEnd; private handleTextWysiwyg; private deselectElements; private getTextElementAtPosition; private getElementAtPosition; private getElementsAtPosition; private startTextEditing; private handleCanvasDoubleClick; private getElementLinkAtPosition; private redirectToLink; private handleCanvasPointerMove; private handleEraser; private handleTouchMove; private handleCanvasPointerDown; private handleCanvasPointerUp; private maybeOpenContextMenuAfterPointerDownOnTouchDevices; private resetContextMenuTimer; private maybeCleanupAfterMissingPointerUp; private handleCanvasPanUsingWheelOrSpaceDrag; private updateGestureOnPointerDown; private initialPointerDownState; private handleDraggingScrollBar; private clearSelectionIfNotUsingSelection; /** * @returns whether the pointer event has been completely handled */ private handleSelectionOnPointerDown; private isASelectedElement; private isHittingCommonBoundingBoxOfSelectedElements; private handleTextOnPointerDown; private handleFreeDrawElementOnPointerDown; private createImageElement; private handleLinearElementOnPointerDown; private createGenericElementOnPointerDown; private onKeyDownFromPointerDownHandler; private onKeyUpFromPointerDownHandler; private onPointerMoveFromPointerDownHandler; private handlePointerMoveOverScrollbars; private onPointerUpFromPointerDownHandler; private restoreReadyToEraseElements; private eraseElements; private initializeImage; /** * inserts image into elements array and rerenders */ private insertImageElement; private setImagePreviewCursor; private onImageAction; private initializeImageDimensions; /** updates image cache, refreshing updated elements and/or setting status to error for images that fail during element creation */ private updateImageCache; /** adds new images to imageCache and re-renders if needed */ private addNewImagesToImageCache; /** generally you should use `addNewImagesToImageCache()` directly if you need * to render new images. This is just a failsafe */ private scheduleImageRefresh; private updateBindingEnabledOnPointerMove; private maybeSuggestBindingAtCursor; private maybeSuggestBindingsForLinearElementAtCoords; private maybeSuggestBindingForAll; private clearSelection; private handleCanvasRef; private handleAppOnDrop; loadFileToCanvas: (file: File, fileHandle: FileSystemHandle | null) => Promise; private handleCanvasContextMenu; private maybeDragNewGenericElement; private maybeHandleResize; /** @private use this.handleCanvasContextMenu */ private _openContextMenu; private handleWheel; private getTextWysiwygSnappedToCenterPosition; private savePointer; private resetShouldCacheIgnoreZoomDebounced; private updateDOMRect; private getCanvasOffsets; private updateLanguage; } declare global { interface Window { h: { elements: readonly ExcalidrawElement[]; state: AppState; setState: React.Component["setState"]; app: InstanceType; history: History; }; } } export default App;