From fc3e0620749bcc633201970021e7063347cc3820 Mon Sep 17 00:00:00 2001 From: David Luzar <5153846+dwelle@users.noreply.github.com> Date: Mon, 26 May 2025 16:51:47 +0200 Subject: [PATCH] feat: do not break polygon on point delete inside line editor (#9580) * feat: do not break polygon on point delete inside line editor * fix: polygon point highlighting when selected point == 0 --- packages/element/src/linearElementEditor.ts | 23 ++++++++----------- .../excalidraw/renderer/interactiveScene.ts | 19 +++++++++++---- 2 files changed, 23 insertions(+), 19 deletions(-) diff --git a/packages/element/src/linearElementEditor.ts b/packages/element/src/linearElementEditor.ts index ae752eeae..ca3d60c63 100644 --- a/packages/element/src/linearElementEditor.ts +++ b/packages/element/src/linearElementEditor.ts @@ -1290,24 +1290,19 @@ export class LinearElementEditor { app.state.editingLinearElement?.lastUncommittedPoint === element.points[element.points.length - 1]; - const isPolygon = isLineElement(element) && element.polygon; - - // break polygon if deleting start/end point - if ( - isPolygon && - // don't disable polygon if cleaning up uncommitted point - !isUncommittedPoint && - (pointIndices.includes(0) || - pointIndices.includes(element.points.length - 1)) - ) { - app.scene.mutateElement(element, { polygon: false }); - } - const nextPoints = element.points.filter((_, idx) => { return !pointIndices.includes(idx); }); - if (isUncommittedPoint && isLineElement(element) && element.polygon) { + const isPolygon = isLineElement(element) && element.polygon; + + // keep polygon intact if deleting start/end point or uncommitted point + if ( + isPolygon && + (isUncommittedPoint || + pointIndices.includes(0) || + pointIndices.includes(element.points.length - 1)) + ) { nextPoints[0] = pointFrom( nextPoints[nextPoints.length - 1][0], nextPoints[nextPoints.length - 1][1], diff --git a/packages/excalidraw/renderer/interactiveScene.ts b/packages/excalidraw/renderer/interactiveScene.ts index ac0cb5269..7d8b47485 100644 --- a/packages/excalidraw/renderer/interactiveScene.ts +++ b/packages/excalidraw/renderer/interactiveScene.ts @@ -459,18 +459,27 @@ const renderLinearPointHandles = ( const isOverlappingPoint = idx > 0 && - (idx !== points.length - 1 || - appState.editingLinearElement || - !_isLineElement || - !element.polygon) && + (idx !== points.length - 1 || !_isLineElement || !element.polygon) && pointsEqual( point, idx === points.length - 1 ? points[0] : points[idx - 1], 2 / appState.zoom.value, ); - const isSelected = + let isSelected = !!appState.editingLinearElement?.selectedPointsIndices?.includes(idx); + // when element is a polygon, highlight the last point as well if first + // point is selected since they overlap and the last point tends to be + // rendered on top + if ( + _isLineElement && + element.polygon && + !isSelected && + idx === element.points.length - 1 && + !!appState.editingLinearElement?.selectedPointsIndices?.includes(0) + ) { + isSelected = true; + } renderSingleLinearPoint( context,