Fix arrows

This commit is contained in:
Mark Tolmacs 2025-07-31 20:23:26 +02:00
parent 452be6e5ea
commit a846ebb6e7
No known key found for this signature in database
2 changed files with 94 additions and 81 deletions

View File

@ -422,6 +422,7 @@ const bindingStrategyForNewSimpleArrowEndpointDragging = (
};
let current: BindingStrategy;
// We are hovering another element with the end point
if (hovered) {
const isInsideBinding =
globalBindMode === "inside" || isAlwaysInsideBinding(hovered);
@ -447,9 +448,18 @@ const bindingStrategyForNewSimpleArrowEndpointDragging = (
// No start binding
if (!arrow.startBinding) {
end = hovered
? { element: hovered, mode: "orbit", focusPoint: point }
: { mode: null };
if (hovered) {
const isInsideBinding =
globalBindMode === "inside" || isAlwaysInsideBinding(hovered);
end = {
mode: isInsideBinding ? "inside" : "orbit",
element: hovered,
focusPoint: point,
};
} else {
end = { mode: null };
}
return { start, end };
}
@ -500,33 +510,6 @@ const bindingStrategyForSimpleArrowEndpointDragging = (
return { current, other };
}
// Update the start point on new arrows
if (
opts?.newArrow &&
opts?.appState?.selectedLinearElement &&
oppositeBinding
) {
const oppositeBindingElement = elementsMap.get(
oppositeBinding?.elementId,
) as ExcalidrawBindableElement;
if (oppositeBinding.elementId !== hovered?.id) {
other = {
element: oppositeBindingElement,
mode: "orbit",
focusPoint: elementCenterPoint(oppositeBindingElement, elementsMap),
};
} else {
other = {
element: oppositeBindingElement,
mode: "inside",
focusPoint:
opts.appState.selectedLinearElement.pointerDownState
.arrowOriginalStartPoint ?? point,
};
}
}
// Dragged point is outside of any bindable element
// so we break any existing binding
if (!hovered) {
@ -1378,10 +1361,10 @@ export const snapToCenter = (
element: ExcalidrawBindableElement,
elementsMap: ElementsMap,
p: GlobalPoint,
tolerance: number = 0.05,
) => {
const extent = Math.min(element.width, element.height);
const center = elementCenterPoint(element, elementsMap);
if (pointDistance(p, center) < tolerance) {
if (pointDistance(p, center) < extent * 0.05) {
return pointFrom<GlobalPoint>(center[0], center[1]);
}
return p;

View File

@ -8584,6 +8584,13 @@ class App extends React.Component<AppProps, AppState> {
return;
}
const element = LinearElementEditor.getElement(
linearElementEditor.elementId,
elementsMap,
);
let [x, y] = [pointerCoords.x, pointerCoords.y];
if (isBindingElement(element)) {
const hoveredElement = getHoveredElementForBinding(
pointFrom<GlobalPoint>(pointerCoords.x, pointerCoords.y),
this.scene.getNonDeletedElements(),
@ -8604,18 +8611,40 @@ class App extends React.Component<AppProps, AppState> {
bindMode: "inside",
});
});
const [lastX, lastY] =
hoveredElement && element.startBinding?.mode !== "inside"
? snapToCenter(
hoveredElement,
elementsMap,
pointFrom<GlobalPoint>(
this.lastPointerMoveCoords?.x ??
pointerDownState.origin.x,
this.lastPointerMoveCoords?.y ??
pointerDownState.origin.y,
),
)
: [
this.lastPointerMoveCoords?.x ??
pointerDownState.origin.x,
this.lastPointerMoveCoords?.y ??
pointerDownState.origin.y,
];
const newState = LinearElementEditor.handlePointDragging(
event,
this,
this.lastPointerMoveCoords?.x ?? pointerDownState.origin.x,
this.lastPointerMoveCoords?.y ?? pointerDownState.origin.y,
lastX,
lastY,
linearElementEditor,
);
if (newState) {
pointerDownState.lastCoords.x =
this.lastPointerMoveCoords?.x ?? pointerDownState.origin.x;
this.lastPointerMoveCoords?.x ??
pointerDownState.origin.x;
pointerDownState.lastCoords.y =
this.lastPointerMoveCoords?.y ?? pointerDownState.origin.y;
this.lastPointerMoveCoords?.y ??
pointerDownState.origin.y;
pointerDownState.drag.hasOccurred = true;
this.setState(newState);
@ -8633,14 +8662,15 @@ class App extends React.Component<AppProps, AppState> {
});
}
const [x, y] = hoveredElement
[x, y] =
hoveredElement && element.startBinding?.mode !== "inside"
? snapToCenter(
hoveredElement,
elementsMap,
pointFrom<GlobalPoint>(pointerCoords.x, pointerCoords.y),
10,
)
: [pointerCoords.x, pointerCoords.y];
}
const newState = LinearElementEditor.handlePointDragging(
event,