From 62d7740c94dc74208d8c49dbcb4e04c6c65b25fb Mon Sep 17 00:00:00 2001 From: Mark Tolmacs Date: Tue, 2 Sep 2025 16:39:38 +0200 Subject: [PATCH] fix: Multipoint arrow opposite point movement --- packages/element/src/binding.ts | 36 ++++++++++----------- packages/element/src/linearElementEditor.ts | 12 +++++-- 2 files changed, 28 insertions(+), 20 deletions(-) diff --git a/packages/element/src/binding.ts b/packages/element/src/binding.ts index 07a5ea45bc..43824753b1 100644 --- a/packages/element/src/binding.ts +++ b/packages/element/src/binding.ts @@ -253,6 +253,7 @@ const bindingStrategyForNewSimpleArrowEndpointDragging = ( let start: BindingStrategy = { mode: undefined }; let end: BindingStrategy = { mode: undefined }; + const isMultiPoint = arrow.points.length > 2; const point = LinearElementEditor.getPointGlobalCoordinates( arrow, draggingPoints.get(startDragged ? startIdx : endIdx)!.point, @@ -287,11 +288,13 @@ const bindingStrategyForNewSimpleArrowEndpointDragging = ( ); return { - start: { - mode: "inside", - element: hit, - focusPoint: origin ?? center, - }, + start: isMultiPoint + ? { mode: undefined } + : { + mode: "inside", + element: hit, + focusPoint: origin ?? center, + }, end: { mode: "inside", element: hit, focusPoint: point }, }; } @@ -335,7 +338,7 @@ const bindingStrategyForNewSimpleArrowEndpointDragging = ( } return { - start: other, + start: isMultiPoint ? { mode: undefined } : other, end: current, }; } @@ -362,8 +365,6 @@ const bindingStrategyForNewSimpleArrowEndpointDragging = ( } invariant(false, "New arrow creation should not reach here"); - - return { start, end }; }; const bindingStrategyForSimpleArrowEndpointDragging = ( @@ -371,14 +372,13 @@ const bindingStrategyForSimpleArrowEndpointDragging = ( oppositeBinding: FixedPointBinding | null, elementsMap: NonDeletedSceneElementsMap, elements: readonly Ordered[], - globalBindMode?: AppState["bindMode"], - opts?: { - appState?: AppState; - }, + globalBindMode: AppState["bindMode"], + arrow: NonDeleted, ): { current: BindingStrategy; other: BindingStrategy } => { let current: BindingStrategy = { mode: undefined }; let other: BindingStrategy = { mode: undefined }; + const isMultiPoint = arrow.points.length > 2; const hit = getHoveredElementForBinding(point, elements, elementsMap); // If the global bind mode is in free binding mode, just bind @@ -416,14 +416,14 @@ const bindingStrategyForSimpleArrowEndpointDragging = ( current = { element: hit, mode: "orbit", focusPoint: point }; other = { mode: null }; - return { current, other }; + return { current, other: isMultiPoint ? { mode: undefined } : other }; } // The opposite binding is inside the same element // eslint-disable-next-line no-else-return else { current = { element: hit, mode: "inside", focusPoint: point }; - return { current, other }; + return { current, other: isMultiPoint ? { mode: undefined } : other }; } } // The opposite binding is on a different element @@ -435,7 +435,7 @@ const bindingStrategyForSimpleArrowEndpointDragging = ( focusPoint: snapToCenter(hit, elementsMap, point), }; - return { current, other }; + return { current, other: isMultiPoint ? { mode: undefined } : other }; } } // The opposite binding is on a different element or no binding @@ -449,7 +449,7 @@ const bindingStrategyForSimpleArrowEndpointDragging = ( // Must return as only one endpoint is dragged, therefore // the end binding strategy might accidentally gets overriden - return { current, other }; + return { current, other: isMultiPoint ? { mode: undefined } : other }; }; export const getBindingStrategyForDraggingBindingElementEndpoints = ( @@ -540,7 +540,7 @@ export const getBindingStrategyForDraggingBindingElementEndpoints = ( elementsMap, elements, globalBindMode, - { appState }, + arrow, ); return { start: current, end: other }; @@ -561,7 +561,7 @@ export const getBindingStrategyForDraggingBindingElementEndpoints = ( elementsMap, elements, globalBindMode, - { appState }, + arrow, ); return { start: other, end: current }; diff --git a/packages/element/src/linearElementEditor.ts b/packages/element/src/linearElementEditor.ts index 2f24d861f8..c1a0dd5fe9 100644 --- a/packages/element/src/linearElementEditor.ts +++ b/packages/element/src/linearElementEditor.ts @@ -2217,11 +2217,19 @@ const pointDraggingUpdates = ( ) || nextArrow.points[0] : nextArrow.points[0]; + const endChanged = + pointDistance( + endLocalPoint, + nextArrow.points[nextArrow.points.length - 1], + ) !== 0; + const startChanged = + pointDistance(startLocalPoint, nextArrow.points[0]) !== 0; + const indicesSet = new Set(selectedPointsIndices); - if (startBindable) { + if (startBindable && startChanged) { indicesSet.add(0); } - if (endBindable) { + if (endBindable && endChanged) { indicesSet.add(element.points.length - 1); } const indices = Array.from(indicesSet);