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(
|
||||
nextPoints,
|
||||
filteredNextFixedSegments,
|
||||
|
@ -912,7 +918,11 @@ export const updateElbowArrowPoints = (
|
|||
// 0. During all element replacement in the scene, we just need to renormalize
|
||||
// the arrow
|
||||
// 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(
|
||||
updates.points.map((p) =>
|
||||
pointFrom<GlobalPoint>(arrow.x + p[0], arrow.y + p[1]),
|
||||
|
@ -2123,3 +2133,16 @@ const getHoveredElements = (
|
|||
|
||||
const gridAddressesEqual = (a: GridAddress, b: GridAddress): boolean =>
|
||||
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 { LinearElementEditor } from "./linearElementEditor";
|
||||
import { newArrowElement, newElement } from "./newElement";
|
||||
import type {
|
||||
ElementsMap,
|
||||
ExcalidrawBindableElement,
|
||||
ExcalidrawElement,
|
||||
ExcalidrawFlowchartNodeElement,
|
||||
NonDeletedSceneElementsMap,
|
||||
OrderedExcalidrawElement,
|
||||
import type { SceneElementsMap } from "./types";
|
||||
import {
|
||||
type ElementsMap,
|
||||
type ExcalidrawBindableElement,
|
||||
type ExcalidrawElement,
|
||||
type ExcalidrawFlowchartNodeElement,
|
||||
type NonDeletedSceneElementsMap,
|
||||
type Ordered,
|
||||
type OrderedExcalidrawElement,
|
||||
} from "./types";
|
||||
import { KEYS } from "../keys";
|
||||
import type { AppState, PendingExcalidrawElements } from "../types";
|
||||
|
@ -28,9 +30,10 @@ import {
|
|||
isFrameElement,
|
||||
isFlowchartNodeElement,
|
||||
} from "./typeChecks";
|
||||
import { invariant } from "../utils";
|
||||
import { invariant, toBrandedType } from "../utils";
|
||||
import { pointFrom, type LocalPoint } from "../../math";
|
||||
import { aabbForElement } from "../shapes";
|
||||
import { updateElbowArrowPoints } from "./elbowArrow";
|
||||
|
||||
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 {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue