diff --git a/src/components/App.tsx b/src/components/App.tsx index d894f65a9..80f720ee1 100644 --- a/src/components/App.tsx +++ b/src/components/App.tsx @@ -433,12 +433,7 @@ class App extends React.Component { } public render() { - const { - zenModeEnabled, - width: canvasDOMWidth, - height: canvasDOMHeight, - viewModeEnabled, - } = this.state; + const { zenModeEnabled, viewModeEnabled } = this.state; const { onCollabButtonClick, @@ -447,9 +442,6 @@ class App extends React.Component { renderCustomStats, } = this.props; - const DEFAULT_PASTE_X = canvasDOMWidth / 2; - const DEFAULT_PASTE_Y = canvasDOMHeight / 2; - return (
{ onCollabButtonClick={onCollabButtonClick} onLockToggle={this.toggleLock} onInsertElements={(elements) => - this.addElementsFromPasteOrLibrary( + this.addElementsFromPasteOrLibrary({ elements, - DEFAULT_PASTE_X, - DEFAULT_PASTE_Y, - ) + position: "center", + }) } zenModeEnabled={zenModeEnabled} toggleZenMode={this.toggleZenMode} @@ -1251,7 +1242,10 @@ class App extends React.Component { }, }); } else if (data.elements) { - this.addElementsFromPasteOrLibrary(data.elements); + this.addElementsFromPasteOrLibrary({ + elements: data.elements, + position: "cursor", + }); } else if (data.text) { this.addTextFromPaste(data.text); } @@ -1260,16 +1254,28 @@ class App extends React.Component { }, ); - private addElementsFromPasteOrLibrary = ( - clipboardElements: readonly ExcalidrawElement[], - clientX = cursorX, - clientY = cursorY, - ) => { - const [minX, minY, maxX, maxY] = getCommonBounds(clipboardElements); + private addElementsFromPasteOrLibrary = (opts: { + elements: readonly ExcalidrawElement[]; + position: { clientX: number; clientY: number } | "cursor" | "center"; + }) => { + const [minX, minY, maxX, maxY] = getCommonBounds(opts.elements); const elementsCenterX = distance(minX, maxX) / 2; const elementsCenterY = distance(minY, maxY) / 2; + const clientX = + typeof opts.position === "object" + ? opts.position.clientX + : opts.position === "cursor" + ? cursorX + : this.state.width / 2 + this.state.offsetLeft; + const clientY = + typeof opts.position === "object" + ? opts.position.clientY + : opts.position === "cursor" + ? cursorY + : this.state.height / 2 + this.state.offsetTop; + const { x, y } = viewportCoordsToSceneCoords( { clientX, clientY }, this.state, @@ -1282,7 +1288,7 @@ class App extends React.Component { const [gridX, gridY] = getGridPoint(dx, dy, this.state.gridSize); const oldIdToDuplicatedId = new Map(); - const newElements = clipboardElements.map((element) => { + const newElements = opts.elements.map((element) => { const newElement = duplicateElement( this.state.editingGroupId, groupIdMap, @@ -1301,7 +1307,7 @@ class App extends React.Component { ]; fixBindingsAfterDuplication( nextElements, - clipboardElements, + opts.elements, oldIdToDuplicatedId, ); @@ -1455,8 +1461,8 @@ class App extends React.Component { private updateCurrentCursorPosition = withBatchedUpdates( (event: MouseEvent) => { - cursorX = event.x; - cursorY = event.y; + cursorX = event.clientX; + cursorY = event.clientY; }, ); @@ -3700,11 +3706,10 @@ class App extends React.Component { const libraryShapes = event.dataTransfer.getData(MIME_TYPES.excalidrawlib); if (libraryShapes !== "") { - this.addElementsFromPasteOrLibrary( - JSON.parse(libraryShapes), - event.clientX, - event.clientY, - ); + this.addElementsFromPasteOrLibrary({ + elements: JSON.parse(libraryShapes), + position: event, + }); return; }