fix: Jump out to orbit for new arrows when dragged outside

This commit is contained in:
Mark Tolmacs
2025-11-07 16:25:17 +01:00
parent 6544bc9e3c
commit 494dc62a8d
2 changed files with 56 additions and 40 deletions

View File

@@ -1,6 +1,7 @@
import {
KEYS,
arrayToMap,
debugDrawPoint,
getFeatureFlag,
invariant,
isTransparent,
@@ -679,55 +680,70 @@ const getBindingStrategyForDraggingBindingElementEndpoints_simple = (
};
}
const otherBindableElement = otherBinding
? (elementsMap.get(
otherBinding.elementId,
) as NonDeleted<ExcalidrawBindableElement>)
: undefined;
const otherFocusPoint =
otherBinding &&
otherBindableElement &&
getGlobalFixedPointForBindableElement(
otherBinding.fixedPoint,
otherBindableElement,
elementsMap,
);
const otherPoint = LinearElementEditor.getPointAtIndexGlobalCoordinates(
arrow,
startDragged ? -1 : 0,
elementsMap,
);
const otherFocusPointIsInElement =
otherBindableElement &&
otherFocusPoint &&
isPointInElement(otherFocusPoint, otherBindableElement, elementsMap);
const current: BindingStrategy = hit
? pointInElement
? pointInElement || opts?.altKey
? {
mode: "inside",
element: hit,
focusPoint: globalPoint,
}
: {
mode: opts?.altKey ? "inside" : "orbit",
element: hit,
focusPoint: opts?.altKey
? globalPoint
: projectFixedPointOntoDiagonal(
arrow,
globalPoint,
hit,
startDragged ? "start" : "end",
elementsMap,
) || globalPoint,
}
: { mode: null };
const otherBindableElement = otherBinding
? (elementsMap.get(
otherBinding.elementId,
) as NonDeleted<ExcalidrawBindableElement>)
: undefined;
const otherPoint = LinearElementEditor.getPointAtIndexGlobalCoordinates(
arrow,
startDragged ? -1 : 0,
elementsMap,
);
const other: BindingStrategy =
!opts?.altKey &&
opts?.newArrow &&
otherBindableElement &&
!isPointInElement(otherPoint, otherBindableElement, elementsMap)
? {
mode: "orbit",
element: otherBindableElement,
element: hit,
focusPoint:
projectFixedPointOntoDiagonal(
arrow,
otherPoint,
otherBindableElement,
startDragged ? "end" : "start",
globalPoint,
hit,
startDragged ? "start" : "end",
elementsMap,
) || otherPoint,
) || globalPoint,
}
: { mode: null };
const other: BindingStrategy =
!opts?.altKey && opts?.newArrow && otherBindableElement
? otherBindableElement.id === hit?.id
? {
mode: "inside",
element: otherBindableElement,
focusPoint: otherPoint,
}
: {
mode: "orbit",
element: otherBindableElement,
focusPoint:
projectFixedPointOntoDiagonal(
arrow,
otherPoint,
otherBindableElement,
startDragged ? "end" : "start",
elementsMap,
) || otherPoint,
}
: { mode: undefined };
return {

View File

@@ -582,15 +582,15 @@ export const projectFixedPointOntoDiagonal = (
),
a,
);
const intersector = lineSegment<GlobalPoint>(a, b);
const intersector = lineSegment<GlobalPoint>(point, b);
const p1 = lineSegmentIntersectionPoints(diagonalOne, intersector);
const p2 = lineSegmentIntersectionPoints(diagonalTwo, intersector);
const d1 = p1 && pointDistance(a, p1);
const d2 = p2 && pointDistance(a, p2);
debugDrawLine(diagonalOne, { color: "purple" });
debugDrawLine(diagonalTwo, { color: "purple" });
debugDrawLine(intersector, { color: "orange" });
// debugDrawLine(diagonalOne, { color: "purple" });
// debugDrawLine(diagonalTwo, { color: "purple" });
// debugDrawLine(intersector, { color: "orange" });
if (d1 != null && d2 != null) {
return d1 < d2 ? p1 : p2;