Long inside-other binding

This commit is contained in:
Mark Tolmacs 2025-07-31 18:11:28 +02:00
parent e2e729d761
commit e6056fe7c4
No known key found for this signature in database

View File

@ -322,6 +322,9 @@ const bindingStrategyForNewSimpleArrowEndpointDragging = (
let start: BindingStrategy = { mode: undefined }; let start: BindingStrategy = { mode: undefined };
let end: BindingStrategy = { mode: undefined }; let end: BindingStrategy = { mode: undefined };
const arrowOriginalStartPoint =
appState?.selectedLinearElement?.pointerDownState.arrowOriginalStartPoint;
const point = LinearElementEditor.getPointGlobalCoordinates( const point = LinearElementEditor.getPointGlobalCoordinates(
arrow, arrow,
draggingPoints.get(startDragged ? startIdx : endIdx)!.point, draggingPoints.get(startDragged ? startIdx : endIdx)!.point,
@ -362,9 +365,6 @@ const bindingStrategyForNewSimpleArrowEndpointDragging = (
if (endDragged) { if (endDragged) {
// Inside -> inside binding // Inside -> inside binding
if (hovered && hit && arrow.startBinding?.elementId === hovered.id) { if (hovered && hit && arrow.startBinding?.elementId === hovered.id) {
const arrowOriginalStartPoint =
appState?.selectedLinearElement?.pointerDownState
.arrowOriginalStartPoint;
invariant( invariant(
arrowOriginalStartPoint, arrowOriginalStartPoint,
"appState.selectedLinearElement.pointerDownState.arrowOriginalStartPoint must be defined for new arrow creation", "appState.selectedLinearElement.pointerDownState.arrowOriginalStartPoint must be defined for new arrow creation",
@ -382,14 +382,22 @@ const bindingStrategyForNewSimpleArrowEndpointDragging = (
// Inside -> orbit binding // Inside -> orbit binding
if (hovered && !hit && arrow.startBinding?.elementId === hovered.id) { if (hovered && !hit && arrow.startBinding?.elementId === hovered.id) {
invariant(
arrowOriginalStartPoint,
"appState.selectedLinearElement.pointerDownState.arrowOriginalStartPoint must be defined for new arrow creation",
);
const center = pointFrom<GlobalPoint>(
hovered.x + hovered.width / 2,
hovered.y + hovered.height / 2,
);
return { return {
start: { start: {
mode: "orbit", mode: globalBindMode === "inside" ? "inside" : "orbit",
element: hovered, element: hovered,
focusPoint: pointFrom<GlobalPoint>( focusPoint:
hovered.x + hovered.width / 2, globalBindMode === "inside" ? arrowOriginalStartPoint : center,
hovered.y + hovered.height / 2,
),
}, },
end: { mode: null }, end: { mode: null },
}; };
@ -397,29 +405,41 @@ const bindingStrategyForNewSimpleArrowEndpointDragging = (
// Inside -> outside binding // Inside -> outside binding
if (arrow.startBinding && arrow.startBinding.elementId !== hovered?.id) { if (arrow.startBinding && arrow.startBinding.elementId !== hovered?.id) {
invariant(
arrowOriginalStartPoint,
"appState.selectedLinearElement.pointerDownState.arrowOriginalStartPoint must be defined for new arrow creation",
);
const otherElement = elementsMap.get(arrow.startBinding.elementId); const otherElement = elementsMap.get(arrow.startBinding.elementId);
invariant(otherElement, "Other element must be in the elements map"); invariant(otherElement, "Other element must be in the elements map");
const center = pointFrom<GlobalPoint>(
otherElement.x + otherElement.width / 2,
otherElement.y + otherElement.height / 2,
);
const otherIsInsideBinding = arrow.startBinding?.mode === "inside";
// We need to "jump" the start point out with the detached // We need to "jump" the start point out with the detached
// focus point of the center of the bound element // focus point of the center of the bound element
const other: BindingStrategy = { const other: BindingStrategy = {
mode: "orbit", mode: otherIsInsideBinding ? "inside" : "orbit",
element: otherElement as ExcalidrawBindableElement, element: otherElement as ExcalidrawBindableElement,
focusPoint: pointFrom<GlobalPoint>( focusPoint: otherIsInsideBinding ? arrowOriginalStartPoint : center,
otherElement.x + otherElement.width / 2,
otherElement.y + otherElement.height / 2,
),
}; };
let current: BindingStrategy; let current: BindingStrategy;
if (hovered) { if (hovered) {
const isInsideBinding =
globalBindMode === "inside" || isAlwaysInsideBinding(hovered);
current = { current = {
mode: mode: isInsideBinding ? "inside" : "orbit",
globalBindMode === "inside" || isAlwaysInsideBinding(hovered)
? "inside"
: "orbit",
element: hovered, element: hovered,
focusPoint: point, focusPoint: isInsideBinding
? point
: pointFrom<GlobalPoint>(
hovered.x + hovered.width / 2,
hovered.y + hovered.height / 2,
),
}; };
} else { } else {
current = { mode: null }; current = { mode: null };