diff --git a/src/actions/actionExport.tsx b/src/actions/actionExport.tsx index eb8985ed..5258f87a 100644 --- a/src/actions/actionExport.tsx +++ b/src/actions/actionExport.tsx @@ -135,7 +135,7 @@ export const actionLoadScene = register({ commitToHistory: false, }; }, - PanelComponent: ({ updateData }) => ( + PanelComponent: ({ updateData, appState }) => ( { - loadFromJSON() + loadFromJSON(appState) .then(({ elements, appState }) => { updateData({ elements: elements, appState: appState }); }) diff --git a/src/actions/types.ts b/src/actions/types.ts index f2642192..fbe7fba3 100644 --- a/src/actions/types.ts +++ b/src/actions/types.ts @@ -6,7 +6,7 @@ import { AppState } from "../types"; export type ActionResult = | { elements?: readonly ExcalidrawElement[] | null; - appState?: AppState | null; + appState?: MarkOptional | null; commitToHistory: boolean; syncHistory?: boolean; } diff --git a/src/appState.ts b/src/appState.ts index 76d21281..4bd24cec 100644 --- a/src/appState.ts +++ b/src/appState.ts @@ -8,7 +8,10 @@ import { DEFAULT_TEXT_ALIGN, } from "./constants"; -export const getDefaultAppState = (): AppState => { +export const getDefaultAppState = (): Omit< + AppState, + "offsetTop" | "offsetLeft" +> => { return { isLoading: false, errorMessage: null, @@ -126,6 +129,8 @@ const APP_STATE_STORAGE_CONF = (< width: { browser: false, export: false }, zenModeEnabled: { browser: true, export: false }, zoom: { browser: true, export: false }, + offsetTop: { browser: false, export: false }, + offsetLeft: { browser: false, export: false }, }); const _clearAppStateForStorage = ( diff --git a/src/components/App.tsx b/src/components/App.tsx index 28414d21..2ffb91c5 100644 --- a/src/components/App.tsx +++ b/src/components/App.tsx @@ -3,7 +3,7 @@ import React from "react"; import rough from "roughjs/bin/rough"; import { RoughCanvas } from "roughjs/bin/canvas"; import { simplify, Point } from "points-on-curve"; -import { FlooredNumber, SocketUpdateData } from "../types"; +import { SocketUpdateData } from "../types"; import { newElement, @@ -244,6 +244,7 @@ class App extends React.Component { removeSceneCallback: SceneStateCallbackRemover | null = null; unmounted: boolean = false; actionManager: ActionManager; + private excalidrawRef: any; public static defaultProps: Partial = { width: window.innerWidth, @@ -260,8 +261,10 @@ class App extends React.Component { isLoading: true, width, height, + ...this.getCanvasOffsets(), }; + this.excalidrawRef = React.createRef(); this.actionManager = new ActionManager( this.syncActionResult, () => this.state, @@ -278,6 +281,8 @@ class App extends React.Component { zenModeEnabled, width: canvasDOMWidth, height: canvasDOMHeight, + offsetTop, + offsetLeft, } = this.state; const canvasScale = window.devicePixelRatio; @@ -286,7 +291,16 @@ class App extends React.Component { const canvasHeight = canvasDOMHeight * canvasScale; return ( -
+
{ editingElement || actionResult.appState?.editingElement || null, isCollaborating: state.isCollaborating, collaborators: state.collaborators, + width: state.width, + height: state.height, + offsetTop: state.offsetTop, + offsetLeft: state.offsetLeft, }), () => { if (actionResult.syncHistory) { @@ -498,6 +516,20 @@ class App extends React.Component { if (isCollaborationScene) { this.initializeSocketClient({ showLoadingState: true }); } else if (scene) { + if (scene.appState) { + scene.appState = { + ...scene.appState, + ...calculateScrollCenter( + scene.elements, + { + ...scene.appState, + offsetTop: this.state.offsetTop, + offsetLeft: this.state.offsetLeft, + }, + null, + ), + }; + } this.syncActionResult(scene); } }; @@ -533,7 +565,9 @@ class App extends React.Component { ); this.addEventListeners(); - this.initializeScene(); + this.setState(this.getCanvasOffsets(), () => { + this.initializeScene(); + }); } public componentWillUnmount() { @@ -667,6 +701,7 @@ class App extends React.Component { this.setState({ width: currentWidth, height: currentHeight, + ...this.getCanvasOffsets(), }); } @@ -1548,10 +1583,13 @@ class App extends React.Component { textWysiwyg({ id: element.id, - zoom: this.state.zoom, + appState: this.state, getViewportCoords: (x, y) => { const { x: viewportX, y: viewportY } = sceneCoordsToViewportCoords( - { sceneX: x, sceneY: y }, + { + sceneX: x, + sceneY: y, + }, this.state, this.canvas, window.devicePixelRatio, @@ -3185,7 +3223,7 @@ class App extends React.Component { file?.name.endsWith(".excalidraw") ) { this.setState({ isLoading: true }); - loadFromBlob(file) + loadFromBlob(file, this.state) .then(({ elements, appState }) => this.syncActionResult({ elements, @@ -3349,11 +3387,7 @@ class App extends React.Component { private getTextWysiwygSnappedToCenterPosition( x: number, y: number, - state: { - scrollX: FlooredNumber; - scrollY: FlooredNumber; - zoom: number; - }, + appState: AppState, canvas: HTMLCanvasElement | null, scale: number, ) { @@ -3378,7 +3412,7 @@ class App extends React.Component { if (isSnappedToCenter) { const { x: viewportX, y: viewportY } = sceneCoordsToViewportCoords( { sceneX: elementCenterX, sceneY: elementCenterY }, - state, + appState, canvas, scale, ); @@ -3421,6 +3455,21 @@ class App extends React.Component { this.state, ); }, 300); + + private getCanvasOffsets() { + if (this.excalidrawRef?.current) { + const parentElement = this.excalidrawRef.current.parentElement; + const { left, top } = parentElement.getBoundingClientRect(); + return { + offsetLeft: left, + offsetTop: top, + }; + } + return { + offsetLeft: 0, + offsetTop: 0, + }; + } } // ----------------------------------------------------------------------------- diff --git a/src/data/blob.ts b/src/data/blob.ts index e7e63de3..9a87355d 100644 --- a/src/data/blob.ts +++ b/src/data/blob.ts @@ -2,28 +2,13 @@ import { getDefaultAppState, cleanAppStateForExport } from "../appState"; import { restore } from "./restore"; import { t } from "../i18n"; import { AppState } from "../types"; +import { calculateScrollCenter } from "../scene"; -export const loadFromBlob = async (blob: any) => { - const updateAppState = (contents: string) => { - const defaultAppState = getDefaultAppState(); - let elements = []; - let appState = defaultAppState; - try { - const data = JSON.parse(contents); - if (data.type !== "excalidraw") { - throw new Error(t("alerts.couldNotLoadInvalidFile")); - } - elements = data.elements || []; - appState = { - ...defaultAppState, - ...cleanAppStateForExport(data.appState as Partial), - }; - } catch { - throw new Error(t("alerts.couldNotLoadInvalidFile")); - } - return { elements, appState }; - }; - +/** + * @param blob + * @param appState if provided, used for centering scroll to restored scene + */ +export const loadFromBlob = async (blob: any, appState?: AppState) => { if (blob.handle) { (window as any).handle = blob.handle; } @@ -42,6 +27,23 @@ export const loadFromBlob = async (blob: any) => { }); } - const { elements, appState } = updateAppState(contents); - return restore(elements, appState, { scrollToContent: true }); + const defaultAppState = getDefaultAppState(); + let elements = []; + let _appState = appState || defaultAppState; + try { + const data = JSON.parse(contents); + if (data.type !== "excalidraw") { + throw new Error(t("alerts.couldNotLoadInvalidFile")); + } + elements = data.elements || []; + _appState = { + ...defaultAppState, + ...cleanAppStateForExport(data.appState as Partial), + ...(appState ? calculateScrollCenter(elements, appState, null) : {}), + }; + } catch { + throw new Error(t("alerts.couldNotLoadInvalidFile")); + } + + return restore(elements, _appState); }; diff --git a/src/data/index.ts b/src/data/index.ts index 47e81c29..6f2dc9b0 100644 --- a/src/data/index.ts +++ b/src/data/index.ts @@ -237,7 +237,7 @@ export const importFromBackend = async ( privateKey: string | undefined, ) => { let elements: readonly ExcalidrawElement[] = []; - let appState: AppState = getDefaultAppState(); + let appState = getDefaultAppState(); try { const response = await fetch( @@ -245,7 +245,7 @@ export const importFromBackend = async ( ); if (!response.ok) { window.alert(t("alerts.importBackendFailed")); - return restore(elements, appState, { scrollToContent: true }); + return restore(elements, appState); } let data; if (privateKey) { @@ -276,7 +276,7 @@ export const importFromBackend = async ( window.alert(t("alerts.importBackendFailed")); console.error(error); } finally { - return restore(elements, appState, { scrollToContent: true }); + return restore(elements, appState); } }; diff --git a/src/data/json.ts b/src/data/json.ts index 3dbadde5..42a78861 100644 --- a/src/data/json.ts +++ b/src/data/json.ts @@ -42,11 +42,11 @@ export const saveAsJSON = async ( ); }; -export const loadFromJSON = async () => { +export const loadFromJSON = async (appState: AppState) => { const blob = await fileOpen({ description: "Excalidraw files", extensions: ["json", "excalidraw"], mimeTypes: ["application/json"], }); - return loadFromBlob(blob); + return loadFromBlob(blob, appState); }; diff --git a/src/data/restore.ts b/src/data/restore.ts index 0413e914..e3cfc9eb 100644 --- a/src/data/restore.ts +++ b/src/data/restore.ts @@ -6,7 +6,6 @@ import { import { AppState } from "../types"; import { DataState } from "./types"; import { isInvisiblySmallElement, getNormalizedDimensions } from "../element"; -import { calculateScrollCenter } from "../scene"; import { randomId } from "../random"; import { FONT_FAMILY, @@ -110,8 +109,7 @@ const migrateElement = ( export const restore = ( savedElements: readonly ExcalidrawElement[], - savedState: AppState | null, - opts?: { scrollToContent: boolean }, + savedState: MarkOptional | null, ): DataState => { const elements = savedElements.reduce((elements, element) => { // filtering out selection, which is legacy, no longer kept in elements, @@ -125,13 +123,6 @@ export const restore = ( return elements; }, [] as ExcalidrawElement[]); - if (opts?.scrollToContent && savedState) { - savedState = { - ...savedState, - ...calculateScrollCenter(elements, savedState, null), - }; - } - return { elements: elements, appState: savedState, diff --git a/src/data/types.ts b/src/data/types.ts index 7d0166cc..f29e7d82 100644 --- a/src/data/types.ts +++ b/src/data/types.ts @@ -6,5 +6,5 @@ export interface DataState { version?: string; source?: string; elements: readonly ExcalidrawElement[]; - appState: AppState | null; + appState: MarkOptional | null; } diff --git a/src/element/textWysiwyg.tsx b/src/element/textWysiwyg.tsx index 6b77dbbf..1530baa2 100644 --- a/src/element/textWysiwyg.tsx +++ b/src/element/textWysiwyg.tsx @@ -4,6 +4,7 @@ import { globalSceneState } from "../scene"; import { isTextElement } from "./typeChecks"; import { CLASSES } from "../constants"; import { ExcalidrawElement } from "./types"; +import { AppState } from "../types"; const normalizeText = (text: string) => { return ( @@ -19,23 +20,26 @@ const getTransform = ( width: number, height: number, angle: number, - zoom: number, + appState: AppState, ) => { + const { zoom, offsetTop, offsetLeft } = appState; const degree = (180 * angle) / Math.PI; - return `translate(${(width * (zoom - 1)) / 2}px, ${ - (height * (zoom - 1)) / 2 + // offsets must be multiplied by 2 to account for the division by 2 of + // the whole expression afterwards + return `translate(${((width - offsetLeft * 2) * (zoom - 1)) / 2}px, ${ + ((height - offsetTop * 2) * (zoom - 1)) / 2 }px) scale(${zoom}) rotate(${degree}deg)`; }; export const textWysiwyg = ({ id, - zoom, + appState, onChange, onSubmit, getViewportCoords, }: { id: ExcalidrawElement["id"]; - zoom: number; + appState: AppState; onChange?: (text: string) => void; onSubmit: (text: string) => void; getViewportCoords: (x: number, y: number) => [number, number]; @@ -66,7 +70,7 @@ export const textWysiwyg = ({ updatedElement.width, updatedElement.height, angle, - zoom, + appState, ), textAlign: textAlign, color: updatedElement.strokeColor, diff --git a/src/index-node.ts b/src/index-node.ts index 47f732d1..6267bef3 100644 --- a/src/index-node.ts +++ b/src/index-node.ts @@ -59,7 +59,11 @@ registerFont("./public/Cascadia.ttf", { family: "Cascadia" }); const canvas = exportToCanvas( elements as any, - getDefaultAppState(), + { + ...getDefaultAppState(), + offsetTop: 0, + offsetLeft: 0, + }, { exportBackground: true, viewBackgroundColor: "#ffffff", diff --git a/src/scene/scroll.ts b/src/scene/scroll.ts index 1a6ecb8c..75756a2e 100644 --- a/src/scene/scroll.ts +++ b/src/scene/scroll.ts @@ -47,6 +47,7 @@ export const calculateScrollCenter = ( } const scale = window.devicePixelRatio; let [x1, y1, x2, y2] = getCommonBounds(elements); + if (isOutsideViewPort(appState, canvas, [x1, y1, x2, y2])) { [x1, y1, x2, y2] = getClosestElementBounds( elements, diff --git a/src/tests/__snapshots__/regressionTests.test.tsx.snap b/src/tests/__snapshots__/regressionTests.test.tsx.snap index 31c87858..1d9a1e80 100644 --- a/src/tests/__snapshots__/regressionTests.test.tsx.snap +++ b/src/tests/__snapshots__/regressionTests.test.tsx.snap @@ -34,6 +34,8 @@ Object { "lastPointerDownWith": "mouse", "multiElement": null, "name": "Untitled-201933152653", + "offsetLeft": 0, + "offsetTop": 0, "openMenu": null, "previousSelectedElementIds": Object { "id0": true, @@ -399,7 +401,7 @@ Object { exports[`regression tests adjusts z order when grouping: [end of test] number of elements 1`] = `3`; -exports[`regression tests adjusts z order when grouping: [end of test] number of renders 1`] = `19`; +exports[`regression tests adjusts z order when grouping: [end of test] number of renders 1`] = `20`; exports[`regression tests alt-drag duplicates an element: [end of test] appState 1`] = ` Object { @@ -435,6 +437,8 @@ Object { "lastPointerDownWith": "mouse", "multiElement": null, "name": "Untitled-201933152653", + "offsetLeft": 0, + "offsetTop": 0, "openMenu": null, "previousSelectedElementIds": Object { "id0": true, @@ -609,7 +613,7 @@ Object { exports[`regression tests alt-drag duplicates an element: [end of test] number of elements 1`] = `2`; -exports[`regression tests alt-drag duplicates an element: [end of test] number of renders 1`] = `9`; +exports[`regression tests alt-drag duplicates an element: [end of test] number of renders 1`] = `10`; exports[`regression tests arrow keys: [end of test] appState 1`] = ` Object { @@ -645,6 +649,8 @@ Object { "lastPointerDownWith": "mouse", "multiElement": null, "name": "Untitled-201933152653", + "offsetLeft": 0, + "offsetTop": 0, "openMenu": null, "previousSelectedElementIds": Object {}, "resizingElement": null, @@ -736,7 +742,7 @@ Object { exports[`regression tests arrow keys: [end of test] number of elements 1`] = `1`; -exports[`regression tests arrow keys: [end of test] number of renders 1`] = `12`; +exports[`regression tests arrow keys: [end of test] number of renders 1`] = `13`; exports[`regression tests change the properties of a shape: [end of test] appState 1`] = ` Object { @@ -772,6 +778,8 @@ Object { "lastPointerDownWith": "mouse", "multiElement": null, "name": "Untitled-201933152653", + "offsetLeft": 0, + "offsetTop": 0, "openMenu": null, "previousSelectedElementIds": Object {}, "resizingElement": null, @@ -999,7 +1007,7 @@ Object { exports[`regression tests change the properties of a shape: [end of test] number of elements 1`] = `1`; -exports[`regression tests change the properties of a shape: [end of test] number of renders 1`] = `10`; +exports[`regression tests change the properties of a shape: [end of test] number of renders 1`] = `11`; exports[`regression tests click on an element and drag it: [dragged] appState 1`] = ` Object { @@ -1035,6 +1043,8 @@ Object { "lastPointerDownWith": "mouse", "multiElement": null, "name": "Untitled-201933152653", + "offsetLeft": 0, + "offsetTop": 0, "openMenu": null, "previousSelectedElementIds": Object { "id0": true, @@ -1164,7 +1174,7 @@ Object { exports[`regression tests click on an element and drag it: [dragged] number of elements 1`] = `1`; -exports[`regression tests click on an element and drag it: [dragged] number of renders 1`] = `9`; +exports[`regression tests click on an element and drag it: [dragged] number of renders 1`] = `10`; exports[`regression tests click on an element and drag it: [end of test] appState 1`] = ` Object { @@ -1200,6 +1210,8 @@ Object { "lastPointerDownWith": "mouse", "multiElement": null, "name": "Untitled-201933152653", + "offsetLeft": 0, + "offsetTop": 0, "openMenu": null, "previousSelectedElementIds": Object { "id0": true, @@ -1367,7 +1379,7 @@ Object { exports[`regression tests click on an element and drag it: [end of test] number of elements 1`] = `1`; -exports[`regression tests click on an element and drag it: [end of test] number of renders 1`] = `12`; +exports[`regression tests click on an element and drag it: [end of test] number of renders 1`] = `13`; exports[`regression tests click to select a shape: [end of test] appState 1`] = ` Object { @@ -1403,6 +1415,8 @@ Object { "lastPointerDownWith": "mouse", "multiElement": null, "name": "Untitled-201933152653", + "offsetLeft": 0, + "offsetTop": 0, "openMenu": null, "previousSelectedElementIds": Object { "id1": true, @@ -1576,7 +1590,7 @@ Object { exports[`regression tests click to select a shape: [end of test] number of elements 1`] = `2`; -exports[`regression tests click to select a shape: [end of test] number of renders 1`] = `12`; +exports[`regression tests click to select a shape: [end of test] number of renders 1`] = `13`; exports[`regression tests click-drag to select a group: [end of test] appState 1`] = ` Object { @@ -1612,6 +1626,8 @@ Object { "lastPointerDownWith": "mouse", "multiElement": null, "name": "Untitled-201933152653", + "offsetLeft": 0, + "offsetTop": 0, "openMenu": null, "previousSelectedElementIds": Object { "id2": true, @@ -1886,7 +1902,7 @@ Object { exports[`regression tests click-drag to select a group: [end of test] number of elements 1`] = `3`; -exports[`regression tests click-drag to select a group: [end of test] number of renders 1`] = `18`; +exports[`regression tests click-drag to select a group: [end of test] number of renders 1`] = `19`; exports[`regression tests double click to edit a group: [end of test] appState 1`] = ` Object { @@ -1922,6 +1938,8 @@ Object { "lastPointerDownWith": "mouse", "multiElement": null, "name": "Untitled-201933152653", + "offsetLeft": 0, + "offsetTop": 0, "openMenu": null, "previousSelectedElementIds": Object {}, "resizingElement": null, @@ -2282,7 +2300,7 @@ Object { exports[`regression tests double click to edit a group: [end of test] number of elements 1`] = `3`; -exports[`regression tests double click to edit a group: [end of test] number of renders 1`] = `17`; +exports[`regression tests double click to edit a group: [end of test] number of renders 1`] = `18`; exports[`regression tests draw every type of shape: [end of test] appState 1`] = ` Object { @@ -2318,6 +2336,8 @@ Object { "lastPointerDownWith": "mouse", "multiElement": null, "name": "Untitled-201933152653", + "offsetLeft": 0, + "offsetTop": 0, "openMenu": null, "previousSelectedElementIds": Object {}, "resizingElement": null, @@ -4071,7 +4091,7 @@ Object { exports[`regression tests draw every type of shape: [end of test] number of elements 1`] = `8`; -exports[`regression tests draw every type of shape: [end of test] number of renders 1`] = `46`; +exports[`regression tests draw every type of shape: [end of test] number of renders 1`] = `47`; exports[`regression tests hotkey 2 selects rectangle tool: [end of test] appState 1`] = ` Object { @@ -4107,6 +4127,8 @@ Object { "lastPointerDownWith": "mouse", "multiElement": null, "name": "Untitled-201933152653", + "offsetLeft": 0, + "offsetTop": 0, "openMenu": null, "previousSelectedElementIds": Object {}, "resizingElement": null, @@ -4198,7 +4220,7 @@ Object { exports[`regression tests hotkey 2 selects rectangle tool: [end of test] number of elements 1`] = `1`; -exports[`regression tests hotkey 2 selects rectangle tool: [end of test] number of renders 1`] = `6`; +exports[`regression tests hotkey 2 selects rectangle tool: [end of test] number of renders 1`] = `7`; exports[`regression tests hotkey 3 selects diamond tool: [end of test] appState 1`] = ` Object { @@ -4234,6 +4256,8 @@ Object { "lastPointerDownWith": "mouse", "multiElement": null, "name": "Untitled-201933152653", + "offsetLeft": 0, + "offsetTop": 0, "openMenu": null, "previousSelectedElementIds": Object {}, "resizingElement": null, @@ -4325,7 +4349,7 @@ Object { exports[`regression tests hotkey 3 selects diamond tool: [end of test] number of elements 1`] = `1`; -exports[`regression tests hotkey 3 selects diamond tool: [end of test] number of renders 1`] = `6`; +exports[`regression tests hotkey 3 selects diamond tool: [end of test] number of renders 1`] = `7`; exports[`regression tests hotkey 4 selects ellipse tool: [end of test] appState 1`] = ` Object { @@ -4361,6 +4385,8 @@ Object { "lastPointerDownWith": "mouse", "multiElement": null, "name": "Untitled-201933152653", + "offsetLeft": 0, + "offsetTop": 0, "openMenu": null, "previousSelectedElementIds": Object {}, "resizingElement": null, @@ -4452,7 +4478,7 @@ Object { exports[`regression tests hotkey 4 selects ellipse tool: [end of test] number of elements 1`] = `1`; -exports[`regression tests hotkey 4 selects ellipse tool: [end of test] number of renders 1`] = `6`; +exports[`regression tests hotkey 4 selects ellipse tool: [end of test] number of renders 1`] = `7`; exports[`regression tests hotkey 5 selects arrow tool: [end of test] appState 1`] = ` Object { @@ -4488,6 +4514,8 @@ Object { "lastPointerDownWith": "mouse", "multiElement": null, "name": "Untitled-201933152653", + "offsetLeft": 0, + "offsetTop": 0, "openMenu": null, "previousSelectedElementIds": Object {}, "resizingElement": null, @@ -4601,7 +4629,7 @@ Object { exports[`regression tests hotkey 5 selects arrow tool: [end of test] number of elements 1`] = `1`; -exports[`regression tests hotkey 5 selects arrow tool: [end of test] number of renders 1`] = `6`; +exports[`regression tests hotkey 5 selects arrow tool: [end of test] number of renders 1`] = `7`; exports[`regression tests hotkey 6 selects line tool: [end of test] appState 1`] = ` Object { @@ -4637,6 +4665,8 @@ Object { "lastPointerDownWith": "mouse", "multiElement": null, "name": "Untitled-201933152653", + "offsetLeft": 0, + "offsetTop": 0, "openMenu": null, "previousSelectedElementIds": Object {}, "resizingElement": null, @@ -4750,7 +4780,7 @@ Object { exports[`regression tests hotkey 6 selects line tool: [end of test] number of elements 1`] = `1`; -exports[`regression tests hotkey 6 selects line tool: [end of test] number of renders 1`] = `6`; +exports[`regression tests hotkey 6 selects line tool: [end of test] number of renders 1`] = `7`; exports[`regression tests hotkey 7 selects draw tool: [end of test] appState 1`] = ` Object { @@ -4786,6 +4816,8 @@ Object { "lastPointerDownWith": "mouse", "multiElement": null, "name": "Untitled-201933152653", + "offsetLeft": 0, + "offsetTop": 0, "openMenu": null, "previousSelectedElementIds": Object {}, "resizingElement": null, @@ -4899,7 +4931,7 @@ Object { exports[`regression tests hotkey 7 selects draw tool: [end of test] number of elements 1`] = `1`; -exports[`regression tests hotkey 7 selects draw tool: [end of test] number of renders 1`] = `6`; +exports[`regression tests hotkey 7 selects draw tool: [end of test] number of renders 1`] = `7`; exports[`regression tests hotkey a selects arrow tool: [end of test] appState 1`] = ` Object { @@ -4935,6 +4967,8 @@ Object { "lastPointerDownWith": "mouse", "multiElement": null, "name": "Untitled-201933152653", + "offsetLeft": 0, + "offsetTop": 0, "openMenu": null, "previousSelectedElementIds": Object {}, "resizingElement": null, @@ -5048,7 +5082,7 @@ Object { exports[`regression tests hotkey a selects arrow tool: [end of test] number of elements 1`] = `1`; -exports[`regression tests hotkey a selects arrow tool: [end of test] number of renders 1`] = `6`; +exports[`regression tests hotkey a selects arrow tool: [end of test] number of renders 1`] = `7`; exports[`regression tests hotkey d selects diamond tool: [end of test] appState 1`] = ` Object { @@ -5084,6 +5118,8 @@ Object { "lastPointerDownWith": "mouse", "multiElement": null, "name": "Untitled-201933152653", + "offsetLeft": 0, + "offsetTop": 0, "openMenu": null, "previousSelectedElementIds": Object {}, "resizingElement": null, @@ -5175,7 +5211,7 @@ Object { exports[`regression tests hotkey d selects diamond tool: [end of test] number of elements 1`] = `1`; -exports[`regression tests hotkey d selects diamond tool: [end of test] number of renders 1`] = `6`; +exports[`regression tests hotkey d selects diamond tool: [end of test] number of renders 1`] = `7`; exports[`regression tests hotkey e selects ellipse tool: [end of test] appState 1`] = ` Object { @@ -5211,6 +5247,8 @@ Object { "lastPointerDownWith": "mouse", "multiElement": null, "name": "Untitled-201933152653", + "offsetLeft": 0, + "offsetTop": 0, "openMenu": null, "previousSelectedElementIds": Object {}, "resizingElement": null, @@ -5302,7 +5340,7 @@ Object { exports[`regression tests hotkey e selects ellipse tool: [end of test] number of elements 1`] = `1`; -exports[`regression tests hotkey e selects ellipse tool: [end of test] number of renders 1`] = `6`; +exports[`regression tests hotkey e selects ellipse tool: [end of test] number of renders 1`] = `7`; exports[`regression tests hotkey l selects line tool: [end of test] appState 1`] = ` Object { @@ -5338,6 +5376,8 @@ Object { "lastPointerDownWith": "mouse", "multiElement": null, "name": "Untitled-201933152653", + "offsetLeft": 0, + "offsetTop": 0, "openMenu": null, "previousSelectedElementIds": Object {}, "resizingElement": null, @@ -5451,7 +5491,7 @@ Object { exports[`regression tests hotkey l selects line tool: [end of test] number of elements 1`] = `1`; -exports[`regression tests hotkey l selects line tool: [end of test] number of renders 1`] = `6`; +exports[`regression tests hotkey l selects line tool: [end of test] number of renders 1`] = `7`; exports[`regression tests hotkey r selects rectangle tool: [end of test] appState 1`] = ` Object { @@ -5487,6 +5527,8 @@ Object { "lastPointerDownWith": "mouse", "multiElement": null, "name": "Untitled-201933152653", + "offsetLeft": 0, + "offsetTop": 0, "openMenu": null, "previousSelectedElementIds": Object {}, "resizingElement": null, @@ -5578,7 +5620,7 @@ Object { exports[`regression tests hotkey r selects rectangle tool: [end of test] number of elements 1`] = `1`; -exports[`regression tests hotkey r selects rectangle tool: [end of test] number of renders 1`] = `6`; +exports[`regression tests hotkey r selects rectangle tool: [end of test] number of renders 1`] = `7`; exports[`regression tests hotkey x selects draw tool: [end of test] appState 1`] = ` Object { @@ -5614,6 +5656,8 @@ Object { "lastPointerDownWith": "mouse", "multiElement": null, "name": "Untitled-201933152653", + "offsetLeft": 0, + "offsetTop": 0, "openMenu": null, "previousSelectedElementIds": Object {}, "resizingElement": null, @@ -5727,7 +5771,7 @@ Object { exports[`regression tests hotkey x selects draw tool: [end of test] number of elements 1`] = `1`; -exports[`regression tests hotkey x selects draw tool: [end of test] number of renders 1`] = `6`; +exports[`regression tests hotkey x selects draw tool: [end of test] number of renders 1`] = `7`; exports[`regression tests make a group and duplicate it: [end of test] appState 1`] = ` Object { @@ -5763,6 +5807,8 @@ Object { "lastPointerDownWith": "mouse", "multiElement": null, "name": "Untitled-201933152653", + "offsetLeft": 0, + "offsetTop": 0, "openMenu": null, "previousSelectedElementIds": Object { "id0": true, @@ -6368,7 +6414,7 @@ Object { exports[`regression tests make a group and duplicate it: [end of test] number of elements 1`] = `6`; -exports[`regression tests make a group and duplicate it: [end of test] number of renders 1`] = `21`; +exports[`regression tests make a group and duplicate it: [end of test] number of renders 1`] = `22`; exports[`regression tests noop interaction after undo shouldn't create history entry: [end of test] appState 1`] = ` Object { @@ -6404,6 +6450,8 @@ Object { "lastPointerDownWith": "mouse", "multiElement": null, "name": "Untitled-201933152653", + "offsetLeft": 0, + "offsetTop": 0, "openMenu": null, "previousSelectedElementIds": Object { "id0": true, @@ -6578,7 +6626,7 @@ Object { exports[`regression tests noop interaction after undo shouldn't create history entry: [end of test] number of elements 1`] = `2`; -exports[`regression tests noop interaction after undo shouldn't create history entry: [end of test] number of renders 1`] = `18`; +exports[`regression tests noop interaction after undo shouldn't create history entry: [end of test] number of renders 1`] = `19`; exports[`regression tests pinch-to-zoom works: [end of test] appState 1`] = ` Object { @@ -6614,6 +6662,8 @@ Object { "lastPointerDownWith": "touch", "multiElement": null, "name": "Untitled-201933152653", + "offsetLeft": 0, + "offsetTop": 0, "openMenu": null, "previousSelectedElementIds": Object {}, "resizingElement": null, @@ -6646,7 +6696,7 @@ Object { exports[`regression tests pinch-to-zoom works: [end of test] number of elements 1`] = `0`; -exports[`regression tests pinch-to-zoom works: [end of test] number of renders 1`] = `8`; +exports[`regression tests pinch-to-zoom works: [end of test] number of renders 1`] = `9`; exports[`regression tests rerenders UI on language change: [end of test] appState 1`] = ` Object { @@ -6682,6 +6732,8 @@ Object { "lastPointerDownWith": "mouse", "multiElement": null, "name": "Untitled-201933152653", + "offsetLeft": 0, + "offsetTop": 0, "openMenu": null, "previousSelectedElementIds": Object {}, "resizingElement": null, @@ -6712,7 +6764,7 @@ Object { exports[`regression tests rerenders UI on language change: [end of test] number of elements 1`] = `0`; -exports[`regression tests rerenders UI on language change: [end of test] number of renders 1`] = `5`; +exports[`regression tests rerenders UI on language change: [end of test] number of renders 1`] = `6`; exports[`regression tests resize an element, trying every resize handle: [end of test] appState 1`] = ` Object { @@ -6748,6 +6800,8 @@ Object { "lastPointerDownWith": "mouse", "multiElement": null, "name": "Untitled-201933152653", + "offsetLeft": 0, + "offsetTop": 0, "openMenu": null, "previousSelectedElementIds": Object {}, "resizingElement": null, @@ -7535,7 +7589,7 @@ Object { exports[`regression tests resize an element, trying every resize handle: [end of test] number of elements 1`] = `1`; -exports[`regression tests resize an element, trying every resize handle: [end of test] number of renders 1`] = `54`; +exports[`regression tests resize an element, trying every resize handle: [end of test] number of renders 1`] = `55`; exports[`regression tests resize an element, trying every resize handle: [resize handle ne (+5, +5)] appState 1`] = ` Object { @@ -7571,6 +7625,8 @@ Object { "lastPointerDownWith": "mouse", "multiElement": null, "name": "Untitled-201933152653", + "offsetLeft": 0, + "offsetTop": 0, "openMenu": null, "previousSelectedElementIds": Object {}, "resizingElement": null, @@ -7935,7 +7991,7 @@ Object { exports[`regression tests resize an element, trying every resize handle: [resize handle ne (+5, +5)] number of elements 1`] = `1`; -exports[`regression tests resize an element, trying every resize handle: [resize handle ne (+5, +5)] number of renders 1`] = `27`; +exports[`regression tests resize an element, trying every resize handle: [resize handle ne (+5, +5)] number of renders 1`] = `28`; exports[`regression tests resize an element, trying every resize handle: [resize handle ne (-5, -5)] appState 1`] = ` Object { @@ -7971,6 +8027,8 @@ Object { "lastPointerDownWith": "mouse", "multiElement": null, "name": "Untitled-201933152653", + "offsetLeft": 0, + "offsetTop": 0, "openMenu": null, "previousSelectedElementIds": Object {}, "resizingElement": null, @@ -8252,7 +8310,7 @@ Object { exports[`regression tests resize an element, trying every resize handle: [resize handle ne (-5, -5)] number of elements 1`] = `1`; -exports[`regression tests resize an element, trying every resize handle: [resize handle ne (-5, -5)] number of renders 1`] = `21`; +exports[`regression tests resize an element, trying every resize handle: [resize handle ne (-5, -5)] number of renders 1`] = `22`; exports[`regression tests resize an element, trying every resize handle: [resize handle nw (+5, +5)] appState 1`] = ` Object { @@ -8288,6 +8346,8 @@ Object { "lastPointerDownWith": "mouse", "multiElement": null, "name": "Untitled-201933152653", + "offsetLeft": 0, + "offsetTop": 0, "openMenu": null, "previousSelectedElementIds": Object {}, "resizingElement": null, @@ -8490,7 +8550,7 @@ Object { exports[`regression tests resize an element, trying every resize handle: [resize handle nw (+5, +5)] number of elements 1`] = `1`; -exports[`regression tests resize an element, trying every resize handle: [resize handle nw (+5, +5)] number of renders 1`] = `15`; +exports[`regression tests resize an element, trying every resize handle: [resize handle nw (+5, +5)] number of renders 1`] = `16`; exports[`regression tests resize an element, trying every resize handle: [resize handle nw (-5, -5)] appState 1`] = ` Object { @@ -8526,6 +8586,8 @@ Object { "lastPointerDownWith": "mouse", "multiElement": null, "name": "Untitled-201933152653", + "offsetLeft": 0, + "offsetTop": 0, "openMenu": null, "previousSelectedElementIds": Object {}, "resizingElement": null, @@ -8653,7 +8715,7 @@ Object { exports[`regression tests resize an element, trying every resize handle: [resize handle nw (-5, -5)] number of elements 1`] = `1`; -exports[`regression tests resize an element, trying every resize handle: [resize handle nw (-5, -5)] number of renders 1`] = `9`; +exports[`regression tests resize an element, trying every resize handle: [resize handle nw (-5, -5)] number of renders 1`] = `10`; exports[`regression tests resize an element, trying every resize handle: [resize handle se (+5, +5)] appState 1`] = ` Object { @@ -8689,6 +8751,8 @@ Object { "lastPointerDownWith": "mouse", "multiElement": null, "name": "Untitled-201933152653", + "offsetLeft": 0, + "offsetTop": 0, "openMenu": null, "previousSelectedElementIds": Object {}, "resizingElement": null, @@ -9425,7 +9489,7 @@ Object { exports[`regression tests resize an element, trying every resize handle: [resize handle se (+5, +5)] number of elements 1`] = `1`; -exports[`regression tests resize an element, trying every resize handle: [resize handle se (+5, +5)] number of renders 1`] = `51`; +exports[`regression tests resize an element, trying every resize handle: [resize handle se (+5, +5)] number of renders 1`] = `52`; exports[`regression tests resize an element, trying every resize handle: [resize handle se (-5, -5)] appState 1`] = ` Object { @@ -9461,6 +9525,8 @@ Object { "lastPointerDownWith": "mouse", "multiElement": null, "name": "Untitled-201933152653", + "offsetLeft": 0, + "offsetTop": 0, "openMenu": null, "previousSelectedElementIds": Object {}, "resizingElement": null, @@ -10098,7 +10164,7 @@ Object { exports[`regression tests resize an element, trying every resize handle: [resize handle se (-5, -5)] number of elements 1`] = `1`; -exports[`regression tests resize an element, trying every resize handle: [resize handle se (-5, -5)] number of renders 1`] = `45`; +exports[`regression tests resize an element, trying every resize handle: [resize handle se (-5, -5)] number of renders 1`] = `46`; exports[`regression tests resize an element, trying every resize handle: [resize handle sw (+5, +5)] appState 1`] = ` Object { @@ -10134,6 +10200,8 @@ Object { "lastPointerDownWith": "mouse", "multiElement": null, "name": "Untitled-201933152653", + "offsetLeft": 0, + "offsetTop": 0, "openMenu": null, "previousSelectedElementIds": Object {}, "resizingElement": null, @@ -10676,7 +10744,7 @@ Object { exports[`regression tests resize an element, trying every resize handle: [resize handle sw (+5, +5)] number of elements 1`] = `1`; -exports[`regression tests resize an element, trying every resize handle: [resize handle sw (+5, +5)] number of renders 1`] = `39`; +exports[`regression tests resize an element, trying every resize handle: [resize handle sw (+5, +5)] number of renders 1`] = `40`; exports[`regression tests resize an element, trying every resize handle: [resize handle sw (-5, -5)] appState 1`] = ` Object { @@ -10712,6 +10780,8 @@ Object { "lastPointerDownWith": "mouse", "multiElement": null, "name": "Untitled-201933152653", + "offsetLeft": 0, + "offsetTop": 0, "openMenu": null, "previousSelectedElementIds": Object {}, "resizingElement": null, @@ -11163,7 +11233,7 @@ Object { exports[`regression tests resize an element, trying every resize handle: [resize handle sw (-5, -5)] number of elements 1`] = `1`; -exports[`regression tests resize an element, trying every resize handle: [resize handle sw (-5, -5)] number of renders 1`] = `33`; +exports[`regression tests resize an element, trying every resize handle: [resize handle sw (-5, -5)] number of renders 1`] = `34`; exports[`regression tests resize an element, trying every resize handle: [unresize handle ne (+5, +5)] appState 1`] = ` Object { @@ -11199,6 +11269,8 @@ Object { "lastPointerDownWith": "mouse", "multiElement": null, "name": "Untitled-201933152653", + "offsetLeft": 0, + "offsetTop": 0, "openMenu": null, "previousSelectedElementIds": Object {}, "resizingElement": null, @@ -11606,7 +11678,7 @@ Object { exports[`regression tests resize an element, trying every resize handle: [unresize handle ne (+5, +5)] number of elements 1`] = `1`; -exports[`regression tests resize an element, trying every resize handle: [unresize handle ne (+5, +5)] number of renders 1`] = `30`; +exports[`regression tests resize an element, trying every resize handle: [unresize handle ne (+5, +5)] number of renders 1`] = `31`; exports[`regression tests resize an element, trying every resize handle: [unresize handle ne (-5, -5)] appState 1`] = ` Object { @@ -11642,6 +11714,8 @@ Object { "lastPointerDownWith": "mouse", "multiElement": null, "name": "Untitled-201933152653", + "offsetLeft": 0, + "offsetTop": 0, "openMenu": null, "previousSelectedElementIds": Object {}, "resizingElement": null, @@ -11964,7 +12038,7 @@ Object { exports[`regression tests resize an element, trying every resize handle: [unresize handle ne (-5, -5)] number of elements 1`] = `1`; -exports[`regression tests resize an element, trying every resize handle: [unresize handle ne (-5, -5)] number of renders 1`] = `24`; +exports[`regression tests resize an element, trying every resize handle: [unresize handle ne (-5, -5)] number of renders 1`] = `25`; exports[`regression tests resize an element, trying every resize handle: [unresize handle nw (+5, +5)] appState 1`] = ` Object { @@ -12000,6 +12074,8 @@ Object { "lastPointerDownWith": "mouse", "multiElement": null, "name": "Untitled-201933152653", + "offsetLeft": 0, + "offsetTop": 0, "openMenu": null, "previousSelectedElementIds": Object {}, "resizingElement": null, @@ -12241,7 +12317,7 @@ Object { exports[`regression tests resize an element, trying every resize handle: [unresize handle nw (+5, +5)] number of elements 1`] = `1`; -exports[`regression tests resize an element, trying every resize handle: [unresize handle nw (+5, +5)] number of renders 1`] = `18`; +exports[`regression tests resize an element, trying every resize handle: [unresize handle nw (+5, +5)] number of renders 1`] = `19`; exports[`regression tests resize an element, trying every resize handle: [unresize handle nw (-5, -5)] appState 1`] = ` Object { @@ -12277,6 +12353,8 @@ Object { "lastPointerDownWith": "mouse", "multiElement": null, "name": "Untitled-201933152653", + "offsetLeft": 0, + "offsetTop": 0, "openMenu": null, "previousSelectedElementIds": Object {}, "resizingElement": null, @@ -12441,7 +12519,7 @@ Object { exports[`regression tests resize an element, trying every resize handle: [unresize handle nw (-5, -5)] number of elements 1`] = `1`; -exports[`regression tests resize an element, trying every resize handle: [unresize handle nw (-5, -5)] number of renders 1`] = `12`; +exports[`regression tests resize an element, trying every resize handle: [unresize handle nw (-5, -5)] number of renders 1`] = `13`; exports[`regression tests resize an element, trying every resize handle: [unresize handle se (+5, +5)] appState 1`] = ` Object { @@ -12477,6 +12555,8 @@ Object { "lastPointerDownWith": "mouse", "multiElement": null, "name": "Untitled-201933152653", + "offsetLeft": 0, + "offsetTop": 0, "openMenu": null, "previousSelectedElementIds": Object {}, "resizingElement": null, @@ -13264,7 +13344,7 @@ Object { exports[`regression tests resize an element, trying every resize handle: [unresize handle se (+5, +5)] number of elements 1`] = `1`; -exports[`regression tests resize an element, trying every resize handle: [unresize handle se (+5, +5)] number of renders 1`] = `54`; +exports[`regression tests resize an element, trying every resize handle: [unresize handle se (+5, +5)] number of renders 1`] = `55`; exports[`regression tests resize an element, trying every resize handle: [unresize handle se (-5, -5)] appState 1`] = ` Object { @@ -13300,6 +13380,8 @@ Object { "lastPointerDownWith": "mouse", "multiElement": null, "name": "Untitled-201933152653", + "offsetLeft": 0, + "offsetTop": 0, "openMenu": null, "previousSelectedElementIds": Object {}, "resizingElement": null, @@ -13986,7 +14068,7 @@ Object { exports[`regression tests resize an element, trying every resize handle: [unresize handle se (-5, -5)] number of elements 1`] = `1`; -exports[`regression tests resize an element, trying every resize handle: [unresize handle se (-5, -5)] number of renders 1`] = `48`; +exports[`regression tests resize an element, trying every resize handle: [unresize handle se (-5, -5)] number of renders 1`] = `49`; exports[`regression tests resize an element, trying every resize handle: [unresize handle sw (+5, +5)] appState 1`] = ` Object { @@ -14022,6 +14104,8 @@ Object { "lastPointerDownWith": "mouse", "multiElement": null, "name": "Untitled-201933152653", + "offsetLeft": 0, + "offsetTop": 0, "openMenu": null, "previousSelectedElementIds": Object {}, "resizingElement": null, @@ -14611,7 +14695,7 @@ Object { exports[`regression tests resize an element, trying every resize handle: [unresize handle sw (+5, +5)] number of elements 1`] = `1`; -exports[`regression tests resize an element, trying every resize handle: [unresize handle sw (+5, +5)] number of renders 1`] = `42`; +exports[`regression tests resize an element, trying every resize handle: [unresize handle sw (+5, +5)] number of renders 1`] = `43`; exports[`regression tests resize an element, trying every resize handle: [unresize handle sw (-5, -5)] appState 1`] = ` Object { @@ -14647,6 +14731,8 @@ Object { "lastPointerDownWith": "mouse", "multiElement": null, "name": "Untitled-201933152653", + "offsetLeft": 0, + "offsetTop": 0, "openMenu": null, "previousSelectedElementIds": Object {}, "resizingElement": null, @@ -15143,7 +15229,7 @@ Object { exports[`regression tests resize an element, trying every resize handle: [unresize handle sw (-5, -5)] number of elements 1`] = `1`; -exports[`regression tests resize an element, trying every resize handle: [unresize handle sw (-5, -5)] number of renders 1`] = `36`; +exports[`regression tests resize an element, trying every resize handle: [unresize handle sw (-5, -5)] number of renders 1`] = `37`; exports[`regression tests selecting 'Add to library' in context menu adds element to library: [end of test] appState 1`] = ` Object { @@ -15179,6 +15265,8 @@ Object { "lastPointerDownWith": "mouse", "multiElement": null, "name": "Untitled-201933152653", + "offsetLeft": 0, + "offsetTop": 0, "openMenu": null, "previousSelectedElementIds": Object {}, "resizingElement": null, @@ -15270,7 +15358,7 @@ Object { exports[`regression tests selecting 'Add to library' in context menu adds element to library: [end of test] number of elements 1`] = `1`; -exports[`regression tests selecting 'Add to library' in context menu adds element to library: [end of test] number of renders 1`] = `6`; +exports[`regression tests selecting 'Add to library' in context menu adds element to library: [end of test] number of renders 1`] = `7`; exports[`regression tests selecting 'Bring forward' in context menu brings element forward: [end of test] appState 1`] = ` Object { @@ -15306,6 +15394,8 @@ Object { "lastPointerDownWith": "mouse", "multiElement": null, "name": "Untitled-201933152653", + "offsetLeft": 0, + "offsetTop": 0, "openMenu": null, "previousSelectedElementIds": Object {}, "resizingElement": null, @@ -15531,7 +15621,7 @@ Object { exports[`regression tests selecting 'Bring forward' in context menu brings element forward: [end of test] number of elements 1`] = `2`; -exports[`regression tests selecting 'Bring forward' in context menu brings element forward: [end of test] number of renders 1`] = `12`; +exports[`regression tests selecting 'Bring forward' in context menu brings element forward: [end of test] number of renders 1`] = `13`; exports[`regression tests selecting 'Bring to front' in context menu brings element to front: [end of test] appState 1`] = ` Object { @@ -15567,6 +15657,8 @@ Object { "lastPointerDownWith": "mouse", "multiElement": null, "name": "Untitled-201933152653", + "offsetLeft": 0, + "offsetTop": 0, "openMenu": null, "previousSelectedElementIds": Object {}, "resizingElement": null, @@ -15792,7 +15884,7 @@ Object { exports[`regression tests selecting 'Bring to front' in context menu brings element to front: [end of test] number of elements 1`] = `2`; -exports[`regression tests selecting 'Bring to front' in context menu brings element to front: [end of test] number of renders 1`] = `12`; +exports[`regression tests selecting 'Bring to front' in context menu brings element to front: [end of test] number of renders 1`] = `13`; exports[`regression tests selecting 'Copy styles' in context menu copies styles: [end of test] appState 1`] = ` Object { @@ -15828,6 +15920,8 @@ Object { "lastPointerDownWith": "mouse", "multiElement": null, "name": "Untitled-201933152653", + "offsetLeft": 0, + "offsetTop": 0, "openMenu": null, "previousSelectedElementIds": Object {}, "resizingElement": null, @@ -15919,7 +16013,7 @@ Object { exports[`regression tests selecting 'Copy styles' in context menu copies styles: [end of test] number of elements 1`] = `1`; -exports[`regression tests selecting 'Copy styles' in context menu copies styles: [end of test] number of renders 1`] = `6`; +exports[`regression tests selecting 'Copy styles' in context menu copies styles: [end of test] number of renders 1`] = `7`; exports[`regression tests selecting 'Delete' in context menu deletes element: [end of test] appState 1`] = ` Object { @@ -15955,6 +16049,8 @@ Object { "lastPointerDownWith": "mouse", "multiElement": null, "name": "Untitled-201933152653", + "offsetLeft": 0, + "offsetTop": 0, "openMenu": null, "previousSelectedElementIds": Object {}, "resizingElement": null, @@ -16076,7 +16172,7 @@ Object { exports[`regression tests selecting 'Delete' in context menu deletes element: [end of test] number of elements 1`] = `1`; -exports[`regression tests selecting 'Delete' in context menu deletes element: [end of test] number of renders 1`] = `7`; +exports[`regression tests selecting 'Delete' in context menu deletes element: [end of test] number of renders 1`] = `8`; exports[`regression tests selecting 'Duplicate' in context menu duplicates element: [end of test] appState 1`] = ` Object { @@ -16112,6 +16208,8 @@ Object { "lastPointerDownWith": "mouse", "multiElement": null, "name": "Untitled-201933152653", + "offsetLeft": 0, + "offsetTop": 0, "openMenu": null, "previousSelectedElementIds": Object {}, "resizingElement": null, @@ -16282,7 +16380,7 @@ Object { exports[`regression tests selecting 'Duplicate' in context menu duplicates element: [end of test] number of elements 1`] = `2`; -exports[`regression tests selecting 'Duplicate' in context menu duplicates element: [end of test] number of renders 1`] = `7`; +exports[`regression tests selecting 'Duplicate' in context menu duplicates element: [end of test] number of renders 1`] = `8`; exports[`regression tests selecting 'Group selection' in context menu groups selected elements: [end of test] appState 1`] = ` Object { @@ -16318,6 +16416,8 @@ Object { "lastPointerDownWith": "mouse", "multiElement": null, "name": "Untitled-201933152653", + "offsetLeft": 0, + "offsetTop": 0, "openMenu": null, "previousSelectedElementIds": Object { "id1": true, @@ -16559,7 +16659,7 @@ Object { exports[`regression tests selecting 'Group selection' in context menu groups selected elements: [end of test] number of elements 1`] = `2`; -exports[`regression tests selecting 'Group selection' in context menu groups selected elements: [end of test] number of renders 1`] = `13`; +exports[`regression tests selecting 'Group selection' in context menu groups selected elements: [end of test] number of renders 1`] = `14`; exports[`regression tests selecting 'Paste styles' in context menu pastes styles: [end of test] appState 1`] = ` Object { @@ -16595,6 +16695,8 @@ Object { "lastPointerDownWith": "mouse", "multiElement": null, "name": "Untitled-201933152653", + "offsetLeft": 0, + "offsetTop": 0, "openMenu": null, "previousSelectedElementIds": Object {}, "resizingElement": null, @@ -17315,7 +17417,7 @@ Object { exports[`regression tests selecting 'Paste styles' in context menu pastes styles: [end of test] number of elements 1`] = `2`; -exports[`regression tests selecting 'Paste styles' in context menu pastes styles: [end of test] number of renders 1`] = `21`; +exports[`regression tests selecting 'Paste styles' in context menu pastes styles: [end of test] number of renders 1`] = `22`; exports[`regression tests selecting 'Send backward' in context menu sends element backward: [end of test] appState 1`] = ` Object { @@ -17351,6 +17453,8 @@ Object { "lastPointerDownWith": "mouse", "multiElement": null, "name": "Untitled-201933152653", + "offsetLeft": 0, + "offsetTop": 0, "openMenu": null, "previousSelectedElementIds": Object {}, "resizingElement": null, @@ -17576,7 +17680,7 @@ Object { exports[`regression tests selecting 'Send backward' in context menu sends element backward: [end of test] number of elements 1`] = `2`; -exports[`regression tests selecting 'Send backward' in context menu sends element backward: [end of test] number of renders 1`] = `11`; +exports[`regression tests selecting 'Send backward' in context menu sends element backward: [end of test] number of renders 1`] = `12`; exports[`regression tests selecting 'Send to back' in context menu sends element to back: [end of test] appState 1`] = ` Object { @@ -17612,6 +17716,8 @@ Object { "lastPointerDownWith": "mouse", "multiElement": null, "name": "Untitled-201933152653", + "offsetLeft": 0, + "offsetTop": 0, "openMenu": null, "previousSelectedElementIds": Object {}, "resizingElement": null, @@ -17837,7 +17943,7 @@ Object { exports[`regression tests selecting 'Send to back' in context menu sends element to back: [end of test] number of elements 1`] = `2`; -exports[`regression tests selecting 'Send to back' in context menu sends element to back: [end of test] number of renders 1`] = `11`; +exports[`regression tests selecting 'Send to back' in context menu sends element to back: [end of test] number of renders 1`] = `12`; exports[`regression tests selecting 'Ungroup selection' in context menu ungroups selected group: [end of test] appState 1`] = ` Object { @@ -17873,6 +17979,8 @@ Object { "lastPointerDownWith": "mouse", "multiElement": null, "name": "Untitled-201933152653", + "offsetLeft": 0, + "offsetTop": 0, "openMenu": null, "previousSelectedElementIds": Object { "id1": true, @@ -18165,7 +18273,7 @@ Object { exports[`regression tests selecting 'Ungroup selection' in context menu ungroups selected group: [end of test] number of elements 1`] = `2`; -exports[`regression tests selecting 'Ungroup selection' in context menu ungroups selected group: [end of test] number of renders 1`] = `14`; +exports[`regression tests selecting 'Ungroup selection' in context menu ungroups selected group: [end of test] number of renders 1`] = `15`; exports[`regression tests shift-click to multiselect, then drag: [end of test] appState 1`] = ` Object { @@ -18201,6 +18309,8 @@ Object { "lastPointerDownWith": "mouse", "multiElement": null, "name": "Untitled-201933152653", + "offsetLeft": 0, + "offsetTop": 0, "openMenu": null, "previousSelectedElementIds": Object { "id0": true, @@ -18439,7 +18549,7 @@ Object { exports[`regression tests shift-click to multiselect, then drag: [end of test] number of elements 1`] = `2`; -exports[`regression tests shift-click to multiselect, then drag: [end of test] number of renders 1`] = `17`; +exports[`regression tests shift-click to multiselect, then drag: [end of test] number of renders 1`] = `18`; exports[`regression tests shows 'Group selection' in context menu for multiple selected elements: [end of test] appState 1`] = ` Object { @@ -18475,6 +18585,8 @@ Object { "lastPointerDownWith": "mouse", "multiElement": null, "name": "Untitled-201933152653", + "offsetLeft": 0, + "offsetTop": 0, "openMenu": null, "previousSelectedElementIds": Object { "id0": true, @@ -18651,7 +18763,7 @@ Object { exports[`regression tests shows 'Group selection' in context menu for multiple selected elements: [end of test] number of elements 1`] = `2`; -exports[`regression tests shows 'Group selection' in context menu for multiple selected elements: [end of test] number of renders 1`] = `14`; +exports[`regression tests shows 'Group selection' in context menu for multiple selected elements: [end of test] number of renders 1`] = `15`; exports[`regression tests shows 'Ungroup selection' in context menu for group inside selected elements: [end of test] appState 1`] = ` Object { @@ -18687,6 +18799,8 @@ Object { "lastPointerDownWith": "mouse", "multiElement": null, "name": "Untitled-201933152653", + "offsetLeft": 0, + "offsetTop": 0, "openMenu": null, "previousSelectedElementIds": Object { "id0": true, @@ -18931,7 +19045,7 @@ Object { exports[`regression tests shows 'Ungroup selection' in context menu for group inside selected elements: [end of test] number of elements 1`] = `2`; -exports[`regression tests shows 'Ungroup selection' in context menu for group inside selected elements: [end of test] number of renders 1`] = `15`; +exports[`regression tests shows 'Ungroup selection' in context menu for group inside selected elements: [end of test] number of renders 1`] = `16`; exports[`regression tests shows context menu for canvas: [end of test] appState 1`] = ` Object { @@ -18967,6 +19081,8 @@ Object { "lastPointerDownWith": "mouse", "multiElement": null, "name": "Untitled-201933152653", + "offsetLeft": 0, + "offsetTop": 0, "openMenu": null, "previousSelectedElementIds": Object {}, "resizingElement": null, @@ -18997,7 +19113,7 @@ Object { exports[`regression tests shows context menu for canvas: [end of test] number of elements 1`] = `0`; -exports[`regression tests shows context menu for canvas: [end of test] number of renders 1`] = `2`; +exports[`regression tests shows context menu for canvas: [end of test] number of renders 1`] = `3`; exports[`regression tests shows context menu for element: [end of test] appState 1`] = ` Object { @@ -19033,6 +19149,8 @@ Object { "lastPointerDownWith": "mouse", "multiElement": null, "name": "Untitled-201933152653", + "offsetLeft": 0, + "offsetTop": 0, "openMenu": null, "previousSelectedElementIds": Object {}, "resizingElement": null, @@ -19124,7 +19242,7 @@ Object { exports[`regression tests shows context menu for element: [end of test] number of elements 1`] = `1`; -exports[`regression tests shows context menu for element: [end of test] number of renders 1`] = `6`; +exports[`regression tests shows context menu for element: [end of test] number of renders 1`] = `7`; exports[`regression tests spacebar + drag scrolls the canvas: [end of test] appState 1`] = ` Object { @@ -19160,6 +19278,8 @@ Object { "lastPointerDownWith": "mouse", "multiElement": null, "name": "Untitled-201933152653", + "offsetLeft": 0, + "offsetTop": 0, "openMenu": null, "previousSelectedElementIds": Object {}, "resizingElement": null, @@ -19190,7 +19310,7 @@ Object { exports[`regression tests spacebar + drag scrolls the canvas: [end of test] number of elements 1`] = `0`; -exports[`regression tests spacebar + drag scrolls the canvas: [end of test] number of renders 1`] = `5`; +exports[`regression tests spacebar + drag scrolls the canvas: [end of test] number of renders 1`] = `6`; exports[`regression tests supports nested groups: [end of test] appState 1`] = ` Object { @@ -19226,6 +19346,8 @@ Object { "lastPointerDownWith": "mouse", "multiElement": null, "name": "Untitled-201933152653", + "offsetLeft": 0, + "offsetTop": 0, "openMenu": null, "previousSelectedElementIds": Object {}, "resizingElement": null, @@ -19845,7 +19967,7 @@ Object { exports[`regression tests supports nested groups: [end of test] number of elements 1`] = `3`; -exports[`regression tests supports nested groups: [end of test] number of renders 1`] = `30`; +exports[`regression tests supports nested groups: [end of test] number of renders 1`] = `31`; exports[`regression tests two-finger scroll works: [end of test] appState 1`] = ` Object { @@ -19881,6 +20003,8 @@ Object { "lastPointerDownWith": "touch", "multiElement": null, "name": "Untitled-201933152653", + "offsetLeft": 0, + "offsetTop": 0, "openMenu": null, "previousSelectedElementIds": Object {}, "resizingElement": null, @@ -19913,7 +20037,7 @@ Object { exports[`regression tests two-finger scroll works: [end of test] number of elements 1`] = `0`; -exports[`regression tests two-finger scroll works: [end of test] number of renders 1`] = `10`; +exports[`regression tests two-finger scroll works: [end of test] number of renders 1`] = `11`; exports[`regression tests undo/redo drawing an element: [end of test] appState 1`] = ` Object { @@ -19949,6 +20073,8 @@ Object { "lastPointerDownWith": "mouse", "multiElement": null, "name": "Untitled-201933152653", + "offsetLeft": 0, + "offsetTop": 0, "openMenu": null, "previousSelectedElementIds": Object {}, "resizingElement": null, @@ -20342,7 +20468,7 @@ Object { exports[`regression tests undo/redo drawing an element: [end of test] number of elements 1`] = `3`; -exports[`regression tests undo/redo drawing an element: [end of test] number of renders 1`] = `24`; +exports[`regression tests undo/redo drawing an element: [end of test] number of renders 1`] = `25`; exports[`regression tests updates fontSize & fontFamily appState: [end of test] appState 1`] = ` Object { @@ -20378,6 +20504,8 @@ Object { "lastPointerDownWith": "mouse", "multiElement": null, "name": "Untitled-201933152653", + "offsetLeft": 0, + "offsetTop": 0, "openMenu": null, "previousSelectedElementIds": Object {}, "resizingElement": null, @@ -20419,7 +20547,7 @@ Object { exports[`regression tests updates fontSize & fontFamily appState: [end of test] number of elements 1`] = `0`; -exports[`regression tests updates fontSize & fontFamily appState: [end of test] number of renders 1`] = `4`; +exports[`regression tests updates fontSize & fontFamily appState: [end of test] number of renders 1`] = `5`; exports[`regression tests zoom hotkeys: [end of test] appState 1`] = ` Object { @@ -20455,6 +20583,8 @@ Object { "lastPointerDownWith": "mouse", "multiElement": null, "name": "Untitled-201933152653", + "offsetLeft": 0, + "offsetTop": 0, "openMenu": null, "previousSelectedElementIds": Object {}, "resizingElement": null, @@ -20485,4 +20615,4 @@ Object { exports[`regression tests zoom hotkeys: [end of test] number of elements 1`] = `0`; -exports[`regression tests zoom hotkeys: [end of test] number of renders 1`] = `4`; +exports[`regression tests zoom hotkeys: [end of test] number of renders 1`] = `5`; diff --git a/src/tests/dragCreate.test.tsx b/src/tests/dragCreate.test.tsx index 3ee956e4..137078b2 100644 --- a/src/tests/dragCreate.test.tsx +++ b/src/tests/dragCreate.test.tsx @@ -37,7 +37,7 @@ describe("add element to the scene when pointer dragging long enough", () => { // finish (position does not matter) fireEvent.pointerUp(canvas); - expect(renderScene).toHaveBeenCalledTimes(4); + expect(renderScene).toHaveBeenCalledTimes(5); expect(h.state.selectionElement).toBeNull(); expect(h.elements.length).toEqual(1); @@ -68,7 +68,7 @@ describe("add element to the scene when pointer dragging long enough", () => { // finish (position does not matter) fireEvent.pointerUp(canvas); - expect(renderScene).toHaveBeenCalledTimes(4); + expect(renderScene).toHaveBeenCalledTimes(5); expect(h.state.selectionElement).toBeNull(); expect(h.elements.length).toEqual(1); @@ -99,7 +99,7 @@ describe("add element to the scene when pointer dragging long enough", () => { // finish (position does not matter) fireEvent.pointerUp(canvas); - expect(renderScene).toHaveBeenCalledTimes(4); + expect(renderScene).toHaveBeenCalledTimes(5); expect(h.state.selectionElement).toBeNull(); expect(h.elements.length).toEqual(1); @@ -130,7 +130,7 @@ describe("add element to the scene when pointer dragging long enough", () => { // finish (position does not matter) fireEvent.pointerUp(canvas); - expect(renderScene).toHaveBeenCalledTimes(4); + expect(renderScene).toHaveBeenCalledTimes(5); expect(h.state.selectionElement).toBeNull(); expect(h.elements.length).toEqual(1); @@ -165,7 +165,7 @@ describe("add element to the scene when pointer dragging long enough", () => { // finish (position does not matter) fireEvent.pointerUp(canvas); - expect(renderScene).toHaveBeenCalledTimes(4); + expect(renderScene).toHaveBeenCalledTimes(5); expect(h.state.selectionElement).toBeNull(); expect(h.elements.length).toEqual(1); @@ -198,7 +198,7 @@ describe("do not add element to the scene if size is too small", () => { // finish (position does not matter) fireEvent.pointerUp(canvas); - expect(renderScene).toHaveBeenCalledTimes(3); + expect(renderScene).toHaveBeenCalledTimes(4); expect(h.state.selectionElement).toBeNull(); expect(h.elements.length).toEqual(0); }); @@ -217,7 +217,7 @@ describe("do not add element to the scene if size is too small", () => { // finish (position does not matter) fireEvent.pointerUp(canvas); - expect(renderScene).toHaveBeenCalledTimes(3); + expect(renderScene).toHaveBeenCalledTimes(4); expect(h.state.selectionElement).toBeNull(); expect(h.elements.length).toEqual(0); }); @@ -236,7 +236,7 @@ describe("do not add element to the scene if size is too small", () => { // finish (position does not matter) fireEvent.pointerUp(canvas); - expect(renderScene).toHaveBeenCalledTimes(3); + expect(renderScene).toHaveBeenCalledTimes(4); expect(h.state.selectionElement).toBeNull(); expect(h.elements.length).toEqual(0); }); @@ -258,7 +258,7 @@ describe("do not add element to the scene if size is too small", () => { // we need to finalize it because arrows and lines enter multi-mode fireEvent.keyDown(document, { key: KEYS.ENTER }); - expect(renderScene).toHaveBeenCalledTimes(4); + expect(renderScene).toHaveBeenCalledTimes(5); expect(h.state.selectionElement).toBeNull(); expect(h.elements.length).toEqual(0); }); @@ -280,7 +280,7 @@ describe("do not add element to the scene if size is too small", () => { // we need to finalize it because arrows and lines enter multi-mode fireEvent.keyDown(document, { key: KEYS.ENTER }); - expect(renderScene).toHaveBeenCalledTimes(4); + expect(renderScene).toHaveBeenCalledTimes(5); expect(h.state.selectionElement).toBeNull(); expect(h.elements.length).toEqual(0); }); diff --git a/src/tests/move.test.tsx b/src/tests/move.test.tsx index 2d97e4a6..9e7a2ff4 100644 --- a/src/tests/move.test.tsx +++ b/src/tests/move.test.tsx @@ -30,7 +30,7 @@ describe("move element", () => { fireEvent.pointerMove(canvas, { clientX: 60, clientY: 70 }); fireEvent.pointerUp(canvas); - expect(renderScene).toHaveBeenCalledTimes(4); + expect(renderScene).toHaveBeenCalledTimes(5); expect(h.state.selectionElement).toBeNull(); expect(h.elements.length).toEqual(1); expect(h.state.selectedElementIds[h.elements[0].id]).toBeTruthy(); @@ -65,7 +65,7 @@ describe("duplicate element on move when ALT is clicked", () => { fireEvent.pointerMove(canvas, { clientX: 60, clientY: 70 }); fireEvent.pointerUp(canvas); - expect(renderScene).toHaveBeenCalledTimes(4); + expect(renderScene).toHaveBeenCalledTimes(5); expect(h.state.selectionElement).toBeNull(); expect(h.elements.length).toEqual(1); expect(h.state.selectedElementIds[h.elements[0].id]).toBeTruthy(); diff --git a/src/tests/multiPointCreate.test.tsx b/src/tests/multiPointCreate.test.tsx index b6beb9c4..638f0ad1 100644 --- a/src/tests/multiPointCreate.test.tsx +++ b/src/tests/multiPointCreate.test.tsx @@ -30,7 +30,7 @@ describe("remove shape in non linear elements", () => { fireEvent.pointerDown(canvas, { clientX: 30, clientY: 20 }); fireEvent.pointerUp(canvas, { clientX: 30, clientY: 30 }); - expect(renderScene).toHaveBeenCalledTimes(3); + expect(renderScene).toHaveBeenCalledTimes(4); expect(h.elements.length).toEqual(0); }); @@ -44,7 +44,7 @@ describe("remove shape in non linear elements", () => { fireEvent.pointerDown(canvas, { clientX: 30, clientY: 20 }); fireEvent.pointerUp(canvas, { clientX: 30, clientY: 30 }); - expect(renderScene).toHaveBeenCalledTimes(3); + expect(renderScene).toHaveBeenCalledTimes(4); expect(h.elements.length).toEqual(0); }); @@ -58,7 +58,7 @@ describe("remove shape in non linear elements", () => { fireEvent.pointerDown(canvas, { clientX: 30, clientY: 20 }); fireEvent.pointerUp(canvas, { clientX: 30, clientY: 30 }); - expect(renderScene).toHaveBeenCalledTimes(3); + expect(renderScene).toHaveBeenCalledTimes(4); expect(h.elements.length).toEqual(0); }); }); @@ -88,7 +88,7 @@ describe("multi point mode in linear elements", () => { fireEvent.pointerUp(canvas); fireEvent.keyDown(document, { key: KEYS.ENTER }); - expect(renderScene).toHaveBeenCalledTimes(10); + expect(renderScene).toHaveBeenCalledTimes(11); expect(h.elements.length).toEqual(1); const element = h.elements[0] as ExcalidrawLinearElement; @@ -129,7 +129,7 @@ describe("multi point mode in linear elements", () => { fireEvent.pointerUp(canvas); fireEvent.keyDown(document, { key: KEYS.ENTER }); - expect(renderScene).toHaveBeenCalledTimes(10); + expect(renderScene).toHaveBeenCalledTimes(11); expect(h.elements.length).toEqual(1); const element = h.elements[0] as ExcalidrawLinearElement; diff --git a/src/tests/resize.test.tsx b/src/tests/resize.test.tsx index 2baaf63a..1c27c7ec 100644 --- a/src/tests/resize.test.tsx +++ b/src/tests/resize.test.tsx @@ -30,7 +30,7 @@ describe("resize element", () => { fireEvent.pointerMove(canvas, { clientX: 60, clientY: 70 }); fireEvent.pointerUp(canvas); - expect(renderScene).toHaveBeenCalledTimes(4); + expect(renderScene).toHaveBeenCalledTimes(5); expect(h.state.selectionElement).toBeNull(); expect(h.elements.length).toEqual(1); expect(h.state.selectedElementIds[h.elements[0].id]).toBeTruthy(); @@ -73,7 +73,7 @@ describe("resize element with aspect ratio when SHIFT is clicked", () => { fireEvent.pointerMove(canvas, { clientX: 60, clientY: 70 }); fireEvent.pointerUp(canvas); - expect(renderScene).toHaveBeenCalledTimes(4); + expect(renderScene).toHaveBeenCalledTimes(5); expect(h.state.selectionElement).toBeNull(); expect(h.elements.length).toEqual(1); expect(h.state.selectedElementIds[h.elements[0].id]).toBeTruthy(); diff --git a/src/tests/selection.test.tsx b/src/tests/selection.test.tsx index 4a4a4851..dedbaa64 100644 --- a/src/tests/selection.test.tsx +++ b/src/tests/selection.test.tsx @@ -28,7 +28,7 @@ describe("selection element", () => { const canvas = container.querySelector("canvas")!; fireEvent.pointerDown(canvas, { clientX: 60, clientY: 100 }); - expect(renderScene).toHaveBeenCalledTimes(1); + expect(renderScene).toHaveBeenCalledTimes(2); const selectionElement = h.state.selectionElement!; expect(selectionElement).not.toBeNull(); expect(selectionElement.type).toEqual("selection"); @@ -49,7 +49,7 @@ describe("selection element", () => { fireEvent.pointerDown(canvas, { clientX: 60, clientY: 100 }); fireEvent.pointerMove(canvas, { clientX: 150, clientY: 30 }); - expect(renderScene).toHaveBeenCalledTimes(2); + expect(renderScene).toHaveBeenCalledTimes(3); const selectionElement = h.state.selectionElement!; expect(selectionElement).not.toBeNull(); expect(selectionElement.type).toEqual("selection"); @@ -71,7 +71,7 @@ describe("selection element", () => { fireEvent.pointerMove(canvas, { clientX: 150, clientY: 30 }); fireEvent.pointerUp(canvas); - expect(renderScene).toHaveBeenCalledTimes(3); + expect(renderScene).toHaveBeenCalledTimes(4); expect(h.state.selectionElement).toBeNull(); }); }); @@ -96,7 +96,7 @@ describe("select single element on the scene", () => { fireEvent.pointerDown(canvas, { clientX: 45, clientY: 20 }); fireEvent.pointerUp(canvas); - expect(renderScene).toHaveBeenCalledTimes(7); + expect(renderScene).toHaveBeenCalledTimes(8); expect(h.state.selectionElement).toBeNull(); expect(h.elements.length).toEqual(1); expect(h.state.selectedElementIds[h.elements[0].id]).toBeTruthy(); @@ -123,7 +123,7 @@ describe("select single element on the scene", () => { fireEvent.pointerDown(canvas, { clientX: 45, clientY: 20 }); fireEvent.pointerUp(canvas); - expect(renderScene).toHaveBeenCalledTimes(7); + expect(renderScene).toHaveBeenCalledTimes(8); expect(h.state.selectionElement).toBeNull(); expect(h.elements.length).toEqual(1); expect(h.state.selectedElementIds[h.elements[0].id]).toBeTruthy(); @@ -150,7 +150,7 @@ describe("select single element on the scene", () => { fireEvent.pointerDown(canvas, { clientX: 45, clientY: 20 }); fireEvent.pointerUp(canvas); - expect(renderScene).toHaveBeenCalledTimes(7); + expect(renderScene).toHaveBeenCalledTimes(8); expect(h.state.selectionElement).toBeNull(); expect(h.elements.length).toEqual(1); expect(h.state.selectedElementIds[h.elements[0].id]).toBeTruthy(); @@ -190,7 +190,7 @@ describe("select single element on the scene", () => { fireEvent.pointerDown(canvas, { clientX: 40, clientY: 40 }); fireEvent.pointerUp(canvas); - expect(renderScene).toHaveBeenCalledTimes(7); + expect(renderScene).toHaveBeenCalledTimes(8); expect(h.state.selectionElement).toBeNull(); expect(h.elements.length).toEqual(1); expect(h.state.selectedElementIds[h.elements[0].id]).toBeTruthy(); @@ -229,7 +229,7 @@ describe("select single element on the scene", () => { fireEvent.pointerDown(canvas, { clientX: 40, clientY: 40 }); fireEvent.pointerUp(canvas); - expect(renderScene).toHaveBeenCalledTimes(7); + expect(renderScene).toHaveBeenCalledTimes(8); expect(h.state.selectionElement).toBeNull(); expect(h.elements.length).toEqual(1); expect(h.state.selectedElementIds[h.elements[0].id]).toBeTruthy(); diff --git a/src/types.ts b/src/types.ts index 9dd59523..fe20212b 100644 --- a/src/types.ts +++ b/src/types.ts @@ -81,6 +81,8 @@ export type AppState = { editingGroupId: GroupId | null; width: number; height: number; + offsetTop: number; + offsetLeft: number; isLibraryOpen: boolean; }; diff --git a/src/utils.ts b/src/utils.ts index 1fc57111..0ac8e063 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,4 +1,4 @@ -import { FlooredNumber } from "./types"; +import { AppState } from "./types"; import { getZoomOrigin } from "./scene"; import { CURSOR_TYPE, @@ -185,45 +185,39 @@ export const getShortcutKey = (shortcut: string): string => { }; export const viewportCoordsToSceneCoords = ( { clientX, clientY }: { clientX: number; clientY: number }, - { - scrollX, - scrollY, - zoom, - }: { - scrollX: FlooredNumber; - scrollY: FlooredNumber; - zoom: number; - }, + appState: AppState, canvas: HTMLCanvasElement | null, scale: number, ) => { const zoomOrigin = getZoomOrigin(canvas, scale); - const clientXWithZoom = zoomOrigin.x + (clientX - zoomOrigin.x) / zoom; - const clientYWithZoom = zoomOrigin.y + (clientY - zoomOrigin.y) / zoom; + const clientXWithZoom = + zoomOrigin.x + + (clientX - zoomOrigin.x - appState.offsetLeft) / appState.zoom; + const clientYWithZoom = + zoomOrigin.y + + (clientY - zoomOrigin.y - appState.offsetTop) / appState.zoom; - const x = clientXWithZoom - scrollX; - const y = clientYWithZoom - scrollY; + const x = clientXWithZoom - appState.scrollX; + const y = clientYWithZoom - appState.scrollY; return { x, y }; }; export const sceneCoordsToViewportCoords = ( { sceneX, sceneY }: { sceneX: number; sceneY: number }, - { - scrollX, - scrollY, - zoom, - }: { - scrollX: FlooredNumber; - scrollY: FlooredNumber; - zoom: number; - }, + appState: AppState, canvas: HTMLCanvasElement | null, scale: number, ) => { const zoomOrigin = getZoomOrigin(canvas, scale); - const x = zoomOrigin.x - (zoomOrigin.x - sceneX - scrollX) * zoom; - const y = zoomOrigin.y - (zoomOrigin.y - sceneY - scrollY) * zoom; + const x = + zoomOrigin.x - + (zoomOrigin.x - sceneX - appState.scrollX - appState.offsetLeft) * + appState.zoom; + const y = + zoomOrigin.y - + (zoomOrigin.y - sceneY - appState.scrollY - appState.offsetTop) * + appState.zoom; return { x, y }; };