diff --git a/packages/element/src/binding.ts b/packages/element/src/binding.ts index 821ed78965..e771ba3e88 100644 --- a/packages/element/src/binding.ts +++ b/packages/element/src/binding.ts @@ -275,7 +275,7 @@ const getBindingStrategyForDraggingArrowEndpoints = ( const endDragged = draggingPoints.findIndex((i) => i === endIdx) > -1; const start = startDragged ? isBindingEnabled - ? getElligibleElementForBindingElement( + ? getEligibleElementForBindingElement( selectedElement, "start", elementsMap, @@ -285,7 +285,7 @@ const getBindingStrategyForDraggingArrowEndpoints = ( : null // If binding is disabled and start is dragged, break all binds : !isElbowArrow(selectedElement) ? // We have to update the focus and gap of the binding, so let's rebind - getElligibleElementForBindingElement( + getEligibleElementForBindingElement( selectedElement, "start", elementsMap, @@ -295,7 +295,7 @@ const getBindingStrategyForDraggingArrowEndpoints = ( : "keep"; const end = endDragged ? isBindingEnabled - ? getElligibleElementForBindingElement( + ? getEligibleElementForBindingElement( selectedElement, "end", elementsMap, @@ -305,7 +305,7 @@ const getBindingStrategyForDraggingArrowEndpoints = ( : null // If binding is disabled and end is dragged, break all binds : !isElbowArrow(selectedElement) ? // We have to update the focus and gap of the binding, so let's rebind - getElligibleElementForBindingElement( + getEligibleElementForBindingElement( selectedElement, "end", elementsMap, @@ -336,7 +336,7 @@ const getBindingStrategyForDraggingArrowOrJoints = ( ); const start = startIsClose ? isBindingEnabled - ? getElligibleElementForBindingElement( + ? getEligibleElementForBindingElement( selectedElement, "start", elementsMap, @@ -347,7 +347,7 @@ const getBindingStrategyForDraggingArrowOrJoints = ( : null; const end = endIsClose ? isBindingEnabled - ? getElligibleElementForBindingElement( + ? getEligibleElementForBindingElement( selectedElement, "end", elementsMap, @@ -903,6 +903,13 @@ export const bindPointToSnapToElementOutline = ( ); const edgePoint = avoidRectangularCorner(bindableElement, p); + const otherPointIdx = + startOrEnd === "start" ? linearElement.points.length - 1 : 0; + const otherPoint = pointFrom( + linearElement.x + linearElement.points[otherPointIdx][0], + linearElement.y + linearElement.points[otherPointIdx][1], + ); + const adjacentPointIdx = startOrEnd === "start" ? 1 : linearElement.points.length - 2; const adjacentPoint = @@ -968,6 +975,14 @@ export const bindPointToSnapToElementOutline = ( return edgePoint; } + const shape = getElementShape(bindableElement, elementsMap); + const pointInShape = isPointInShape(edgePoint, shape); + const otherPointInShape = isPointInShape(otherPoint, shape); + + if (pointInShape && otherPointInShape) { + return edgePoint; + } + if (elbowed) { const scalar = pointDistanceSq(edgePoint, center) - @@ -1379,7 +1394,7 @@ export const calculateFixedPointForElbowArrowBinding = ( }; }; -const getElligibleElementForBindingElement = ( +const getEligibleElementForBindingElement = ( linearElement: NonDeleted, startOrEnd: "start" | "end", elementsMap: NonDeletedSceneElementsMap, diff --git a/packages/element/src/elbowArrow.ts b/packages/element/src/elbowArrow.ts index 71552cce82..d77bf8280d 100644 --- a/packages/element/src/elbowArrow.ts +++ b/packages/element/src/elbowArrow.ts @@ -63,7 +63,6 @@ import type { ExcalidrawBindableElement, FixedPointBinding, FixedSegment, - NonDeletedExcalidrawElement, } from "./types"; type GridAddress = [number, number] & { _brand: "gridaddress" }; @@ -1221,18 +1220,22 @@ const getElbowArrowData = ( if (options?.isDragging) { const elements = Array.from(elementsMap.values()); hoveredStartElement = - getHoveredElement( - origStartGlobalPoint, - elementsMap, + getHoveredElementForBinding( + tupleToCoors(origStartGlobalPoint), elements, + elementsMap, options?.zoom, + true, + true, ) || null; hoveredEndElement = - getHoveredElement( - origEndGlobalPoint, - elementsMap, + getHoveredElementForBinding( + tupleToCoors(origEndGlobalPoint), elements, + elementsMap, options?.zoom, + true, + true, ) || null; } else { hoveredStartElement = arrow.startBinding @@ -2275,22 +2278,6 @@ const getBindPointHeading = ( origPoint, ); -const getHoveredElement = ( - origPoint: GlobalPoint, - elementsMap: NonDeletedSceneElementsMap, - elements: readonly NonDeletedExcalidrawElement[], - zoom?: AppState["zoom"], -) => { - return getHoveredElementForBinding( - tupleToCoors(origPoint), - elements, - elementsMap, - zoom, - true, - true, - ); -}; - const gridAddressesEqual = (a: GridAddress, b: GridAddress): boolean => a[0] === b[0] && a[1] === b[1];