From 72a3450c998c6353acbd66d4093ba156ea52e93f Mon Sep 17 00:00:00 2001 From: David Luzar Date: Fri, 23 Oct 2020 19:06:16 +0200 Subject: [PATCH] allow to supply canvas offsets from upstream (#2271) --- src/components/App.tsx | 63 +++++-- src/excalidraw-embed/index.tsx | 4 + src/index.tsx | 2 + .../regressionTests.test.tsx.snap | 166 +++++++++--------- src/tests/regressionTests.test.tsx | 2 +- src/types.ts | 4 + 6 files changed, 140 insertions(+), 101 deletions(-) diff --git a/src/components/App.tsx b/src/components/App.tsx index 3d19938c..4a472805 100644 --- a/src/components/App.tsx +++ b/src/components/App.tsx @@ -294,14 +294,14 @@ class App extends React.Component { super(props); const defaultAppState = getDefaultAppState(); - const { width, height, user, forwardedRef } = props; + const { width, height, offsetLeft, offsetTop, user, forwardedRef } = props; this.state = { ...defaultAppState, isLoading: true, width, height, username: user?.name || "", - ...this.getCanvasOffsets(), + ...this.getCanvasOffsets({ offsetLeft, offsetTop }), }; if (forwardedRef && "current" in forwardedRef) { forwardedRef.current = { @@ -702,9 +702,18 @@ class App extends React.Component { this.scene.addCallback(this.onSceneUpdated); this.addEventListeners(); - this.setState(this.getCanvasOffsets(), () => { + + // optim to avoid extra render on init + if ( + typeof this.props.offsetLeft === "number" && + typeof this.props.offsetTop === "number" + ) { this.initializeScene(); - }); + } else { + this.setState(this.getCanvasOffsets(this.props), () => { + this.initializeScene(); + }); + } } public componentWillUnmount() { @@ -838,13 +847,18 @@ class App extends React.Component { }, SYNC_FULL_SCENE_INTERVAL_MS); componentDidUpdate(prevProps: ExcalidrawProps, prevState: AppState) { - const { width: prevWidth, height: prevHeight } = prevProps; - const { width: currentWidth, height: currentHeight, onChange } = this.props; - if (prevWidth !== currentWidth || prevHeight !== currentHeight) { + if ( + prevProps.width !== this.props.width || + prevProps.height !== this.props.height || + (typeof this.props.offsetLeft === "number" && + prevProps.offsetLeft !== this.props.offsetLeft) || + (typeof this.props.offsetTop === "number" && + prevProps.offsetTop !== this.props.offsetTop) + ) { this.setState({ - width: currentWidth, - height: currentHeight, - ...this.getCanvasOffsets(), + width: this.props.width, + height: this.props.height, + ...this.getCanvasOffsets(this.props), }); } @@ -966,8 +980,8 @@ class App extends React.Component { history.record(this.state, this.scene.getElementsIncludingDeleted()); - if (onChange) { - onChange(this.scene.getElementsIncludingDeleted(), this.state); + if (this.props.onChange) { + this.props.onChange(this.scene.getElementsIncludingDeleted(), this.state); } } @@ -3964,18 +3978,33 @@ class App extends React.Component { this.setState({ shouldCacheIgnoreZoom: false }); }, 300); - private getCanvasOffsets(): Pick { + private getCanvasOffsets(offsets?: { + offsetLeft?: number; + offsetTop?: number; + }): Pick { + if ( + typeof offsets?.offsetLeft === "number" && + typeof offsets?.offsetTop === "number" + ) { + return { + offsetLeft: offsets.offsetLeft, + offsetTop: offsets.offsetTop, + }; + } if (this.excalidrawRef?.current) { const parentElement = this.excalidrawRef.current.parentElement; const { left, top } = parentElement.getBoundingClientRect(); return { - offsetLeft: left, - offsetTop: top, + offsetLeft: + typeof offsets?.offsetLeft === "number" ? offsets.offsetLeft : left, + offsetTop: + typeof offsets?.offsetTop === "number" ? offsets.offsetTop : top, }; } return { - offsetLeft: 0, - offsetTop: 0, + offsetLeft: + typeof offsets?.offsetLeft === "number" ? offsets.offsetLeft : 0, + offsetTop: typeof offsets?.offsetTop === "number" ? offsets.offsetTop : 0, }; } } diff --git a/src/excalidraw-embed/index.tsx b/src/excalidraw-embed/index.tsx index b02bfba3..c07608e3 100644 --- a/src/excalidraw-embed/index.tsx +++ b/src/excalidraw-embed/index.tsx @@ -13,6 +13,8 @@ const Excalidraw = (props: ExcalidrawProps) => { const { width, height, + offsetLeft, + offsetTop, onChange, initialData, user, @@ -44,6 +46,8 @@ const Excalidraw = (props: ExcalidrawProps) => { { finger2.reset(); await setLanguage("en.json"); - render(); + render(); }); afterEach(() => { diff --git a/src/types.ts b/src/types.ts index 2578829d..ffd08a30 100644 --- a/src/types.ts +++ b/src/types.ts @@ -126,6 +126,10 @@ export type LibraryItems = readonly LibraryItem[]; export interface ExcalidrawProps { width: number; height: number; + /** if not supplied, calculated by Excalidraw */ + offsetLeft?: number; + /** if not supplied, calculated by Excalidraw */ + offsetTop?: number; onChange?: ( elements: readonly ExcalidrawElement[], appState: AppState,