mirror of
https://github.com/excalidraw/excalidraw
synced 2025-07-25 13:58:22 +08:00
Update simple arrow fixed point when arrow is dragged or moved by arrow keys
This commit is contained in:
@ -1400,7 +1400,7 @@ export const snapToMid = (
|
|||||||
return p;
|
return p;
|
||||||
};
|
};
|
||||||
|
|
||||||
const updateBoundPoint = (
|
export const updateBoundPoint = (
|
||||||
linearElement: NonDeleted<ExcalidrawLinearElement>,
|
linearElement: NonDeleted<ExcalidrawLinearElement>,
|
||||||
startOrEnd: "startBinding" | "endBinding",
|
startOrEnd: "startBinding" | "endBinding",
|
||||||
binding: PointBinding | null | undefined,
|
binding: PointBinding | null | undefined,
|
||||||
|
@ -235,6 +235,8 @@ import {
|
|||||||
isLineElement,
|
isLineElement,
|
||||||
isSimpleArrow,
|
isSimpleArrow,
|
||||||
getOutlineAvoidingPoint,
|
getOutlineAvoidingPoint,
|
||||||
|
isFixedPointBinding,
|
||||||
|
calculateFixedPointForNonElbowArrowBinding,
|
||||||
} from "@excalidraw/element";
|
} from "@excalidraw/element";
|
||||||
|
|
||||||
import type { GlobalPoint, LocalPoint, Radians } from "@excalidraw/math";
|
import type { GlobalPoint, LocalPoint, Radians } from "@excalidraw/math";
|
||||||
@ -261,6 +263,7 @@ import type {
|
|||||||
MagicGenerationData,
|
MagicGenerationData,
|
||||||
ExcalidrawArrowElement,
|
ExcalidrawArrowElement,
|
||||||
ExcalidrawElbowArrowElement,
|
ExcalidrawElbowArrowElement,
|
||||||
|
ExcalidrawBindableElement,
|
||||||
} from "@excalidraw/element/types";
|
} from "@excalidraw/element/types";
|
||||||
|
|
||||||
import type { Mutable, ValueOf } from "@excalidraw/common/utility-types";
|
import type { Mutable, ValueOf } from "@excalidraw/common/utility-types";
|
||||||
@ -4629,6 +4632,51 @@ class App extends React.Component<AppProps, AppState> {
|
|||||||
this.scene,
|
this.scene,
|
||||||
this.state.zoom,
|
this.state.zoom,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const elementsMap = this.scene.getNonDeletedElementsMap();
|
||||||
|
|
||||||
|
this.scene
|
||||||
|
.getSelectedElements(this.state)
|
||||||
|
.filter(isSimpleArrow)
|
||||||
|
.forEach((element) => {
|
||||||
|
// Update the fixed point bindings for non-elbow arrows
|
||||||
|
// when the pointer is released, so that they are correctly positioned
|
||||||
|
// after the drag.
|
||||||
|
if (
|
||||||
|
element.startBinding &&
|
||||||
|
isFixedPointBinding(element.startBinding)
|
||||||
|
) {
|
||||||
|
this.scene.mutateElement(element, {
|
||||||
|
startBinding: {
|
||||||
|
...element.startBinding,
|
||||||
|
...calculateFixedPointForNonElbowArrowBinding(
|
||||||
|
element,
|
||||||
|
elementsMap.get(
|
||||||
|
element.startBinding.elementId,
|
||||||
|
) as ExcalidrawBindableElement,
|
||||||
|
"start",
|
||||||
|
elementsMap,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (element.endBinding && isFixedPointBinding(element.endBinding)) {
|
||||||
|
this.scene.mutateElement(element, {
|
||||||
|
endBinding: {
|
||||||
|
...element.endBinding,
|
||||||
|
...calculateFixedPointForNonElbowArrowBinding(
|
||||||
|
element,
|
||||||
|
elementsMap.get(
|
||||||
|
element.endBinding.elementId,
|
||||||
|
) as ExcalidrawBindableElement,
|
||||||
|
"end",
|
||||||
|
elementsMap,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
this.setState({ suggestedBindings: [] });
|
this.setState({ suggestedBindings: [] });
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -9077,6 +9125,8 @@ class App extends React.Component<AppProps, AppState> {
|
|||||||
pointerDownState: PointerDownState,
|
pointerDownState: PointerDownState,
|
||||||
): (event: PointerEvent) => void {
|
): (event: PointerEvent) => void {
|
||||||
return withBatchedUpdates((childEvent: PointerEvent) => {
|
return withBatchedUpdates((childEvent: PointerEvent) => {
|
||||||
|
const elementsMap = this.scene.getNonDeletedElementsMap();
|
||||||
|
|
||||||
this.removePointer(childEvent);
|
this.removePointer(childEvent);
|
||||||
if (pointerDownState.eventListeners.onMove) {
|
if (pointerDownState.eventListeners.onMove) {
|
||||||
pointerDownState.eventListeners.onMove.flush();
|
pointerDownState.eventListeners.onMove.flush();
|
||||||
@ -9168,7 +9218,6 @@ class App extends React.Component<AppProps, AppState> {
|
|||||||
selectedElementsAreBeingDragged: false,
|
selectedElementsAreBeingDragged: false,
|
||||||
bindMode: "focus",
|
bindMode: "focus",
|
||||||
});
|
});
|
||||||
const elementsMap = this.scene.getNonDeletedElementsMap();
|
|
||||||
|
|
||||||
if (
|
if (
|
||||||
pointerDownState.drag.hasOccurred &&
|
pointerDownState.drag.hasOccurred &&
|
||||||
@ -9242,6 +9291,48 @@ class App extends React.Component<AppProps, AppState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.scene
|
||||||
|
.getSelectedElements(this.state)
|
||||||
|
.filter(isSimpleArrow)
|
||||||
|
.forEach((element) => {
|
||||||
|
// Update the fixed point bindings for non-elbow arrows
|
||||||
|
// when the pointer is released, so that they are correctly positioned
|
||||||
|
// after the drag.
|
||||||
|
if (
|
||||||
|
element.startBinding &&
|
||||||
|
isFixedPointBinding(element.startBinding)
|
||||||
|
) {
|
||||||
|
this.scene.mutateElement(element, {
|
||||||
|
startBinding: {
|
||||||
|
...element.startBinding,
|
||||||
|
...calculateFixedPointForNonElbowArrowBinding(
|
||||||
|
element,
|
||||||
|
elementsMap.get(
|
||||||
|
element.startBinding.elementId,
|
||||||
|
) as ExcalidrawBindableElement,
|
||||||
|
"start",
|
||||||
|
elementsMap,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (element.endBinding && isFixedPointBinding(element.endBinding)) {
|
||||||
|
this.scene.mutateElement(element, {
|
||||||
|
endBinding: {
|
||||||
|
...element.endBinding,
|
||||||
|
...calculateFixedPointForNonElbowArrowBinding(
|
||||||
|
element,
|
||||||
|
elementsMap.get(
|
||||||
|
element.endBinding.elementId,
|
||||||
|
) as ExcalidrawBindableElement,
|
||||||
|
"end",
|
||||||
|
elementsMap,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
this.missingPointerEventCleanupEmitter.clear();
|
this.missingPointerEventCleanupEmitter.clear();
|
||||||
|
|
||||||
window.removeEventListener(
|
window.removeEventListener(
|
||||||
|
Reference in New Issue
Block a user