From 99b91c46f7d2153eab61e4b92f6d82a3f9769e32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1rk=20Tolm=C3=A1cs?= Date: Fri, 9 Aug 2024 17:33:12 +0200 Subject: [PATCH] fix: Yet more patching of intersect code (#8352) * Yet more patching of intersect code --- packages/excalidraw/element/binding.ts | 31 +++++++++++++++-------- packages/excalidraw/element/typeChecks.ts | 17 +++++++++++++ 2 files changed, 37 insertions(+), 11 deletions(-) diff --git a/packages/excalidraw/element/binding.ts b/packages/excalidraw/element/binding.ts index 2c7ef13d53..eb982470ef 100644 --- a/packages/excalidraw/element/binding.ts +++ b/packages/excalidraw/element/binding.ts @@ -41,6 +41,7 @@ import { isElbowArrow, isFrameLikeElement, isLinearElement, + isRectangularElement, isTextElement, } from "./typeChecks"; import type { ElementUpdate } from "./mutateElement"; @@ -751,7 +752,7 @@ export const bindPointToSnapToElementOutline = ( const aabb = bindableElement && aabbForElement(bindableElement); if (bindableElement && aabb) { - // TODO: Dirty hack until tangents are properly calculated + // TODO: Dirty hacks until tangents are properly calculated const intersections = [ ...intersectElementWithLine( bindableElement, @@ -759,24 +760,32 @@ export const bindPointToSnapToElementOutline = ( [point[0], point[1] + 2 * bindableElement.height], FIXED_BINDING_DISTANCE, elementsMap, - ).map((i) => - distanceToBindableElement(bindableElement, i, elementsMap) >= - bindableElement.height / 2 + ).map((i) => { + if (!isRectangularElement(bindableElement)) { + return i; + } + + const d = distanceToBindableElement(bindableElement, i, elementsMap); + return d >= bindableElement.height / 2 || d < FIXED_BINDING_DISTANCE ? ([point[0], -1 * i[1]] as Point) - : ([point[0], i[1]] as Point), - ), + : ([point[0], i[1]] as Point); + }), ...intersectElementWithLine( bindableElement, [point[0] - 2 * bindableElement.width, point[1]], [point[0] + 2 * bindableElement.width, point[1]], FIXED_BINDING_DISTANCE, elementsMap, - ).map((i) => - distanceToBindableElement(bindableElement, i, elementsMap) >= - bindableElement.width / 2 + ).map((i) => { + if (!isRectangularElement(bindableElement)) { + return i; + } + + const d = distanceToBindableElement(bindableElement, i, elementsMap); + return d >= bindableElement.width / 2 || d < FIXED_BINDING_DISTANCE ? ([-1 * i[0], point[1]] as Point) - : ([i[0], point[1]] as Point), - ), + : ([i[0], point[1]] as Point); + }), ]; const heading = headingForPointFromElement(bindableElement, aabb, point); diff --git a/packages/excalidraw/element/typeChecks.ts b/packages/excalidraw/element/typeChecks.ts index 821ba2d368..9c1d6913dc 100644 --- a/packages/excalidraw/element/typeChecks.ts +++ b/packages/excalidraw/element/typeChecks.ts @@ -176,6 +176,23 @@ export const isRectanguloidElement = ( ); }; +// TODO: Remove this when proper distance calculation is introduced +// @see binding.ts:distanceToBindableElement() +export const isRectangularElement = ( + element?: ExcalidrawElement | null, +): element is ExcalidrawBindableElement => { + return ( + element != null && + (element.type === "rectangle" || + element.type === "image" || + element.type === "text" || + element.type === "iframe" || + element.type === "embeddable" || + element.type === "frame" || + element.type === "magicframe") + ); +}; + export const isTextBindableContainer = ( element: ExcalidrawElement | null, includeLocked = true,