Fix quarter snap

Signed-off-by: Mark Tolmacs <mark@lazycat.hu>
This commit is contained in:
Mark Tolmacs 2025-05-18 19:47:28 +02:00
parent 946c366a1c
commit 9801b9a12f
No known key found for this signature in database
2 changed files with 19 additions and 54 deletions

View File

@ -933,22 +933,24 @@ export const bindPointToSnapToElementOutline = (
const isHorizontal = headingIsHorizontal( const isHorizontal = headingIsHorizontal(
headingForPointFromElement(bindableElement, aabb, globalP), headingForPointFromElement(bindableElement, aabb, globalP),
); );
const snapPoint = snapToMid(bindableElement, edgePoint);
const otherPoint = pointFrom<GlobalPoint>( const otherPoint = pointFrom<GlobalPoint>(
isHorizontal ? center[0] : edgePoint[0], isHorizontal ? center[0] : snapPoint[0],
!isHorizontal ? center[1] : edgePoint[1], !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( intersection = intersectElementWithLineSegment(
bindableElement, bindableElement,
lineSegment( intersector,
otherPoint,
pointFromVector(
vectorScale(
vectorNormalize(vectorFromPoint(edgePoint, otherPoint)),
Math.max(bindableElement.width, bindableElement.height) * 2,
),
otherPoint,
),
),
FIXED_BINDING_DISTANCE, FIXED_BINDING_DISTANCE,
)[0]; )[0];
} else { } else {
@ -1084,9 +1086,7 @@ export const snapToMid = (
tolerance: number = 0.05, tolerance: number = 0.05,
): GlobalPoint => { ): GlobalPoint => {
const { x, y, width, height, angle } = element; const { x, y, width, height, angle } = element;
const center = elementCenterPoint(element, -0.1, -0.1); const center = elementCenterPoint(element, -0.1, -0.1);
const nonRotated = pointRotateRads(p, center, -angle as Radians); const nonRotated = pointRotateRads(p, center, -angle as Radians);
// snap-to-center point is adaptive to element size, but we don't want to go // 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 nonRotated[1] < center[1] + verticalThreshold
) { ) {
// LEFT // LEFT
const otherPoint = pointRotateRads<GlobalPoint>( return pointRotateRads<GlobalPoint>(
pointFrom(x - FIXED_BINDING_DISTANCE, center[1]), pointFrom(x - FIXED_BINDING_DISTANCE, center[1]),
center, center,
angle, angle,
); );
return (
intersectElementWithLineSegment(
element,
lineSegment(center, otherPoint),
FIXED_BINDING_DISTANCE,
)[0] ?? otherPoint
);
} else if ( } else if (
nonRotated[1] <= y + height / 2 && nonRotated[1] <= y + height / 2 &&
nonRotated[0] > center[0] - horizontalThreshold && nonRotated[0] > center[0] - horizontalThreshold &&
nonRotated[0] < center[0] + horizontalThreshold nonRotated[0] < center[0] + horizontalThreshold
) { ) {
// TOP // TOP
const otherPoint = pointRotateRads<GlobalPoint>( return pointRotateRads(
pointFrom(center[0], y - FIXED_BINDING_DISTANCE), pointFrom(center[0], y - FIXED_BINDING_DISTANCE),
center, center,
angle, angle,
); );
return (
intersectElementWithLineSegment(
element,
lineSegment(center, otherPoint),
FIXED_BINDING_DISTANCE,
)[0] ?? otherPoint
);
} else if ( } else if (
nonRotated[0] >= x + width / 2 && nonRotated[0] >= x + width / 2 &&
nonRotated[1] > center[1] - verticalThreshold && nonRotated[1] > center[1] - verticalThreshold &&
nonRotated[1] < center[1] + verticalThreshold nonRotated[1] < center[1] + verticalThreshold
) { ) {
// RIGHT // RIGHT
const otherPoint = pointRotateRads<GlobalPoint>( return pointRotateRads(
pointFrom(x + width + FIXED_BINDING_DISTANCE, center[1]), pointFrom(x + width + FIXED_BINDING_DISTANCE, center[1]),
center, center,
angle, angle,
); );
return (
intersectElementWithLineSegment(
element,
lineSegment(center, otherPoint),
FIXED_BINDING_DISTANCE,
)[0] ?? otherPoint
);
} else if ( } else if (
nonRotated[1] >= y + height / 2 && nonRotated[1] >= y + height / 2 &&
nonRotated[0] > center[0] - horizontalThreshold && nonRotated[0] > center[0] - horizontalThreshold &&
nonRotated[0] < center[0] + horizontalThreshold nonRotated[0] < center[0] + horizontalThreshold
) { ) {
// DOWN // DOWN
const otherPoint = pointRotateRads<GlobalPoint>( return pointRotateRads(
pointFrom(center[0], y + height + FIXED_BINDING_DISTANCE), pointFrom(center[0], y + height + FIXED_BINDING_DISTANCE),
center, center,
angle, angle,
); );
return (
intersectElementWithLineSegment(
element,
lineSegment(center, otherPoint),
FIXED_BINDING_DISTANCE,
)[0] ?? otherPoint
);
} else if (element.type === "diamond") { } else if (element.type === "diamond") {
const distance = FIXED_BINDING_DISTANCE; const distance = FIXED_BINDING_DISTANCE;
const topLeft = pointFrom<GlobalPoint>( const topLeft = pointFrom<GlobalPoint>(

View File

@ -29,7 +29,6 @@ import {
FIXED_BINDING_DISTANCE, FIXED_BINDING_DISTANCE,
getHeadingForElbowArrowSnap, getHeadingForElbowArrowSnap,
getGlobalFixedPointForBindableElement, getGlobalFixedPointForBindableElement,
snapToMid,
getHoveredElementForBinding, getHoveredElementForBinding,
} from "./binding"; } from "./binding";
import { distanceToElement } from "./distance"; import { distanceToElement } from "./distance";
@ -2214,13 +2213,7 @@ const getGlobalPoint = (
): GlobalPoint => { ): GlobalPoint => {
if (isDragging) { if (isDragging) {
if (element) { if (element) {
const snapPoint = bindPointToSnapToElementOutline( return bindPointToSnapToElementOutline(arrow, element, startOrEnd);
arrow,
element,
startOrEnd,
);
return snapToMid(element, snapPoint);
} }
return initialPoint; return initialPoint;