mirror of
https://github.com/excalidraw/excalidraw.git
synced 2025-09-19 15:31:04 +02:00
fix: Overlap behavior
This commit is contained in:
@@ -3,6 +3,7 @@ import {
|
|||||||
arrayToMap,
|
arrayToMap,
|
||||||
invariant,
|
invariant,
|
||||||
isAlwaysInsideBinding,
|
isAlwaysInsideBinding,
|
||||||
|
isTransparent,
|
||||||
} from "@excalidraw/common";
|
} from "@excalidraw/common";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@@ -303,49 +304,31 @@ const bindingStrategyForNewSimpleArrowEndpointDragging = (
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check and handle nested shapes
|
// Check and handle nested shapes
|
||||||
if (arrow.startBinding) {
|
if (hit && arrow.startBinding) {
|
||||||
const otherElement = elementsMap.get(
|
const otherElement = elementsMap.get(
|
||||||
arrow.startBinding.elementId,
|
arrow.startBinding.elementId,
|
||||||
) as ExcalidrawBindableElement;
|
) as ExcalidrawBindableElement;
|
||||||
invariant(otherElement, "Other element must be in the elements map");
|
|
||||||
const startFocusElements = getAllHoveredElementAtPoint(
|
|
||||||
getGlobalFixedPointForBindableElement(
|
|
||||||
arrow.startBinding.fixedPoint,
|
|
||||||
otherElement,
|
|
||||||
elementsMap,
|
|
||||||
),
|
|
||||||
elements,
|
|
||||||
elementsMap,
|
|
||||||
);
|
|
||||||
const startHoverElements = getAllHoveredElementAtPoint(
|
|
||||||
LinearElementEditor.getPointAtIndexGlobalCoordinates(
|
|
||||||
arrow,
|
|
||||||
0,
|
|
||||||
elementsMap,
|
|
||||||
),
|
|
||||||
elements,
|
|
||||||
elementsMap,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (
|
invariant(otherElement, "Other element must be in the elements map");
|
||||||
hit &&
|
|
||||||
otherElement.id !== hit.id &&
|
const allHits = getAllHoveredElementAtPoint(point, elements, elementsMap);
|
||||||
(startHoverElements.find((el) => el.id === hit.id) ||
|
|
||||||
startFocusElements.find((el) => el.id === hit.id))
|
if (allHits.find((el) => el.id === otherElement.id)) {
|
||||||
) {
|
const otherIsTransparent = isTransparent(otherElement.backgroundColor);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
start: isMultiPoint
|
start: isMultiPoint
|
||||||
? { mode: undefined }
|
? { mode: undefined }
|
||||||
: {
|
: {
|
||||||
mode: "orbit",
|
mode: "inside",
|
||||||
element: otherElement,
|
element: otherElement,
|
||||||
focusPoint: snapToCenter(
|
focusPoint: origin ?? pointFrom<GlobalPoint>(arrow.x, arrow.y),
|
||||||
otherElement,
|
|
||||||
elementsMap,
|
|
||||||
origin ?? pointFrom<GlobalPoint>(arrow.x, arrow.y),
|
|
||||||
),
|
|
||||||
},
|
},
|
||||||
end: { mode: "inside", element: hit, focusPoint: point },
|
end: {
|
||||||
|
mode: "inside",
|
||||||
|
element: otherIsTransparent ? hit : otherElement,
|
||||||
|
focusPoint: point,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -117,6 +117,7 @@ type PointMoveOtherUpdates = {
|
|||||||
startBinding?: FixedPointBinding | null;
|
startBinding?: FixedPointBinding | null;
|
||||||
endBinding?: FixedPointBinding | null;
|
endBinding?: FixedPointBinding | null;
|
||||||
moveMidPointsWithElement?: boolean | null;
|
moveMidPointsWithElement?: boolean | null;
|
||||||
|
suggestedBinding?: AppState["suggestedBinding"] | null;
|
||||||
};
|
};
|
||||||
|
|
||||||
export class LinearElementEditor {
|
export class LinearElementEditor {
|
||||||
@@ -484,6 +485,7 @@ export class LinearElementEditor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Apply the point movement if needed
|
// Apply the point movement if needed
|
||||||
|
let suggestedBinding: AppState["suggestedBinding"] = null;
|
||||||
if (deltaX || deltaY) {
|
if (deltaX || deltaY) {
|
||||||
const { positions, updates } = pointDraggingUpdates(
|
const { positions, updates } = pointDraggingUpdates(
|
||||||
selectedPointsIndices,
|
selectedPointsIndices,
|
||||||
@@ -497,6 +499,13 @@ export class LinearElementEditor {
|
|||||||
|
|
||||||
LinearElementEditor.movePoints(element, app.scene, positions, updates);
|
LinearElementEditor.movePoints(element, app.scene, positions, updates);
|
||||||
|
|
||||||
|
// Set the suggested binding from the updates if available
|
||||||
|
if (isBindingElement(element, false)) {
|
||||||
|
if (isBindingEnabled(app.state) && (startIsSelected || endIsSelected)) {
|
||||||
|
suggestedBinding = updates?.suggestedBinding ?? null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Move the arrow over the bindable object in terms of z-index
|
// Move the arrow over the bindable object in terms of z-index
|
||||||
if (isBindingElement(element) && startIsSelected !== endIsSelected) {
|
if (isBindingElement(element) && startIsSelected !== endIsSelected) {
|
||||||
moveArrowAboveBindable(
|
moveArrowAboveBindable(
|
||||||
@@ -522,7 +531,6 @@ export class LinearElementEditor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Suggest bindings for first and last point if selected
|
// Suggest bindings for first and last point if selected
|
||||||
let suggestedBinding: AppState["suggestedBinding"] = null;
|
|
||||||
if (isBindingElement(element, false)) {
|
if (isBindingElement(element, false)) {
|
||||||
if (isBindingEnabled(app.state) && (startIsSelected || endIsSelected)) {
|
if (isBindingEnabled(app.state) && (startIsSelected || endIsSelected)) {
|
||||||
suggestedBinding = maybeSuggestBindingsForBindingElementAtCoords(
|
suggestedBinding = maybeSuggestBindingsForBindingElementAtCoords(
|
||||||
@@ -2086,7 +2094,9 @@ const pointDraggingUpdates = (
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Generate the next bindings for the arrow
|
// Generate the next bindings for the arrow
|
||||||
const updates: PointMoveOtherUpdates = {};
|
const updates: PointMoveOtherUpdates = {
|
||||||
|
suggestedBinding: null,
|
||||||
|
};
|
||||||
if (start.mode === null) {
|
if (start.mode === null) {
|
||||||
updates.startBinding = null;
|
updates.startBinding = null;
|
||||||
} else if (start.mode) {
|
} else if (start.mode) {
|
||||||
@@ -2101,6 +2111,10 @@ const pointDraggingUpdates = (
|
|||||||
start.focusPoint,
|
start.focusPoint,
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (startIsDragged) {
|
||||||
|
updates.suggestedBinding = start.element;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (end.mode === null) {
|
if (end.mode === null) {
|
||||||
updates.endBinding = null;
|
updates.endBinding = null;
|
||||||
@@ -2116,6 +2130,10 @@ const pointDraggingUpdates = (
|
|||||||
end.focusPoint,
|
end.focusPoint,
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (endIsDragged) {
|
||||||
|
updates.suggestedBinding = end.element;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Simulate the updated arrow for the bind point calculation
|
// Simulate the updated arrow for the bind point calculation
|
||||||
|
Reference in New Issue
Block a user