mirror of
https://github.com/excalidraw/excalidraw.git
synced 2025-05-03 10:00:07 -04:00
fix: Elbow arrow orthogonality (#9073)
This commit is contained in:
parent
6cdb683410
commit
9b6edc767a
2 changed files with 52 additions and 10 deletions
|
@ -244,6 +244,12 @@ const handleSegmentRenormalization = (
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
import.meta.env.DEV &&
|
||||||
|
invariant(
|
||||||
|
validateElbowPoints(nextPoints),
|
||||||
|
"Invalid elbow points with fixed segments",
|
||||||
|
);
|
||||||
|
|
||||||
return normalizeArrowElementUpdate(
|
return normalizeArrowElementUpdate(
|
||||||
nextPoints,
|
nextPoints,
|
||||||
filteredNextFixedSegments,
|
filteredNextFixedSegments,
|
||||||
|
@ -912,7 +918,11 @@ export const updateElbowArrowPoints = (
|
||||||
// 0. During all element replacement in the scene, we just need to renormalize
|
// 0. During all element replacement in the scene, we just need to renormalize
|
||||||
// the arrow
|
// the arrow
|
||||||
// TODO (dwelle,mtolmacs): Remove this once Scene.getScene() is removed
|
// TODO (dwelle,mtolmacs): Remove this once Scene.getScene() is removed
|
||||||
if (elementsMap.size === 0 && updates.points) {
|
if (
|
||||||
|
elementsMap.size === 0 &&
|
||||||
|
updates.points &&
|
||||||
|
validateElbowPoints(updates.points)
|
||||||
|
) {
|
||||||
return normalizeArrowElementUpdate(
|
return normalizeArrowElementUpdate(
|
||||||
updates.points.map((p) =>
|
updates.points.map((p) =>
|
||||||
pointFrom<GlobalPoint>(arrow.x + p[0], arrow.y + p[1]),
|
pointFrom<GlobalPoint>(arrow.x + p[0], arrow.y + p[1]),
|
||||||
|
@ -2123,3 +2133,16 @@ const getHoveredElements = (
|
||||||
|
|
||||||
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];
|
||||||
|
|
||||||
|
const validateElbowPoints = <P extends GlobalPoint | LocalPoint>(
|
||||||
|
points: readonly P[],
|
||||||
|
tolerance: number = DEDUP_TRESHOLD,
|
||||||
|
) =>
|
||||||
|
points
|
||||||
|
.slice(1)
|
||||||
|
.map(
|
||||||
|
(p, i) =>
|
||||||
|
Math.abs(p[0] - points[i][0]) < tolerance ||
|
||||||
|
Math.abs(p[1] - points[i][1]) < tolerance,
|
||||||
|
)
|
||||||
|
.every(Boolean);
|
||||||
|
|
|
@ -10,13 +10,15 @@ import {
|
||||||
import { bindLinearElement } from "./binding";
|
import { bindLinearElement } from "./binding";
|
||||||
import { LinearElementEditor } from "./linearElementEditor";
|
import { LinearElementEditor } from "./linearElementEditor";
|
||||||
import { newArrowElement, newElement } from "./newElement";
|
import { newArrowElement, newElement } from "./newElement";
|
||||||
import type {
|
import type { SceneElementsMap } from "./types";
|
||||||
ElementsMap,
|
import {
|
||||||
ExcalidrawBindableElement,
|
type ElementsMap,
|
||||||
ExcalidrawElement,
|
type ExcalidrawBindableElement,
|
||||||
ExcalidrawFlowchartNodeElement,
|
type ExcalidrawElement,
|
||||||
NonDeletedSceneElementsMap,
|
type ExcalidrawFlowchartNodeElement,
|
||||||
OrderedExcalidrawElement,
|
type NonDeletedSceneElementsMap,
|
||||||
|
type Ordered,
|
||||||
|
type OrderedExcalidrawElement,
|
||||||
} from "./types";
|
} from "./types";
|
||||||
import { KEYS } from "../keys";
|
import { KEYS } from "../keys";
|
||||||
import type { AppState, PendingExcalidrawElements } from "../types";
|
import type { AppState, PendingExcalidrawElements } from "../types";
|
||||||
|
@ -28,9 +30,10 @@ import {
|
||||||
isFrameElement,
|
isFrameElement,
|
||||||
isFlowchartNodeElement,
|
isFlowchartNodeElement,
|
||||||
} from "./typeChecks";
|
} from "./typeChecks";
|
||||||
import { invariant } from "../utils";
|
import { invariant, toBrandedType } from "../utils";
|
||||||
import { pointFrom, type LocalPoint } from "../../math";
|
import { pointFrom, type LocalPoint } from "../../math";
|
||||||
import { aabbForElement } from "../shapes";
|
import { aabbForElement } from "../shapes";
|
||||||
|
import { updateElbowArrowPoints } from "./elbowArrow";
|
||||||
|
|
||||||
type LinkDirection = "up" | "right" | "down" | "left";
|
type LinkDirection = "up" | "right" | "down" | "left";
|
||||||
|
|
||||||
|
@ -467,7 +470,23 @@ const createBindingArrow = (
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return bindingArrow;
|
const update = updateElbowArrowPoints(
|
||||||
|
bindingArrow,
|
||||||
|
toBrandedType<SceneElementsMap>(
|
||||||
|
new Map([
|
||||||
|
...elementsMap.entries(),
|
||||||
|
[startBindingElement.id, startBindingElement],
|
||||||
|
[endBindingElement.id, endBindingElement],
|
||||||
|
[bindingArrow.id, bindingArrow],
|
||||||
|
] as [string, Ordered<ExcalidrawElement>][]),
|
||||||
|
),
|
||||||
|
{ points: bindingArrow.points },
|
||||||
|
);
|
||||||
|
|
||||||
|
return {
|
||||||
|
...bindingArrow,
|
||||||
|
...update,
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export class FlowChartNavigator {
|
export class FlowChartNavigator {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue