mirror of
https://github.com/excalidraw/excalidraw.git
synced 2025-04-14 16:40:58 -04:00
Merge eaa869620e
into dff69e9191
This commit is contained in:
commit
4847c639ba
7 changed files with 81 additions and 31 deletions
|
@ -18,7 +18,7 @@ import {
|
|||
} from "@excalidraw/math";
|
||||
import { isCurve } from "@excalidraw/math/curve";
|
||||
|
||||
import type { DebugElement } from "@excalidraw/excalidraw/visualdebug";
|
||||
import type { DebugElement } from "@excalidraw/utils/visualdebug";
|
||||
|
||||
import type { Curve } from "@excalidraw/math";
|
||||
|
||||
|
|
|
@ -981,6 +981,7 @@ export const bindPointToSnapToElementOutline = (
|
|||
otherPoint,
|
||||
),
|
||||
),
|
||||
0.1,
|
||||
)[0];
|
||||
} else {
|
||||
intersection = intersectElementWithLineSegment(
|
||||
|
|
|
@ -53,7 +53,7 @@ import {
|
|||
type SceneElementsMap,
|
||||
} from "./types";
|
||||
|
||||
import { aabbForElement, pointInsideBounds } from "./shapes";
|
||||
import { aabbForElement, aabbForPoints, pointInsideBounds } from "./shapes";
|
||||
|
||||
import type { Bounds } from "./bounds";
|
||||
import type { Heading } from "./heading";
|
||||
|
@ -108,7 +108,30 @@ type ElbowArrowData = {
|
|||
};
|
||||
|
||||
const DEDUP_TRESHOLD = 1;
|
||||
export const BASE_PADDING = 40;
|
||||
|
||||
const calculatePadding = (
|
||||
aabb: Bounds,
|
||||
startHeading: Heading,
|
||||
endHeading: Heading,
|
||||
) => {
|
||||
const width = aabb[2] - aabb[0];
|
||||
const height = aabb[3] - aabb[1];
|
||||
const size = Math.max(width, height);
|
||||
// || compareHeading(startHeading, flipHeading(endHeading))
|
||||
return size > 55
|
||||
? 40
|
||||
: Math.min(
|
||||
Math.max(
|
||||
headingIsHorizontal(startHeading) ? width / 2 - 1 : height / 2 - 1,
|
||||
10,
|
||||
),
|
||||
Math.max(
|
||||
headingIsHorizontal(endHeading) ? width / 2 - 1 : height / 2 - 1,
|
||||
10,
|
||||
),
|
||||
40,
|
||||
);
|
||||
};
|
||||
|
||||
const handleSegmentRenormalization = (
|
||||
arrow: ExcalidrawElbowArrowElement,
|
||||
|
@ -464,6 +487,11 @@ const handleSegmentMove = (
|
|||
hoveredStartElement: ExcalidrawBindableElement | null,
|
||||
hoveredEndElement: ExcalidrawBindableElement | null,
|
||||
): ElementUpdate<ExcalidrawElbowArrowElement> => {
|
||||
const BASE_PADDING = calculatePadding(
|
||||
aabbForElement(arrow),
|
||||
startHeading,
|
||||
endHeading,
|
||||
);
|
||||
const activelyModifiedSegmentIdx = fixedSegments
|
||||
.map((segment, i) => {
|
||||
if (
|
||||
|
@ -708,6 +736,11 @@ const handleEndpointDrag = (
|
|||
hoveredStartElement: ExcalidrawBindableElement | null,
|
||||
hoveredEndElement: ExcalidrawBindableElement | null,
|
||||
) => {
|
||||
const BASE_PADDING = calculatePadding(
|
||||
aabbForPoints([startGlobalPoint, endGlobalPoint]),
|
||||
startHeading,
|
||||
endHeading,
|
||||
);
|
||||
let startIsSpecial = arrow.startIsSpecial ?? null;
|
||||
let endIsSpecial = arrow.endIsSpecial ?? null;
|
||||
const globalUpdatedPoints = updatedPoints.map((p, i) =>
|
||||
|
@ -742,6 +775,7 @@ const handleEndpointDrag = (
|
|||
|
||||
// Calculate the moving second point connection and add the start point
|
||||
{
|
||||
startIsSpecial = arrow.startIsSpecial && globalUpdatedPoints.length > 2;
|
||||
const secondPoint = globalUpdatedPoints[startIsSpecial ? 2 : 1];
|
||||
const thirdPoint = globalUpdatedPoints[startIsSpecial ? 3 : 2];
|
||||
const startIsHorizontal = headingIsHorizontal(startHeading);
|
||||
|
@ -802,6 +836,7 @@ const handleEndpointDrag = (
|
|||
|
||||
// Calculate the moving second to last point connection
|
||||
{
|
||||
endIsSpecial = arrow.endIsSpecial && globalUpdatedPoints.length > 2;
|
||||
const secondToLastPoint =
|
||||
globalUpdatedPoints[globalUpdatedPoints.length - (endIsSpecial ? 3 : 2)];
|
||||
const thirdToLastPoint =
|
||||
|
@ -1296,6 +1331,11 @@ const getElbowArrowData = (
|
|||
endGlobalPoint[0] + 2,
|
||||
endGlobalPoint[1] + 2,
|
||||
] as Bounds;
|
||||
const BASE_PADDING = calculatePadding(
|
||||
aabbForPoints([startGlobalPoint, endGlobalPoint]),
|
||||
startHeading,
|
||||
endHeading,
|
||||
);
|
||||
const startElementBounds = hoveredStartElement
|
||||
? aabbForElement(
|
||||
hoveredStartElement,
|
||||
|
|
|
@ -282,6 +282,15 @@ export const mapIntervalToBezierT = <P extends GlobalPoint | LocalPoint>(
|
|||
);
|
||||
};
|
||||
|
||||
export const aabbForPoints = <Point extends GlobalPoint | LocalPoint>(
|
||||
points: Point[],
|
||||
): Bounds => [
|
||||
Math.min(...points.map((point) => point[0])),
|
||||
Math.min(...points.map((point) => point[1])),
|
||||
Math.max(...points.map((point) => point[0])),
|
||||
Math.max(...points.map((point) => point[1])),
|
||||
];
|
||||
|
||||
/**
|
||||
* Get the axis-aligned bounding box for a given element
|
||||
*/
|
||||
|
|
|
@ -77,9 +77,9 @@ describe("elbow arrow segment move", () => {
|
|||
|
||||
expect(arrow.points).toCloselyEqualPoints([
|
||||
[0, 0],
|
||||
[110, 0],
|
||||
[110, 200],
|
||||
[190, 200],
|
||||
[109.92, 0],
|
||||
[109.92, 200],
|
||||
[189.85, 200],
|
||||
]);
|
||||
|
||||
mouse.reset();
|
||||
|
@ -88,9 +88,9 @@ describe("elbow arrow segment move", () => {
|
|||
|
||||
expect(arrow.points).toCloselyEqualPoints([
|
||||
[0, 0],
|
||||
[110, 0],
|
||||
[110, 200],
|
||||
[190, 200],
|
||||
[109.92, 0],
|
||||
[109.92, 200],
|
||||
[189.85, 200],
|
||||
]);
|
||||
});
|
||||
|
||||
|
@ -198,11 +198,11 @@ describe("elbow arrow routing", () => {
|
|||
points: [pointFrom<LocalPoint>(0, 0), pointFrom<LocalPoint>(90, 200)],
|
||||
});
|
||||
|
||||
expect(arrow.points).toEqual([
|
||||
expect(arrow.points).toCloselyEqualPoints([
|
||||
[0, 0],
|
||||
[45, 0],
|
||||
[45, 200],
|
||||
[90, 200],
|
||||
[44.92, 0],
|
||||
[44.92, 200],
|
||||
[89.85, 200],
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
@ -252,11 +252,11 @@ describe("elbow arrow ui", () => {
|
|||
|
||||
expect(arrow.type).toBe("arrow");
|
||||
expect(arrow.elbowed).toBe(true);
|
||||
expect(arrow.points).toEqual([
|
||||
expect(arrow.points).toCloselyEqualPoints([
|
||||
[0, 0],
|
||||
[45, 0],
|
||||
[45, 200],
|
||||
[90, 200],
|
||||
[44.92, 0],
|
||||
[44.92, 200],
|
||||
[89.85, 200],
|
||||
]);
|
||||
});
|
||||
|
||||
|
@ -296,9 +296,9 @@ describe("elbow arrow ui", () => {
|
|||
|
||||
expect(arrow.points.map((point) => point.map(Math.round))).toEqual([
|
||||
[0, 0],
|
||||
[35, 0],
|
||||
[35, 165],
|
||||
[103, 165],
|
||||
[34, 0],
|
||||
[34, 165],
|
||||
[104, 165],
|
||||
]);
|
||||
});
|
||||
|
||||
|
@ -350,11 +350,11 @@ describe("elbow arrow ui", () => {
|
|||
expect(duplicatedArrow.id).not.toBe(originalArrowId);
|
||||
expect(duplicatedArrow.type).toBe("arrow");
|
||||
expect(duplicatedArrow.elbowed).toBe(true);
|
||||
expect(duplicatedArrow.points).toEqual([
|
||||
expect(duplicatedArrow.points).toCloselyEqualPoints([
|
||||
[0, 0],
|
||||
[45, 0],
|
||||
[45, 200],
|
||||
[90, 200],
|
||||
[44.92, 0],
|
||||
[44.92, 200],
|
||||
[89.85, 200],
|
||||
]);
|
||||
expect(arrow.startBinding).not.toBe(null);
|
||||
expect(arrow.endBinding).not.toBe(null);
|
||||
|
@ -404,11 +404,11 @@ describe("elbow arrow ui", () => {
|
|||
expect(duplicatedArrow.id).not.toBe(originalArrowId);
|
||||
expect(duplicatedArrow.type).toBe("arrow");
|
||||
expect(duplicatedArrow.elbowed).toBe(true);
|
||||
expect(duplicatedArrow.points).toEqual([
|
||||
expect(duplicatedArrow.points).toCloselyEqualPoints([
|
||||
[0, 0],
|
||||
[0, 100],
|
||||
[90, 100],
|
||||
[90, 200],
|
||||
[89.85, 100],
|
||||
[89.85, 200],
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -510,12 +510,12 @@ describe("arrow element", () => {
|
|||
h.state,
|
||||
)[0] as ExcalidrawElbowArrowElement;
|
||||
|
||||
expect(arrow.startBinding?.fixedPoint?.[0]).toBeCloseTo(1);
|
||||
expect(arrow.startBinding?.fixedPoint?.[0]).toBeCloseTo(1.05);
|
||||
expect(arrow.startBinding?.fixedPoint?.[1]).toBeCloseTo(0.75);
|
||||
|
||||
UI.resize(rectangle, "se", [-200, -150]);
|
||||
|
||||
expect(arrow.startBinding?.fixedPoint?.[0]).toBeCloseTo(1);
|
||||
expect(arrow.startBinding?.fixedPoint?.[0]).toBeCloseTo(1.05);
|
||||
expect(arrow.startBinding?.fixedPoint?.[1]).toBeCloseTo(0.75);
|
||||
});
|
||||
|
||||
|
@ -538,11 +538,11 @@ describe("arrow element", () => {
|
|||
h.state,
|
||||
)[0] as ExcalidrawElbowArrowElement;
|
||||
|
||||
expect(arrow.startBinding?.fixedPoint?.[0]).toBeCloseTo(1);
|
||||
expect(arrow.startBinding?.fixedPoint?.[0]).toBeCloseTo(1.05);
|
||||
expect(arrow.startBinding?.fixedPoint?.[1]).toBeCloseTo(0.75);
|
||||
|
||||
UI.resize([rectangle, arrow], "nw", [300, 350]);
|
||||
expect(arrow.startBinding?.fixedPoint?.[0]).toBeCloseTo(0);
|
||||
expect(arrow.startBinding?.fixedPoint?.[0]).toBeCloseTo(-0.05);
|
||||
expect(arrow.startBinding?.fixedPoint?.[1]).toBeCloseTo(0.25);
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Add table
Reference in a new issue