Refine corner avoidance

This commit is contained in:
Mark Tolmacs 2025-04-25 14:25:40 +02:00
parent 41711af210
commit ece841326b
No known key found for this signature in database

View File

@ -45,6 +45,12 @@ import {
import { intersectElementWithLineSegment } from "./collision"; import { intersectElementWithLineSegment } from "./collision";
import { distanceToBindableElement } from "./distance"; import { distanceToBindableElement } from "./distance";
import { import {
compareHeading,
HEADING_DOWN,
HEADING_LEFT,
HEADING_RIGHT,
HEADING_UP,
headingForPoint,
headingForPointFromElement, headingForPointFromElement,
headingIsHorizontal, headingIsHorizontal,
vectorToHeading, vectorToHeading,
@ -87,6 +93,7 @@ import type {
SceneElementsMap, SceneElementsMap,
FixedPointBinding, FixedPointBinding,
} from "./types"; } from "./types";
import { debugDrawLine, debugDrawPoint } from "@excalidraw/utils/visualdebug";
export type SuggestedBinding = export type SuggestedBinding =
| NonDeleted<ExcalidrawBindableElement> | NonDeleted<ExcalidrawBindableElement>
@ -1040,7 +1047,14 @@ export const avoidRectangularCorner = (
if (nonRotatedPoint[0] < element.x && nonRotatedPoint[1] < element.y) { if (nonRotatedPoint[0] < element.x && nonRotatedPoint[1] < element.y) {
// Top left // Top left
if (nonRotatedPoint[1] - element.y > -FIXED_BINDING_DISTANCE) { const heading = headingForPoint(
nonRotatedPoint,
pointFrom(element.x, element.y),
);
if (
compareHeading(heading, HEADING_DOWN) ||
compareHeading(heading, HEADING_LEFT)
) {
return pointRotateRads<GlobalPoint>( return pointRotateRads<GlobalPoint>(
pointFrom(element.x - FIXED_BINDING_DISTANCE, element.y), pointFrom(element.x - FIXED_BINDING_DISTANCE, element.y),
center, center,
@ -1057,7 +1071,14 @@ export const avoidRectangularCorner = (
nonRotatedPoint[1] > element.y + element.height nonRotatedPoint[1] > element.y + element.height
) { ) {
// Bottom left // Bottom left
if (nonRotatedPoint[0] - element.x > -FIXED_BINDING_DISTANCE) { const heading = headingForPoint(
nonRotatedPoint,
pointFrom(element.x, element.y + element.height),
);
if (
compareHeading(heading, HEADING_DOWN) ||
compareHeading(heading, HEADING_RIGHT)
) {
return pointRotateRads( return pointRotateRads(
pointFrom( pointFrom(
element.x, element.x,
@ -1077,9 +1098,13 @@ export const avoidRectangularCorner = (
nonRotatedPoint[1] > element.y + element.height nonRotatedPoint[1] > element.y + element.height
) { ) {
// Bottom right // Bottom right
const heading = headingForPoint(
nonRotatedPoint,
pointFrom(element.x + element.width, element.y + element.height),
);
if ( if (
nonRotatedPoint[0] - element.x < compareHeading(heading, HEADING_DOWN) ||
element.width + FIXED_BINDING_DISTANCE compareHeading(heading, HEADING_LEFT)
) { ) {
return pointRotateRads( return pointRotateRads(
pointFrom( pointFrom(
@ -1103,9 +1128,13 @@ export const avoidRectangularCorner = (
nonRotatedPoint[1] < element.y nonRotatedPoint[1] < element.y
) { ) {
// Top right // Top right
const heading = headingForPoint(
nonRotatedPoint,
pointFrom(element.x + element.width, element.y),
);
if ( if (
nonRotatedPoint[0] - element.x < compareHeading(heading, HEADING_UP) ||
element.width + FIXED_BINDING_DISTANCE compareHeading(heading, HEADING_LEFT)
) { ) {
return pointRotateRads( return pointRotateRads(
pointFrom( pointFrom(