mirror of
https://github.com/excalidraw/excalidraw.git
synced 2025-11-14 09:45:27 +01:00
fix: Elbow arrow direction at binding
This commit is contained in:
@@ -223,6 +223,7 @@ const bindingStrategyForElbowArrowEndpointDragging = (
|
||||
draggingPoints: PointsPositionUpdates,
|
||||
elementsMap: NonDeletedSceneElementsMap,
|
||||
elements: readonly Ordered<NonDeletedExcalidrawElement>[],
|
||||
zoom?: AppState["zoom"],
|
||||
): {
|
||||
start: BindingStrategy;
|
||||
end: BindingStrategy;
|
||||
@@ -242,7 +243,13 @@ const bindingStrategyForElbowArrowEndpointDragging = (
|
||||
point,
|
||||
elementsMap,
|
||||
);
|
||||
const hit = getHoveredElementForBinding(globalPoint, elements, elementsMap);
|
||||
const hit = getHoveredElementForBinding(
|
||||
globalPoint,
|
||||
elements,
|
||||
elementsMap,
|
||||
(element) =>
|
||||
maxBindingGap_simple(element, element.width, element.height, zoom),
|
||||
);
|
||||
|
||||
const current = hit
|
||||
? {
|
||||
@@ -558,6 +565,7 @@ export const getBindingStrategyForDraggingBindingElementEndpoints = (
|
||||
altKey?: boolean;
|
||||
finalize?: boolean;
|
||||
initialBinding?: boolean;
|
||||
zoom?: AppState["zoom"];
|
||||
},
|
||||
): { start: BindingStrategy; end: BindingStrategy } => {
|
||||
if (getFeatureFlag("COMPLEX_BINDINGS")) {
|
||||
@@ -593,6 +601,7 @@ const getBindingStrategyForDraggingBindingElementEndpoints_simple = (
|
||||
altKey?: boolean;
|
||||
finalize?: boolean;
|
||||
initialBinding?: boolean;
|
||||
zoom?: AppState["zoom"];
|
||||
},
|
||||
): { start: BindingStrategy; end: BindingStrategy } => {
|
||||
const startIdx = 0;
|
||||
@@ -635,6 +644,7 @@ const getBindingStrategyForDraggingBindingElementEndpoints_simple = (
|
||||
draggingPoints,
|
||||
elementsMap,
|
||||
elements,
|
||||
opts?.zoom,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1156,6 +1166,7 @@ export const getHeadingForElbowArrowSnap = (
|
||||
aabb: Bounds | undefined | null,
|
||||
origPoint: GlobalPoint,
|
||||
elementsMap: ElementsMap,
|
||||
zoom?: AppState["zoom"],
|
||||
): Heading => {
|
||||
const otherPointHeading = vectorToHeading(vectorFromPoint(otherPoint, p));
|
||||
|
||||
@@ -1163,9 +1174,12 @@ export const getHeadingForElbowArrowSnap = (
|
||||
return otherPointHeading;
|
||||
}
|
||||
|
||||
const d = distanceToElement(bindableElement, elementsMap, origPoint);
|
||||
|
||||
const distance = d > 0 ? null : d;
|
||||
const distance = getDistanceForBinding(
|
||||
origPoint,
|
||||
bindableElement,
|
||||
elementsMap,
|
||||
zoom,
|
||||
);
|
||||
|
||||
if (!distance) {
|
||||
return vectorToHeading(
|
||||
@@ -1176,6 +1190,23 @@ export const getHeadingForElbowArrowSnap = (
|
||||
return headingForPointFromElement(bindableElement, aabb, p);
|
||||
};
|
||||
|
||||
const getDistanceForBinding = (
|
||||
point: Readonly<GlobalPoint>,
|
||||
bindableElement: ExcalidrawBindableElement,
|
||||
elementsMap: ElementsMap,
|
||||
zoom?: AppState["zoom"],
|
||||
) => {
|
||||
const distance = distanceToElement(bindableElement, elementsMap, point);
|
||||
const bindDistance = maxBindingGap_simple(
|
||||
bindableElement,
|
||||
bindableElement.width,
|
||||
bindableElement.height,
|
||||
zoom,
|
||||
);
|
||||
|
||||
return distance > bindDistance ? null : distance;
|
||||
};
|
||||
|
||||
export const bindPointToSnapToElementOutline = (
|
||||
linearElement: ExcalidrawArrowElement,
|
||||
bindableElement: ExcalidrawBindableElement,
|
||||
|
||||
@@ -30,6 +30,7 @@ import {
|
||||
getHeadingForElbowArrowSnap,
|
||||
getGlobalFixedPointForBindableElement,
|
||||
getFixedBindingDistance,
|
||||
maxBindingGap_simple,
|
||||
} from "./binding";
|
||||
import { distanceToElement } from "./distance";
|
||||
import {
|
||||
@@ -1217,9 +1218,19 @@ const getElbowArrowData = (
|
||||
if (options?.isDragging) {
|
||||
const elements = Array.from(elementsMap.values());
|
||||
hoveredStartElement =
|
||||
getHoveredElement(origStartGlobalPoint, elementsMap, elements) || null;
|
||||
getHoveredElement(
|
||||
origStartGlobalPoint,
|
||||
elementsMap,
|
||||
elements,
|
||||
options?.zoom,
|
||||
) || null;
|
||||
hoveredEndElement =
|
||||
getHoveredElement(origEndGlobalPoint, elementsMap, elements) || null;
|
||||
getHoveredElement(
|
||||
origEndGlobalPoint,
|
||||
elementsMap,
|
||||
elements,
|
||||
options?.zoom,
|
||||
) || null;
|
||||
} else {
|
||||
hoveredStartElement = arrow.startBinding
|
||||
? getBindableElementForId(arrow.startBinding.elementId, elementsMap) ||
|
||||
@@ -1264,6 +1275,7 @@ const getElbowArrowData = (
|
||||
hoveredStartElement,
|
||||
origStartGlobalPoint,
|
||||
elementsMap,
|
||||
options?.zoom,
|
||||
);
|
||||
const endHeading = getBindPointHeading(
|
||||
endGlobalPoint,
|
||||
@@ -1271,6 +1283,7 @@ const getElbowArrowData = (
|
||||
hoveredEndElement,
|
||||
origEndGlobalPoint,
|
||||
elementsMap,
|
||||
options?.zoom,
|
||||
);
|
||||
const startPointBounds = [
|
||||
startGlobalPoint[0] - 2,
|
||||
@@ -2229,6 +2242,7 @@ const getBindPointHeading = (
|
||||
hoveredElement: ExcalidrawBindableElement | null | undefined,
|
||||
origPoint: GlobalPoint,
|
||||
elementsMap: ElementsMap,
|
||||
zoom?: AppState["zoom"],
|
||||
): Heading =>
|
||||
getHeadingForElbowArrowSnap(
|
||||
p,
|
||||
@@ -2247,18 +2261,21 @@ const getBindPointHeading = (
|
||||
),
|
||||
origPoint,
|
||||
elementsMap,
|
||||
zoom,
|
||||
);
|
||||
|
||||
const getHoveredElement = (
|
||||
origPoint: GlobalPoint,
|
||||
elementsMap: NonDeletedSceneElementsMap,
|
||||
elements: readonly Ordered<NonDeletedExcalidrawElement>[],
|
||||
zoom?: AppState["zoom"],
|
||||
) => {
|
||||
return getHoveredElementForBinding(
|
||||
origPoint,
|
||||
elements,
|
||||
elementsMap,
|
||||
(element) => getFixedBindingDistance(element) + 1,
|
||||
(element) =>
|
||||
maxBindingGap_simple(element, element.width, element.height, zoom),
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -2142,7 +2142,7 @@ const pointDraggingUpdates = (
|
||||
);
|
||||
|
||||
// Linear elements have no special logic
|
||||
if (!isArrowElement(element) || isElbowArrow(element)) {
|
||||
if (!isArrowElement(element)) {
|
||||
return {
|
||||
positions: naiveDraggingPoints,
|
||||
};
|
||||
@@ -2153,12 +2153,6 @@ const pointDraggingUpdates = (
|
||||
element.points.length - 1,
|
||||
);
|
||||
|
||||
if (startIsDragged === endIsDragged) {
|
||||
return {
|
||||
positions: naiveDraggingPoints,
|
||||
};
|
||||
}
|
||||
|
||||
const { start, end } = getBindingStrategyForDraggingBindingElementEndpoints(
|
||||
element,
|
||||
naiveDraggingPoints,
|
||||
@@ -2172,6 +2166,25 @@ const pointDraggingUpdates = (
|
||||
},
|
||||
);
|
||||
|
||||
if (isElbowArrow(element)) {
|
||||
return {
|
||||
positions: naiveDraggingPoints,
|
||||
updates: {
|
||||
suggestedBinding: startIsDragged
|
||||
? start.element
|
||||
: endIsDragged
|
||||
? end.element
|
||||
: null,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
if (startIsDragged === endIsDragged) {
|
||||
return {
|
||||
positions: naiveDraggingPoints,
|
||||
};
|
||||
}
|
||||
|
||||
// Generate the next bindings for the arrow
|
||||
const updates: PointMoveOtherUpdates = {
|
||||
suggestedBinding: null,
|
||||
|
||||
Reference in New Issue
Block a user