Binding distance fix
Signed-off-by: Mark Tolmacs <mark@lazycat.hu>
This commit is contained in:
parent
2d72ef421d
commit
f5908dad18
|
@ -48,12 +48,20 @@ import { KEYS } from "../keys";
|
|||
import { getBoundTextElement, handleBindTextResize } from "./textElement";
|
||||
import { getElementShape } from "../shapes";
|
||||
import { headingForPointFromElement } from "./routing";
|
||||
import type { Heading } from "../math";
|
||||
import {
|
||||
aabbForElement,
|
||||
compareHeading,
|
||||
HEADING_DOWN,
|
||||
HEADING_LEFT,
|
||||
HEADING_RIGHT,
|
||||
HEADING_UP,
|
||||
pointInsideBounds,
|
||||
pointToVector,
|
||||
rotatePoint,
|
||||
scaleVector,
|
||||
translatePoint,
|
||||
vectorToHeading,
|
||||
} from "../math";
|
||||
|
||||
export type SuggestedBinding =
|
||||
|
@ -671,18 +679,53 @@ const getSimultaneouslyUpdatedElementIds = (
|
|||
|
||||
export const bindPointToSnapToElementOutline = (
|
||||
point: Point,
|
||||
otherPoint: Point,
|
||||
bindableElement: ExcalidrawBindableElement,
|
||||
elementsMap: ElementsMap,
|
||||
): Point => {
|
||||
const heading = headingForPointFromElement(
|
||||
const distance = distanceToBindableElement(
|
||||
bindableElement,
|
||||
aabbForElement(bindableElement),
|
||||
point,
|
||||
elementsMap,
|
||||
);
|
||||
const distance =
|
||||
distanceToBindableElement(bindableElement, point, elementsMap) -
|
||||
const bindDistance = maxBindingGap(
|
||||
bindableElement,
|
||||
bindableElement.width,
|
||||
bindableElement.height,
|
||||
);
|
||||
|
||||
if (distance > bindDistance) {
|
||||
return point;
|
||||
}
|
||||
|
||||
const aabb = aabbForElement(bindableElement);
|
||||
const pointHeading = headingForPointFromElement(bindableElement, aabb, point);
|
||||
const otherPointHeading = scaleVector(
|
||||
vectorToHeading(pointToVector(point, otherPoint)),
|
||||
-1,
|
||||
) as Heading;
|
||||
const isInner =
|
||||
otherPointHeading === HEADING_LEFT || otherPointHeading === HEADING_RIGHT
|
||||
? distance < bindableElement.width * -0.2
|
||||
: distance < bindableElement.height * -0.2;
|
||||
const heading = isInner ? otherPointHeading : pointHeading;
|
||||
const pointOnAABB: Point = compareHeading(heading, HEADING_UP)
|
||||
? [point[0], aabb[1]]
|
||||
: compareHeading(heading, HEADING_RIGHT)
|
||||
? [aabb[2], point[1]]
|
||||
: compareHeading(heading, HEADING_DOWN)
|
||||
? [point[0], aabb[3]]
|
||||
: [aabb[0], point[1]];
|
||||
const distanceFromAABB =
|
||||
distanceToBindableElement(bindableElement, pointOnAABB, elementsMap) -
|
||||
FIXED_BINDING_DISTANCE;
|
||||
return translatePoint(point, scaleVector(heading, -distance));
|
||||
|
||||
const result = translatePoint(
|
||||
pointOnAABB,
|
||||
scaleVector(heading, -distanceFromAABB),
|
||||
);
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
export const avoidRectangularCorner = (
|
||||
|
@ -880,6 +923,8 @@ const calculateFixedPointForElbowArrowBinding = (
|
|||
] as Bounds;
|
||||
const edgePointIndex =
|
||||
startOrEnd === "start" ? 0 : linearElement.points.length - 1;
|
||||
const otherPointIndex =
|
||||
startOrEnd === "end" ? 0 : linearElement.points.length - 1;
|
||||
const globalPoint = LinearElementEditor.getPointAtIndexGlobalCoordinates(
|
||||
linearElement,
|
||||
edgePointIndex,
|
||||
|
@ -893,9 +938,15 @@ const calculateFixedPointForElbowArrowBinding = (
|
|||
globalPoint,
|
||||
globalMidPoint,
|
||||
-hoveredElement.angle,
|
||||
) as Point;
|
||||
const otherPoint = LinearElementEditor.getPointAtIndexGlobalCoordinates(
|
||||
linearElement,
|
||||
otherPointIndex,
|
||||
elementsMap,
|
||||
);
|
||||
const snappedPoint = bindPointToSnapToElementOutline(
|
||||
[nonRotatedGlobalPoint[0], nonRotatedGlobalPoint[1]],
|
||||
nonRotatedGlobalPoint,
|
||||
otherPoint,
|
||||
hoveredElement,
|
||||
elementsMap,
|
||||
);
|
||||
|
|
|
@ -24,7 +24,6 @@ import { getSizeFromPoints } from "../points";
|
|||
import type Scene from "../scene/Scene";
|
||||
import type { Point } from "../types";
|
||||
import { toBrandedType, tupleToCoors } from "../utils";
|
||||
import { debugDrawBounds } from "../visualdebug";
|
||||
import {
|
||||
bindPointToSnapToElementOutline,
|
||||
distanceToBindableElement,
|
||||
|
@ -119,15 +118,19 @@ export const mutateElbowArrow = (
|
|||
|
||||
const startGlobalPoint = getGlobalPoint(
|
||||
origStartGlobalPoint,
|
||||
origEndGlobalPoint,
|
||||
elementsMap,
|
||||
startElement,
|
||||
hoveredStartElement,
|
||||
options?.isDragging,
|
||||
);
|
||||
const endGlobalPoint = getGlobalPoint(
|
||||
origEndGlobalPoint,
|
||||
origStartGlobalPoint,
|
||||
elementsMap,
|
||||
endElement,
|
||||
hoveredEndElement,
|
||||
options?.isDragging,
|
||||
);
|
||||
|
||||
const startHeading = getBindPointHeading(
|
||||
|
@ -244,11 +247,11 @@ export const mutateElbowArrow = (
|
|||
endHeading,
|
||||
commonBounds,
|
||||
);
|
||||
console.log(boundsOverlap);
|
||||
dynamicAABBs.forEach((bbox) => debugDrawBounds(bbox));
|
||||
[startElementBounds, endElementBounds]
|
||||
.filter((aabb) => aabb !== null)
|
||||
.forEach((bbox) => debugDrawBounds(bbox, "red"));
|
||||
|
||||
// dynamicAABBs.forEach((bbox) => debugDrawBounds(bbox));
|
||||
// [startElementBounds, endElementBounds]
|
||||
// .filter((aabb) => aabb !== null)
|
||||
// .forEach((bbox) => debugDrawBounds(bbox, "red"));
|
||||
// debugDrawBounds(commonBounds, "cyan");
|
||||
// grid.data.forEach((node) => node && debugDrawPoint(node.pos));
|
||||
|
||||
|
@ -1116,15 +1119,15 @@ export const getArrowLocalFixedPoints = (
|
|||
];
|
||||
};
|
||||
|
||||
const aabbsOverlapping = (a: Bounds, b: Bounds) =>
|
||||
pointInsideBounds([a[0], a[1]], b) ||
|
||||
pointInsideBounds([a[2], a[1]], b) ||
|
||||
pointInsideBounds([a[2], a[3]], b) ||
|
||||
pointInsideBounds([a[0], a[3]], b) ||
|
||||
pointInsideBounds([b[0], b[1]], a) ||
|
||||
pointInsideBounds([b[2], b[1]], a) ||
|
||||
pointInsideBounds([b[2], b[3]], a) ||
|
||||
pointInsideBounds([b[0], b[3]], a);
|
||||
// const aabbsOverlapping = (a: Bounds, b: Bounds) =>
|
||||
// pointInsideBounds([a[0], a[1]], b) ||
|
||||
// pointInsideBounds([a[2], a[1]], b) ||
|
||||
// pointInsideBounds([a[2], a[3]], b) ||
|
||||
// pointInsideBounds([a[0], a[3]], b) ||
|
||||
// pointInsideBounds([b[0], b[1]], a) ||
|
||||
// pointInsideBounds([b[2], b[1]], a) ||
|
||||
// pointInsideBounds([b[2], b[3]], a) ||
|
||||
// pointInsideBounds([b[0], b[3]], a);
|
||||
|
||||
const getAllElementsMap = (
|
||||
scene: Scene,
|
||||
|
@ -1149,6 +1152,7 @@ const getAllElements = (
|
|||
|
||||
const getGlobalPoint = (
|
||||
initialPoint: Point,
|
||||
otherPoint: Point,
|
||||
elementsMap: NonDeletedSceneElementsMap,
|
||||
boundElement?: ExcalidrawBindableElement | null,
|
||||
hoveredElement?: ExcalidrawBindableElement | null,
|
||||
|
@ -1159,6 +1163,7 @@ const getGlobalPoint = (
|
|||
hoveredElement &&
|
||||
bindPointToSnapToElementOutline(
|
||||
initialPoint,
|
||||
otherPoint,
|
||||
hoveredElement,
|
||||
elementsMap,
|
||||
);
|
||||
|
@ -1172,6 +1177,7 @@ const getGlobalPoint = (
|
|||
} else if (boundElement) {
|
||||
return bindPointToSnapToElementOutline(
|
||||
initialPoint,
|
||||
otherPoint,
|
||||
boundElement,
|
||||
elementsMap,
|
||||
);
|
||||
|
|
|
@ -563,6 +563,9 @@ export const vectorToHeading = (vec: Vector): Heading => {
|
|||
return HEADING_UP;
|
||||
};
|
||||
|
||||
export const compareHeading = (a: Heading, b: Heading) =>
|
||||
a[0] === b[0] && a[1] === b[1];
|
||||
|
||||
export const scalePointFromOrigin = (
|
||||
p: Point,
|
||||
mid: Point,
|
||||
|
|
Loading…
Reference in New Issue