mirror of
https://github.com/excalidraw/excalidraw.git
synced 2025-09-10 13:26:11 -04:00
Fix arrows
This commit is contained in:
parent
452be6e5ea
commit
a846ebb6e7
@ -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;
|
||||
|
@ -8584,63 +8584,93 @@ class App extends React.Component<AppProps, AppState> {
|
||||
return;
|
||||
}
|
||||
|
||||
const hoveredElement = getHoveredElementForBinding(
|
||||
pointFrom<GlobalPoint>(pointerCoords.x, pointerCoords.y),
|
||||
this.scene.getNonDeletedElements(),
|
||||
const element = LinearElementEditor.getElement(
|
||||
linearElementEditor.elementId,
|
||||
elementsMap,
|
||||
this.state.zoom,
|
||||
);
|
||||
let [x, y] = [pointerCoords.x, pointerCoords.y];
|
||||
|
||||
// Timed bind mode handler for arrow elements
|
||||
if (this.state.bindMode === "orbit") {
|
||||
if (this.bindModeHandler && !hoveredElement) {
|
||||
clearTimeout(this.bindModeHandler);
|
||||
this.bindModeHandler = null;
|
||||
} else if (!this.bindModeHandler && hoveredElement) {
|
||||
this.bindModeHandler = setTimeout(() => {
|
||||
if (hoveredElement) {
|
||||
flushSync(() => {
|
||||
this.setState({
|
||||
bindMode: "inside",
|
||||
if (isBindingElement(element)) {
|
||||
const hoveredElement = getHoveredElementForBinding(
|
||||
pointFrom<GlobalPoint>(pointerCoords.x, pointerCoords.y),
|
||||
this.scene.getNonDeletedElements(),
|
||||
elementsMap,
|
||||
this.state.zoom,
|
||||
);
|
||||
|
||||
// Timed bind mode handler for arrow elements
|
||||
if (this.state.bindMode === "orbit") {
|
||||
if (this.bindModeHandler && !hoveredElement) {
|
||||
clearTimeout(this.bindModeHandler);
|
||||
this.bindModeHandler = null;
|
||||
} else if (!this.bindModeHandler && hoveredElement) {
|
||||
this.bindModeHandler = setTimeout(() => {
|
||||
if (hoveredElement) {
|
||||
flushSync(() => {
|
||||
this.setState({
|
||||
bindMode: "inside",
|
||||
});
|
||||
});
|
||||
});
|
||||
const newState = LinearElementEditor.handlePointDragging(
|
||||
event,
|
||||
this,
|
||||
this.lastPointerMoveCoords?.x ?? pointerDownState.origin.x,
|
||||
this.lastPointerMoveCoords?.y ?? pointerDownState.origin.y,
|
||||
linearElementEditor,
|
||||
);
|
||||
if (newState) {
|
||||
pointerDownState.lastCoords.x =
|
||||
this.lastPointerMoveCoords?.x ?? pointerDownState.origin.x;
|
||||
pointerDownState.lastCoords.y =
|
||||
this.lastPointerMoveCoords?.y ?? pointerDownState.origin.y;
|
||||
pointerDownState.drag.hasOccurred = true;
|
||||
|
||||
this.setState(newState);
|
||||
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,
|
||||
lastX,
|
||||
lastY,
|
||||
linearElementEditor,
|
||||
);
|
||||
if (newState) {
|
||||
pointerDownState.lastCoords.x =
|
||||
this.lastPointerMoveCoords?.x ??
|
||||
pointerDownState.origin.x;
|
||||
pointerDownState.lastCoords.y =
|
||||
this.lastPointerMoveCoords?.y ??
|
||||
pointerDownState.origin.y;
|
||||
pointerDownState.drag.hasOccurred = true;
|
||||
|
||||
this.setState(newState);
|
||||
}
|
||||
} else {
|
||||
this.bindModeHandler = null;
|
||||
}
|
||||
} else {
|
||||
this.bindModeHandler = null;
|
||||
}
|
||||
}, BIND_MODE_TIMEOUT);
|
||||
}
|
||||
} else if (!hoveredElement) {
|
||||
flushSync(() => {
|
||||
this.setState({
|
||||
bindMode: "orbit",
|
||||
}, BIND_MODE_TIMEOUT);
|
||||
}
|
||||
} else if (!hoveredElement) {
|
||||
flushSync(() => {
|
||||
this.setState({
|
||||
bindMode: "orbit",
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const [x, y] = hoveredElement
|
||||
? snapToCenter(
|
||||
hoveredElement,
|
||||
elementsMap,
|
||||
pointFrom<GlobalPoint>(pointerCoords.x, pointerCoords.y),
|
||||
10,
|
||||
)
|
||||
: [pointerCoords.x, pointerCoords.y];
|
||||
[x, y] =
|
||||
hoveredElement && element.startBinding?.mode !== "inside"
|
||||
? snapToCenter(
|
||||
hoveredElement,
|
||||
elementsMap,
|
||||
pointFrom<GlobalPoint>(pointerCoords.x, pointerCoords.y),
|
||||
)
|
||||
: [pointerCoords.x, pointerCoords.y];
|
||||
}
|
||||
|
||||
const newState = LinearElementEditor.handlePointDragging(
|
||||
event,
|
||||
|
Loading…
x
Reference in New Issue
Block a user