diff --git a/packages/excalidraw/element/binding.ts b/packages/excalidraw/element/binding.ts index b9aa72ff2..31e1212fb 100644 --- a/packages/excalidraw/element/binding.ts +++ b/packages/excalidraw/element/binding.ts @@ -29,7 +29,12 @@ import type { } from "./types"; import type { Bounds } from "./bounds"; -import { getCenterForBounds, getElementAbsoluteCoords } from "./bounds"; +import { + getCenterForBounds, + getElementAbsoluteCoords, + getElementBounds, + doBoundsIntersect, +} from "./bounds"; import type { AppState } from "../types"; import { isPointOnShape } from "../../utils/collision"; import { getElementAtPosition } from "../scene"; @@ -599,6 +604,21 @@ export const updateBoundElements = ( return; } + // Check for intersections before updating bound elements incase connected elements overlap + const startBindingElement = element.startBinding + ? elementsMap.get(element.startBinding.elementId) + : null; + const endBindingElement = element.endBinding + ? elementsMap.get(element.endBinding.elementId) + : null; + + let startBounds: Bounds | null = null; + let endBounds: Bounds | null = null; + if (startBindingElement && endBindingElement) { + startBounds = getElementBounds(startBindingElement, elementsMap); + endBounds = getElementBounds(endBindingElement, elementsMap); + } + const bindings = { startBinding: maybeCalculateNewGapWhenScaling( changedElement, @@ -627,10 +647,11 @@ export const updateBoundElements = ( isBindableElement(bindableElement) && (bindingProp === "startBinding" || bindingProp === "endBinding") && (changedElement.id === element[bindingProp]?.elementId || - changedElement.id === + (changedElement.id === element[ bindingProp === "startBinding" ? "endBinding" : "startBinding" - ]?.elementId) + ]?.elementId && + !doBoundsIntersect(startBounds, endBounds))) ) { const point = updateBoundPoint( element, diff --git a/packages/excalidraw/element/bounds.ts b/packages/excalidraw/element/bounds.ts index 6fedd4113..276448d55 100644 --- a/packages/excalidraw/element/bounds.ts +++ b/packages/excalidraw/element/bounds.ts @@ -994,3 +994,17 @@ export const getCenterForBounds = (bounds: Bounds): GlobalPoint => bounds[0] + (bounds[2] - bounds[0]) / 2, bounds[1] + (bounds[3] - bounds[1]) / 2, ); + +export const doBoundsIntersect = ( + bounds1: Bounds | null, + bounds2: Bounds | null, +): boolean => { + if (bounds1 == null || bounds2 == null) { + return false; + } + + const [minX1, minY1, maxX1, maxY1] = bounds1; + const [minX2, minY2, maxX2, maxY2] = bounds2; + + return minX1 < maxX2 && maxX1 > minX2 && minY1 < maxY2 && maxY1 > minY2; +};