diff --git a/packages/element/src/linearElementEditor.ts b/packages/element/src/linearElementEditor.ts index e57211abbc..2ef5d53776 100644 --- a/packages/element/src/linearElementEditor.ts +++ b/packages/element/src/linearElementEditor.ts @@ -476,16 +476,22 @@ export class LinearElementEditor { }); } - invariant( - lastClickedPoint > -1 && - selectedPointsIndices.includes(lastClickedPoint) && - element.points[lastClickedPoint], - `There must be a valid lastClickedPoint in order to drag it. selectedPointsIndices(${JSON.stringify( - selectedPointsIndices, - )}) points(0..${ - element.points.length - 1 - }) lastClickedPoint(${lastClickedPoint})`, - ); + if ( + lastClickedPoint < 0 || + !selectedPointsIndices.includes(lastClickedPoint) || + !element.points[lastClickedPoint] + ) { + console.error( + `There must be a valid lastClickedPoint in order to drag it. selectedPointsIndices(${JSON.stringify( + selectedPointsIndices, + )}) points(0..${ + element.points.length - 1 + }) lastClickedPoint(${lastClickedPoint})`, + ); + + // Fall back to the actual last point as a last resort. + lastClickedPoint = element.points.length - 1; + } // point that's being dragged (out of all selected points) const draggingPoint = element.points[lastClickedPoint]; diff --git a/packages/excalidraw/components/App.tsx b/packages/excalidraw/components/App.tsx index 480dae2f7b..4a79e93baf 100644 --- a/packages/excalidraw/components/App.tsx +++ b/packages/excalidraw/components/App.tsx @@ -6995,27 +6995,23 @@ class App extends React.Component { }, { informMutation: false, isDragging: false }, ); + const newLastIdx = multiElement.points.length - 1; this.setState({ selectedLinearElement: { ...selectedLinearElement, - selectedPointsIndices: - selectedLinearElement.selectedPointsIndices?.includes( - multiElement.points.length, - ) - ? [ - ...selectedLinearElement.selectedPointsIndices.filter( - (idx) => - idx !== multiElement.points.length && - idx !== multiElement.points.length - 1, + selectedPointsIndices: selectedLinearElement.selectedPointsIndices + ? [ + ...new Set( + selectedLinearElement.selectedPointsIndices.map((idx) => + Math.min(idx, newLastIdx), ), - multiElement.points.length - 1, - ] - : selectedLinearElement.selectedPointsIndices, - lastCommittedPoint: - multiElement.points[multiElement.points.length - 1], + ), + ] + : selectedLinearElement.selectedPointsIndices, + lastCommittedPoint: multiElement.points[newLastIdx], initialState: { ...selectedLinearElement.initialState, - lastClickedPoint: multiElement.points.length - 1, + lastClickedPoint: newLastIdx, }, }, }); diff --git a/packages/excalidraw/data/restore.ts b/packages/excalidraw/data/restore.ts index 4550338edf..1ed068dc1c 100644 --- a/packages/excalidraw/data/restore.ts +++ b/packages/excalidraw/data/restore.ts @@ -251,7 +251,9 @@ const repairBinding = ( }; } - console.error(`could not repair binding for element`); + console.error( + `Could not repair binding for element "${boundElement?.id}" out of (${elementsMap?.size}) elements`, + ); } catch (error) { console.error("Error repairing binding:", error); }