From c0efc162703bc360940611ddbfdacd87fb2e051f Mon Sep 17 00:00:00 2001 From: Ryan Di Date: Wed, 19 Jul 2023 18:15:04 +0800 Subject: [PATCH] fix: do not bind invisible part of an element to arrow --- src/element/binding.ts | 33 +++++++++++++++++++++++++++++---- src/frame.ts | 10 ++++++++++ 2 files changed, 39 insertions(+), 4 deletions(-) diff --git a/src/element/binding.ts b/src/element/binding.ts index b175f14e7..4bc7e4271 100644 --- a/src/element/binding.ts +++ b/src/element/binding.ts @@ -27,6 +27,7 @@ import { LinearElementEditor } from "./linearElementEditor"; import { arrayToMap, tupleToCoors } from "../utils"; import { KEYS } from "../keys"; import { getBoundTextElement, handleBindTextResize } from "./textElement"; +import { getContainingFrame, isPointInFrame } from "../frame"; export type SuggestedBinding = | NonDeleted @@ -274,6 +275,18 @@ export const getHoveredElementForBinding = ( isBindableElement(element, false) && bindingBorderTest(element, pointerCoords), ); + + if (hoveredElement) { + const frame = getContainingFrame(hoveredElement); + + if (frame) { + if (isPointInFrame(pointerCoords, frame)) { + return hoveredElement as NonDeleted; + } + return null; + } + } + return hoveredElement as NonDeleted | null; }; @@ -499,10 +512,22 @@ const getElligibleElementsForBindingElement = ( return [ getElligibleElementForBindingElement(linearElement, "start"), getElligibleElementForBindingElement(linearElement, "end"), - ].filter( - (element): element is NonDeleted => - element != null, - ); + ].filter((element): element is NonDeleted => { + if (element != null) { + const frame = getContainingFrame(element); + return frame + ? isPointInFrame( + getLinearElementEdgeCoors(linearElement, "start"), + frame, + ) || + isPointInFrame( + getLinearElementEdgeCoors(linearElement, "end"), + frame, + ) + : true; + } + return false; + }); }; const getElligibleElementForBindingElement = ( diff --git a/src/frame.ts b/src/frame.ts index 8a39a41b3..8f143203d 100644 --- a/src/frame.ts +++ b/src/frame.ts @@ -1,6 +1,7 @@ import { getCommonBounds, getElementAbsoluteCoords, + getElementBounds, isTextElement, } from "./element"; import { @@ -299,6 +300,15 @@ export const groupsAreCompletelyOutOfFrame = ( ); }; +export const isPointInFrame = ( + { x, y }: { x: number; y: number }, + frame: ExcalidrawFrameElement, +) => { + const [x1, y1, x2, y2] = getElementBounds(frame); + + return x >= x1 && x <= x2 && y >= y1 && y <= y2; +}; + // --------------------------- Frame Utils ------------------------------------ /**