diff --git a/packages/excalidraw/actions/actionCanvas.tsx b/packages/excalidraw/actions/actionCanvas.tsx index f3e0a8a32..7bd80ded3 100644 --- a/packages/excalidraw/actions/actionCanvas.tsx +++ b/packages/excalidraw/actions/actionCanvas.tsx @@ -27,8 +27,12 @@ import { ZOOM_STEP, } from "../constants"; import { setCursor } from "../cursor"; -import { getCommonBounds, getNonDeletedElements } from "../element"; -import { newElementWith } from "../element/mutateElement"; +import { + getCommonBounds, + getNonDeletedElements, + isInvisiblySmallElement, +} from "../element"; +import { mutateElement, newElementWith } from "../element/mutateElement"; import { t } from "../i18n"; import { CODES, KEYS } from "../keys"; import { getNormalizedZoom } from "../scene"; @@ -36,6 +40,7 @@ import { centerScrollOn } from "../scene/scroll"; import { getStateForZoom } from "../scene/zoom"; import { CaptureUpdateAction } from "../store"; import { getShortcutKey, updateActiveTool } from "../utils"; +import { isLinearElement } from "../element/typeChecks"; import { register } from "./register"; @@ -544,13 +549,44 @@ export const actionToggleHandTool = register({ setCursor(app.interactiveCanvas, CURSOR_TYPE.GRAB); } + let newElements = elements; + + const multiPointElement = + appState.multiElement && isLinearElement(appState.multiElement) + ? appState.multiElement + : null; + + if (multiPointElement) { + // pen and mouse have hover + if (appState.lastPointerDownWith !== "touch") { + const { points, lastCommittedPoint } = multiPointElement; + if ( + !lastCommittedPoint || + points[points.length - 1] !== lastCommittedPoint + ) { + mutateElement(multiPointElement, { + points: multiPointElement.points.slice(0, -1), + }); + } + } + if (isInvisiblySmallElement(multiPointElement)) { + // TODO: #7348 in theory this gets recorded by the store, so the invisible elements could be restored by the undo/redo, which might be not what we would want + newElements = newElements.filter( + (el) => el.id !== multiPointElement.id, + ); + } + } + return { + elements: newElements, appState: { ...appState, selectedElementIds: {}, selectedGroupIds: {}, activeEmbeddable: null, activeTool, + newElement: null, + multiElement: null, }, captureUpdate: CaptureUpdateAction.IMMEDIATELY, }; diff --git a/packages/excalidraw/components/App.tsx b/packages/excalidraw/components/App.tsx index af8c13d7b..3d1952928 100644 --- a/packages/excalidraw/components/App.tsx +++ b/packages/excalidraw/components/App.tsx @@ -3573,7 +3573,7 @@ class App extends React.Component { ...prevState.activeTool, ...updateActiveTool( this.state, - prevState.activeTool.locked + prevState.activeTool.locked && !prevState.newElement ? { type: "selection" } : prevState.activeTool, ), @@ -4689,6 +4689,11 @@ class App extends React.Component { return; } + //cancel adding linearElement if tool is switched + if (this.state.newElement && isLinearElement(this.state.newElement)) { + this.actionManager.executeAction(actionFinalize); + } + const nextActiveTool = updateActiveTool(this.state, tool); if (nextActiveTool.type === "hand") { setCursor(this.interactiveCanvas, CURSOR_TYPE.GRAB);