mirror of
https://github.com/excalidraw/excalidraw.git
synced 2025-09-14 13:00:09 +02:00
fix: Existing arrow nested bindable
Signed-off-by: Mark Tolmacs <mark@lazycat.hu>
This commit is contained in:
@@ -305,15 +305,16 @@ const bindingStrategyForNewSimpleArrowEndpointDragging = (
|
|||||||
|
|
||||||
// Check and handle nested shapes
|
// Check and handle nested shapes
|
||||||
if (hit && arrow.startBinding) {
|
if (hit && arrow.startBinding) {
|
||||||
const otherElement = elementsMap.get(
|
const startBinding = arrow.startBinding;
|
||||||
arrow.startBinding.elementId,
|
|
||||||
) as ExcalidrawBindableElement;
|
|
||||||
|
|
||||||
invariant(otherElement, "Other element must be in the elements map");
|
|
||||||
|
|
||||||
const allHits = getAllHoveredElementAtPoint(point, elements, elementsMap);
|
const allHits = getAllHoveredElementAtPoint(point, elements, elementsMap);
|
||||||
|
|
||||||
if (allHits.find((el) => el.id === otherElement.id)) {
|
if (allHits.find((el) => el.id === startBinding.elementId)) {
|
||||||
|
const otherElement = elementsMap.get(
|
||||||
|
arrow.startBinding.elementId,
|
||||||
|
) as ExcalidrawBindableElement;
|
||||||
|
|
||||||
|
invariant(otherElement, "Other element must be in the elements map");
|
||||||
|
|
||||||
const otherIsTransparent = isTransparent(otherElement.backgroundColor);
|
const otherIsTransparent = isTransparent(otherElement.backgroundColor);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@@ -414,6 +415,20 @@ const bindingStrategyForSimpleArrowEndpointDragging = (
|
|||||||
|
|
||||||
const isMultiPoint = arrow.points.length > 2;
|
const isMultiPoint = arrow.points.length > 2;
|
||||||
const hit = getHoveredElementForBinding(point, elements, elementsMap);
|
const hit = getHoveredElementForBinding(point, elements, elementsMap);
|
||||||
|
const isNested = oppositeBinding
|
||||||
|
? getAllHoveredElementAtPoint(point, elements, elementsMap).some(
|
||||||
|
(el) => el.id === oppositeBinding.elementId,
|
||||||
|
)
|
||||||
|
: false;
|
||||||
|
const oppositeElement =
|
||||||
|
isNested && oppositeBinding
|
||||||
|
? (elementsMap.get(
|
||||||
|
oppositeBinding.elementId,
|
||||||
|
) as ExcalidrawBindableElement)
|
||||||
|
: null;
|
||||||
|
const otherIsTransparent = oppositeElement
|
||||||
|
? isTransparent(oppositeElement.backgroundColor)
|
||||||
|
: false;
|
||||||
|
|
||||||
// If the global bind mode is in free binding mode, just bind
|
// If the global bind mode is in free binding mode, just bind
|
||||||
// where the pointer is and keep the other end intact
|
// where the pointer is and keep the other end intact
|
||||||
@@ -424,7 +439,10 @@ const bindingStrategyForSimpleArrowEndpointDragging = (
|
|||||||
) {
|
) {
|
||||||
current = hit
|
current = hit
|
||||||
? {
|
? {
|
||||||
element: hit,
|
element:
|
||||||
|
!isNested || !oppositeElement || otherIsTransparent
|
||||||
|
? hit
|
||||||
|
: oppositeElement,
|
||||||
focusPoint: point,
|
focusPoint: point,
|
||||||
mode: "inside",
|
mode: "inside",
|
||||||
}
|
}
|
||||||
@@ -440,10 +458,8 @@ const bindingStrategyForSimpleArrowEndpointDragging = (
|
|||||||
}
|
}
|
||||||
|
|
||||||
// The dragged point is inside the hovered bindable element
|
// The dragged point is inside the hovered bindable element
|
||||||
|
|
||||||
// The opposite binding is on the same element
|
|
||||||
// eslint-disable-next-line no-lonely-if
|
|
||||||
if (oppositeBinding) {
|
if (oppositeBinding) {
|
||||||
|
// The opposite binding is on the same element
|
||||||
if (oppositeBinding.elementId === hit.id) {
|
if (oppositeBinding.elementId === hit.id) {
|
||||||
// The opposite binding is on the binding gap of the same element
|
// The opposite binding is on the binding gap of the same element
|
||||||
if (oppositeBinding.mode === "orbit") {
|
if (oppositeBinding.mode === "orbit") {
|
||||||
@@ -460,14 +476,23 @@ const bindingStrategyForSimpleArrowEndpointDragging = (
|
|||||||
return { current, other: isMultiPoint ? { mode: undefined } : other };
|
return { current, other: isMultiPoint ? { mode: undefined } : other };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// The opposite binding is on a different element
|
// The opposite binding is on a different element (or nested)
|
||||||
// eslint-disable-next-line no-else-return
|
// eslint-disable-next-line no-else-return
|
||||||
else {
|
else {
|
||||||
current = {
|
// Handle the nested element case
|
||||||
element: hit,
|
if (isNested && oppositeElement && !otherIsTransparent) {
|
||||||
mode: "orbit",
|
current = {
|
||||||
focusPoint: snapToCenter(hit, elementsMap, point),
|
element: oppositeElement,
|
||||||
};
|
mode: "inside",
|
||||||
|
focusPoint: point,
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
current = {
|
||||||
|
element: hit,
|
||||||
|
mode: "orbit",
|
||||||
|
focusPoint: snapToCenter(hit, elementsMap, point),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
return { current, other: isMultiPoint ? { mode: undefined } : other };
|
return { current, other: isMultiPoint ? { mode: undefined } : other };
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user