From 9801b9a12f031f0dfc2fe1b19cd219e5b7a2ba43 Mon Sep 17 00:00:00 2001 From: Mark Tolmacs Date: Sun, 18 May 2025 19:47:28 +0200 Subject: [PATCH] Fix quarter snap Signed-off-by: Mark Tolmacs --- packages/element/src/binding.ts | 64 +++++++++--------------------- packages/element/src/elbowArrow.ts | 9 +---- 2 files changed, 19 insertions(+), 54 deletions(-) diff --git a/packages/element/src/binding.ts b/packages/element/src/binding.ts index f3a28cffd..32bbd4f1d 100644 --- a/packages/element/src/binding.ts +++ b/packages/element/src/binding.ts @@ -933,22 +933,24 @@ export const bindPointToSnapToElementOutline = ( const isHorizontal = headingIsHorizontal( headingForPointFromElement(bindableElement, aabb, globalP), ); + const snapPoint = snapToMid(bindableElement, edgePoint); const otherPoint = pointFrom( - isHorizontal ? center[0] : edgePoint[0], - !isHorizontal ? center[1] : edgePoint[1], + isHorizontal ? center[0] : snapPoint[0], + !isHorizontal ? center[1] : snapPoint[1], + ); + const intersector = lineSegment( + otherPoint, + pointFromVector( + vectorScale( + vectorNormalize(vectorFromPoint(snapPoint, otherPoint)), + Math.max(bindableElement.width, bindableElement.height) * 2, + ), + otherPoint, + ), ); intersection = intersectElementWithLineSegment( bindableElement, - lineSegment( - otherPoint, - pointFromVector( - vectorScale( - vectorNormalize(vectorFromPoint(edgePoint, otherPoint)), - Math.max(bindableElement.width, bindableElement.height) * 2, - ), - otherPoint, - ), - ), + intersector, FIXED_BINDING_DISTANCE, )[0]; } else { @@ -1084,9 +1086,7 @@ export const snapToMid = ( tolerance: number = 0.05, ): GlobalPoint => { const { x, y, width, height, angle } = element; - const center = elementCenterPoint(element, -0.1, -0.1); - const nonRotated = pointRotateRads(p, center, -angle as Radians); // snap-to-center point is adaptive to element size, but we don't want to go @@ -1100,72 +1100,44 @@ export const snapToMid = ( nonRotated[1] < center[1] + verticalThreshold ) { // LEFT - const otherPoint = pointRotateRads( + return pointRotateRads( pointFrom(x - FIXED_BINDING_DISTANCE, center[1]), center, angle, ); - return ( - intersectElementWithLineSegment( - element, - lineSegment(center, otherPoint), - FIXED_BINDING_DISTANCE, - )[0] ?? otherPoint - ); } else if ( nonRotated[1] <= y + height / 2 && nonRotated[0] > center[0] - horizontalThreshold && nonRotated[0] < center[0] + horizontalThreshold ) { // TOP - const otherPoint = pointRotateRads( + return pointRotateRads( pointFrom(center[0], y - FIXED_BINDING_DISTANCE), center, angle, ); - return ( - intersectElementWithLineSegment( - element, - lineSegment(center, otherPoint), - FIXED_BINDING_DISTANCE, - )[0] ?? otherPoint - ); } else if ( nonRotated[0] >= x + width / 2 && nonRotated[1] > center[1] - verticalThreshold && nonRotated[1] < center[1] + verticalThreshold ) { // RIGHT - const otherPoint = pointRotateRads( + return pointRotateRads( pointFrom(x + width + FIXED_BINDING_DISTANCE, center[1]), center, angle, ); - return ( - intersectElementWithLineSegment( - element, - lineSegment(center, otherPoint), - FIXED_BINDING_DISTANCE, - )[0] ?? otherPoint - ); } else if ( nonRotated[1] >= y + height / 2 && nonRotated[0] > center[0] - horizontalThreshold && nonRotated[0] < center[0] + horizontalThreshold ) { // DOWN - const otherPoint = pointRotateRads( + return pointRotateRads( pointFrom(center[0], y + height + FIXED_BINDING_DISTANCE), center, angle, ); - return ( - intersectElementWithLineSegment( - element, - lineSegment(center, otherPoint), - FIXED_BINDING_DISTANCE, - )[0] ?? otherPoint - ); } else if (element.type === "diamond") { const distance = FIXED_BINDING_DISTANCE; const topLeft = pointFrom( diff --git a/packages/element/src/elbowArrow.ts b/packages/element/src/elbowArrow.ts index 990f4e570..e267a71a3 100644 --- a/packages/element/src/elbowArrow.ts +++ b/packages/element/src/elbowArrow.ts @@ -29,7 +29,6 @@ import { FIXED_BINDING_DISTANCE, getHeadingForElbowArrowSnap, getGlobalFixedPointForBindableElement, - snapToMid, getHoveredElementForBinding, } from "./binding"; import { distanceToElement } from "./distance"; @@ -2214,13 +2213,7 @@ const getGlobalPoint = ( ): GlobalPoint => { if (isDragging) { if (element) { - const snapPoint = bindPointToSnapToElementOutline( - arrow, - element, - startOrEnd, - ); - - return snapToMid(element, snapPoint); + return bindPointToSnapToElementOutline(arrow, element, startOrEnd); } return initialPoint;