diff --git a/packages/excalidraw/components/App.tsx b/packages/excalidraw/components/App.tsx index af8c13d7b..acae88ba2 100644 --- a/packages/excalidraw/components/App.tsx +++ b/packages/excalidraw/components/App.tsx @@ -6449,7 +6449,7 @@ class App extends React.Component { // we must exit before we set `cursorButton` state and `savePointer` // else it will send pointer state & laser pointer events in collab when // panning - if (this.handleCanvasPanUsingWheelOrSpaceDrag(event)) { + if (this.handleCanvasPan(event)) { return; } @@ -6772,14 +6772,16 @@ class App extends React.Component { }; // Returns whether the event is a panning - public handleCanvasPanUsingWheelOrSpaceDrag = ( + public handleCanvasPan = ( event: React.PointerEvent | MouseEvent, ): boolean => { + const isRightClicked = event.button === POINTER_BUTTON.SECONDARY; if ( !( gesture.pointers.size <= 1 && (event.button === POINTER_BUTTON.WHEEL || (event.button === POINTER_BUTTON.MAIN && isHoldingSpace) || + isRightClicked || isHandToolActive(this.state) || this.state.viewModeEnabled) ) @@ -6807,9 +6809,16 @@ class App extends React.Component { ? false : /Linux/.test(window.navigator.platform); - setCursor(this.interactiveCanvas, CURSOR_TYPE.GRABBING); + if (!isRightClicked) { + setCursor(this.interactiveCanvas, CURSOR_TYPE.GRABBING); + } let { clientX: lastX, clientY: lastY } = event; + let hasDragged = false; const onPointerMove = withBatchedUpdatesThrottled((event: PointerEvent) => { + if (isRightClicked && !hasDragged) { + setCursor(this.interactiveCanvas, CURSOR_TYPE.GRABBING); + } + hasDragged = true; const deltaX = lastX - event.clientX; const deltaY = lastY - event.clientY; lastX = event.clientX; @@ -6873,6 +6882,11 @@ class App extends React.Component { window.removeEventListener(EVENT.POINTER_UP, teardown); window.removeEventListener(EVENT.BLUR, teardown); onPointerMove.flush(); + if (!hasDragged && isRightClicked) { + this.handleCanvasContextMenu( + event as React.MouseEvent, + ); + } }), ); window.addEventListener(EVENT.BLUR, teardown); @@ -9953,7 +9967,7 @@ class App extends React.Component { }; /** updates image cache, refreshing updated elements and/or setting status - to error for images that fail during element creation */ + to error for images that fail during element creation */ private updateImageCache = async ( elements: readonly InitializedExcalidrawImageElement[], files = this.files, @@ -10335,6 +10349,10 @@ class App extends React.Component { return; } + if (isPanning) { + return; + } + const { x, y } = viewportCoordsToSceneCoords(event, this.state); const element = this.getElementAtPosition(x, y, { preferSelected: true, diff --git a/packages/excalidraw/element/textWysiwyg.tsx b/packages/excalidraw/element/textWysiwyg.tsx index b31798687..51f696bee 100644 --- a/packages/excalidraw/element/textWysiwyg.tsx +++ b/packages/excalidraw/element/textWysiwyg.tsx @@ -648,7 +648,7 @@ export const textWysiwyg = ({ // trying to pan by clicking inside text area itself -> handle here if (target instanceof HTMLTextAreaElement) { event.preventDefault(); - app.handleCanvasPanUsingWheelOrSpaceDrag(event); + app.handleCanvasPan(event); } temporarilyDisableSubmit(); return; diff --git a/packages/excalidraw/locales/en.json b/packages/excalidraw/locales/en.json index f14b79705..bbe6d3812 100644 --- a/packages/excalidraw/locales/en.json +++ b/packages/excalidraw/locales/en.json @@ -320,7 +320,7 @@ }, "hints": { "dismissSearch": "Escape to dismiss search", - "canvasPanning": "To move canvas, hold mouse wheel or spacebar while dragging, or use the hand tool", + "canvasPanning": "To move canvas, hold mouse wheel or spacebar while dragging, drag with right click, or use the hand tool", "linearElement": "Click to start multiple points, drag for single line", "arrowTool": "Click to start multiple points, drag for single line. Press {{arrowShortcut}} again to change arrow type.", "freeDraw": "Click and drag, release when you're finished",