Inside detection for outline binding

Signed-off-by: Mark Tolmacs <mark@lazycat.hu>
This commit is contained in:
Mark Tolmacs 2025-03-29 13:58:50 +01:00
parent 4ea534a732
commit d6d4d00f60
2 changed files with 32 additions and 30 deletions

View file

@ -275,7 +275,7 @@ const getBindingStrategyForDraggingArrowEndpoints = (
const endDragged = draggingPoints.findIndex((i) => i === endIdx) > -1; const endDragged = draggingPoints.findIndex((i) => i === endIdx) > -1;
const start = startDragged const start = startDragged
? isBindingEnabled ? isBindingEnabled
? getElligibleElementForBindingElement( ? getEligibleElementForBindingElement(
selectedElement, selectedElement,
"start", "start",
elementsMap, elementsMap,
@ -285,7 +285,7 @@ const getBindingStrategyForDraggingArrowEndpoints = (
: null // If binding is disabled and start is dragged, break all binds : null // If binding is disabled and start is dragged, break all binds
: !isElbowArrow(selectedElement) : !isElbowArrow(selectedElement)
? // We have to update the focus and gap of the binding, so let's rebind ? // We have to update the focus and gap of the binding, so let's rebind
getElligibleElementForBindingElement( getEligibleElementForBindingElement(
selectedElement, selectedElement,
"start", "start",
elementsMap, elementsMap,
@ -295,7 +295,7 @@ const getBindingStrategyForDraggingArrowEndpoints = (
: "keep"; : "keep";
const end = endDragged const end = endDragged
? isBindingEnabled ? isBindingEnabled
? getElligibleElementForBindingElement( ? getEligibleElementForBindingElement(
selectedElement, selectedElement,
"end", "end",
elementsMap, elementsMap,
@ -305,7 +305,7 @@ const getBindingStrategyForDraggingArrowEndpoints = (
: null // If binding is disabled and end is dragged, break all binds : null // If binding is disabled and end is dragged, break all binds
: !isElbowArrow(selectedElement) : !isElbowArrow(selectedElement)
? // We have to update the focus and gap of the binding, so let's rebind ? // We have to update the focus and gap of the binding, so let's rebind
getElligibleElementForBindingElement( getEligibleElementForBindingElement(
selectedElement, selectedElement,
"end", "end",
elementsMap, elementsMap,
@ -336,7 +336,7 @@ const getBindingStrategyForDraggingArrowOrJoints = (
); );
const start = startIsClose const start = startIsClose
? isBindingEnabled ? isBindingEnabled
? getElligibleElementForBindingElement( ? getEligibleElementForBindingElement(
selectedElement, selectedElement,
"start", "start",
elementsMap, elementsMap,
@ -347,7 +347,7 @@ const getBindingStrategyForDraggingArrowOrJoints = (
: null; : null;
const end = endIsClose const end = endIsClose
? isBindingEnabled ? isBindingEnabled
? getElligibleElementForBindingElement( ? getEligibleElementForBindingElement(
selectedElement, selectedElement,
"end", "end",
elementsMap, elementsMap,
@ -903,6 +903,13 @@ export const bindPointToSnapToElementOutline = (
); );
const edgePoint = avoidRectangularCorner(bindableElement, p); const edgePoint = avoidRectangularCorner(bindableElement, p);
const otherPointIdx =
startOrEnd === "start" ? linearElement.points.length - 1 : 0;
const otherPoint = pointFrom<GlobalPoint>(
linearElement.x + linearElement.points[otherPointIdx][0],
linearElement.y + linearElement.points[otherPointIdx][1],
);
const adjacentPointIdx = const adjacentPointIdx =
startOrEnd === "start" ? 1 : linearElement.points.length - 2; startOrEnd === "start" ? 1 : linearElement.points.length - 2;
const adjacentPoint = const adjacentPoint =
@ -968,6 +975,14 @@ export const bindPointToSnapToElementOutline = (
return edgePoint; return edgePoint;
} }
const shape = getElementShape(bindableElement, elementsMap);
const pointInShape = isPointInShape(edgePoint, shape);
const otherPointInShape = isPointInShape(otherPoint, shape);
if (pointInShape && otherPointInShape) {
return edgePoint;
}
if (elbowed) { if (elbowed) {
const scalar = const scalar =
pointDistanceSq(edgePoint, center) - pointDistanceSq(edgePoint, center) -
@ -1379,7 +1394,7 @@ export const calculateFixedPointForElbowArrowBinding = (
}; };
}; };
const getElligibleElementForBindingElement = ( const getEligibleElementForBindingElement = (
linearElement: NonDeleted<ExcalidrawLinearElement>, linearElement: NonDeleted<ExcalidrawLinearElement>,
startOrEnd: "start" | "end", startOrEnd: "start" | "end",
elementsMap: NonDeletedSceneElementsMap, elementsMap: NonDeletedSceneElementsMap,

View file

@ -63,7 +63,6 @@ import type {
ExcalidrawBindableElement, ExcalidrawBindableElement,
FixedPointBinding, FixedPointBinding,
FixedSegment, FixedSegment,
NonDeletedExcalidrawElement,
} from "./types"; } from "./types";
type GridAddress = [number, number] & { _brand: "gridaddress" }; type GridAddress = [number, number] & { _brand: "gridaddress" };
@ -1221,18 +1220,22 @@ const getElbowArrowData = (
if (options?.isDragging) { if (options?.isDragging) {
const elements = Array.from(elementsMap.values()); const elements = Array.from(elementsMap.values());
hoveredStartElement = hoveredStartElement =
getHoveredElement( getHoveredElementForBinding(
origStartGlobalPoint, tupleToCoors(origStartGlobalPoint),
elementsMap,
elements, elements,
elementsMap,
options?.zoom, options?.zoom,
true,
true,
) || null; ) || null;
hoveredEndElement = hoveredEndElement =
getHoveredElement( getHoveredElementForBinding(
origEndGlobalPoint, tupleToCoors(origEndGlobalPoint),
elementsMap,
elements, elements,
elementsMap,
options?.zoom, options?.zoom,
true,
true,
) || null; ) || null;
} else { } else {
hoveredStartElement = arrow.startBinding hoveredStartElement = arrow.startBinding
@ -2275,22 +2278,6 @@ const getBindPointHeading = (
origPoint, origPoint,
); );
const getHoveredElement = (
origPoint: GlobalPoint,
elementsMap: NonDeletedSceneElementsMap,
elements: readonly NonDeletedExcalidrawElement[],
zoom?: AppState["zoom"],
) => {
return getHoveredElementForBinding(
tupleToCoors(origPoint),
elements,
elementsMap,
zoom,
true,
true,
);
};
const gridAddressesEqual = (a: GridAddress, b: GridAddress): boolean => const gridAddressesEqual = (a: GridAddress, b: GridAddress): boolean =>
a[0] === b[0] && a[1] === b[1]; a[0] === b[0] && a[1] === b[1];