|
@@ -15,7 +15,7 @@ import {
|
|
|
import BinaryHeap from "../binaryheap";
|
|
|
import { getSizeFromPoints } from "../points";
|
|
|
import { aabbForElement, pointInsideBounds } from "../shapes";
|
|
|
-import { invariant, isAnyTrue, toBrandedType, tupleToCoors } from "../utils";
|
|
|
+import { invariant, isAnyTrue, tupleToCoors } from "../utils";
|
|
|
import type { AppState } from "../types";
|
|
|
import {
|
|
|
bindPointToSnapToElementOutline,
|
|
@@ -52,6 +52,7 @@ import type {
|
|
|
ExcalidrawBindableElement,
|
|
|
FixedPointBinding,
|
|
|
FixedSegment,
|
|
|
+ NonDeletedExcalidrawElement,
|
|
|
} from "./types";
|
|
|
import { distanceToBindableElement } from "./distance";
|
|
|
|
|
@@ -101,7 +102,7 @@ export const BASE_PADDING = 40;
|
|
|
|
|
|
const handleSegmentRenormalization = (
|
|
|
arrow: ExcalidrawElbowArrowElement,
|
|
|
- elementsMap: NonDeletedSceneElementsMap | SceneElementsMap,
|
|
|
+ elementsMap: NonDeletedSceneElementsMap,
|
|
|
) => {
|
|
|
const nextFixedSegments: FixedSegment[] | null = arrow.fixedSegments
|
|
|
? arrow.fixedSegments.slice()
|
|
@@ -234,6 +235,16 @@ const handleSegmentRenormalization = (
|
|
|
nextPoints.map((p) =>
|
|
|
pointFrom<LocalPoint>(p[0] - arrow.x, p[1] - arrow.y),
|
|
|
),
|
|
|
+ arrow.startBinding &&
|
|
|
+ getBindableElementForId(
|
|
|
+ arrow.startBinding.elementId,
|
|
|
+ elementsMap,
|
|
|
+ ),
|
|
|
+ arrow.endBinding &&
|
|
|
+ getBindableElementForId(
|
|
|
+ arrow.endBinding.elementId,
|
|
|
+ elementsMap,
|
|
|
+ ),
|
|
|
),
|
|
|
) ?? [],
|
|
|
),
|
|
@@ -271,7 +282,7 @@ const handleSegmentRenormalization = (
|
|
|
const handleSegmentRelease = (
|
|
|
arrow: ExcalidrawElbowArrowElement,
|
|
|
fixedSegments: readonly FixedSegment[],
|
|
|
- elementsMap: NonDeletedSceneElementsMap | SceneElementsMap,
|
|
|
+ elementsMap: NonDeletedSceneElementsMap,
|
|
|
) => {
|
|
|
const newFixedSegmentIndices = fixedSegments.map((segment) => segment.index);
|
|
|
const oldFixedSegmentIndices =
|
|
@@ -295,6 +306,8 @@ const handleSegmentRelease = (
|
|
|
// We need to render a sub-arrow path to restore deleted segments
|
|
|
const x = arrow.x + (prevSegment ? prevSegment.end[0] : 0);
|
|
|
const y = arrow.y + (prevSegment ? prevSegment.end[1] : 0);
|
|
|
+ const startBinding = prevSegment ? null : arrow.startBinding;
|
|
|
+ const endBinding = nextSegment ? null : arrow.endBinding;
|
|
|
const {
|
|
|
startHeading,
|
|
|
endHeading,
|
|
@@ -307,10 +320,11 @@ const handleSegmentRelease = (
|
|
|
{
|
|
|
x,
|
|
|
y,
|
|
|
- startBinding: prevSegment ? null : arrow.startBinding,
|
|
|
- endBinding: nextSegment ? null : arrow.endBinding,
|
|
|
+ startBinding,
|
|
|
+ endBinding,
|
|
|
startArrowhead: null,
|
|
|
endArrowhead: null,
|
|
|
+ points: arrow.points,
|
|
|
},
|
|
|
elementsMap,
|
|
|
[
|
|
@@ -324,6 +338,9 @@ const handleSegmentRelease = (
|
|
|
y,
|
|
|
),
|
|
|
],
|
|
|
+ startBinding &&
|
|
|
+ getBindableElementForId(startBinding.elementId, elementsMap),
|
|
|
+ endBinding && getBindableElementForId(endBinding.elementId, elementsMap),
|
|
|
{ isDragging: false },
|
|
|
);
|
|
|
|
|
@@ -870,7 +887,7 @@ const MAX_POS = 1e6;
|
|
|
*/
|
|
|
export const updateElbowArrowPoints = (
|
|
|
arrow: Readonly<ExcalidrawElbowArrowElement>,
|
|
|
- elementsMap: NonDeletedSceneElementsMap | SceneElementsMap,
|
|
|
+ elementsMap: NonDeletedSceneElementsMap,
|
|
|
updates: {
|
|
|
points?: readonly LocalPoint[];
|
|
|
fixedSegments?: FixedSegment[] | null;
|
|
@@ -986,8 +1003,11 @@ export const updateElbowArrowPoints = (
|
|
|
typeof updates.endBinding !== "undefined"
|
|
|
? updates.endBinding
|
|
|
: arrow.endBinding;
|
|
|
- const startElement = startBinding && elementsMap.get(startBinding.elementId);
|
|
|
- const endElement = endBinding && elementsMap.get(endBinding.elementId);
|
|
|
+ const startElement =
|
|
|
+ startBinding &&
|
|
|
+ getBindableElementForId(startBinding.elementId, elementsMap);
|
|
|
+ const endElement =
|
|
|
+ endBinding && getBindableElementForId(endBinding.elementId, elementsMap);
|
|
|
if (
|
|
|
(elementsMap.size === 0 && validateElbowPoints(updatedPoints)) ||
|
|
|
startElement?.id !== startBinding?.elementId ||
|
|
@@ -1019,9 +1039,12 @@ export const updateElbowArrowPoints = (
|
|
|
endBinding,
|
|
|
startArrowhead: arrow.startArrowhead,
|
|
|
endArrowhead: arrow.endArrowhead,
|
|
|
+ points: arrow.points,
|
|
|
},
|
|
|
elementsMap,
|
|
|
updatedPoints,
|
|
|
+ startElement,
|
|
|
+ endElement,
|
|
|
options,
|
|
|
);
|
|
|
|
|
@@ -1155,9 +1178,12 @@ const getElbowArrowData = (
|
|
|
endBinding: FixedPointBinding | null;
|
|
|
startArrowhead: Arrowhead | null;
|
|
|
endArrowhead: Arrowhead | null;
|
|
|
+ points: readonly LocalPoint[];
|
|
|
},
|
|
|
- elementsMap: NonDeletedSceneElementsMap | SceneElementsMap,
|
|
|
+ elementsMap: NonDeletedSceneElementsMap,
|
|
|
nextPoints: readonly LocalPoint[],
|
|
|
+ startElement: ExcalidrawBindableElement | null,
|
|
|
+ endElement: ExcalidrawBindableElement | null,
|
|
|
options?: {
|
|
|
isDragging?: boolean;
|
|
|
zoom?: AppState["zoom"];
|
|
@@ -1171,20 +1197,27 @@ const getElbowArrowData = (
|
|
|
LocalPoint,
|
|
|
GlobalPoint
|
|
|
>(nextPoints[nextPoints.length - 1], vector(arrow.x, arrow.y));
|
|
|
- const startElement =
|
|
|
- arrow.startBinding &&
|
|
|
- getBindableElementForId(arrow.startBinding.elementId, elementsMap);
|
|
|
- const endElement =
|
|
|
- arrow.endBinding &&
|
|
|
- getBindableElementForId(arrow.endBinding.elementId, elementsMap);
|
|
|
- const [hoveredStartElement, hoveredEndElement] = options?.isDragging
|
|
|
- ? getHoveredElements(
|
|
|
+
|
|
|
+ let hoveredStartElement = startElement;
|
|
|
+ let hoveredEndElement = endElement;
|
|
|
+ if (options?.isDragging) {
|
|
|
+ const elements = Array.from(elementsMap.values());
|
|
|
+ hoveredStartElement =
|
|
|
+ getHoveredElement(
|
|
|
origStartGlobalPoint,
|
|
|
+ elementsMap,
|
|
|
+ elements,
|
|
|
+ options?.zoom,
|
|
|
+ ) || startElement;
|
|
|
+ hoveredEndElement =
|
|
|
+ getHoveredElement(
|
|
|
origEndGlobalPoint,
|
|
|
elementsMap,
|
|
|
+ elements,
|
|
|
options?.zoom,
|
|
|
- )
|
|
|
- : [startElement, endElement];
|
|
|
+ ) || endElement;
|
|
|
+ }
|
|
|
+
|
|
|
const startGlobalPoint = getGlobalPoint(
|
|
|
{
|
|
|
...arrow,
|
|
@@ -2214,36 +2247,20 @@ const getBindPointHeading = (
|
|
|
origPoint,
|
|
|
);
|
|
|
|
|
|
-const getHoveredElements = (
|
|
|
- origStartGlobalPoint: GlobalPoint,
|
|
|
- origEndGlobalPoint: GlobalPoint,
|
|
|
- elementsMap: NonDeletedSceneElementsMap | SceneElementsMap,
|
|
|
+const getHoveredElement = (
|
|
|
+ origPoint: GlobalPoint,
|
|
|
+ elementsMap: NonDeletedSceneElementsMap,
|
|
|
+ elements: readonly NonDeletedExcalidrawElement[],
|
|
|
zoom?: AppState["zoom"],
|
|
|
) => {
|
|
|
- // TODO: Might be a performance bottleneck and the Map type
|
|
|
- // remembers the insertion order anyway...
|
|
|
- const nonDeletedSceneElementsMap = toBrandedType<NonDeletedSceneElementsMap>(
|
|
|
- new Map([...elementsMap].filter((el) => !el[1].isDeleted)),
|
|
|
+ return getHoveredElementForBinding(
|
|
|
+ tupleToCoors(origPoint),
|
|
|
+ elements,
|
|
|
+ elementsMap,
|
|
|
+ zoom,
|
|
|
+ true,
|
|
|
+ true,
|
|
|
);
|
|
|
- const elements = Array.from(elementsMap.values());
|
|
|
- return [
|
|
|
- getHoveredElementForBinding(
|
|
|
- tupleToCoors(origStartGlobalPoint),
|
|
|
- elements,
|
|
|
- nonDeletedSceneElementsMap,
|
|
|
- zoom,
|
|
|
- true,
|
|
|
- true,
|
|
|
- ),
|
|
|
- getHoveredElementForBinding(
|
|
|
- tupleToCoors(origEndGlobalPoint),
|
|
|
- elements,
|
|
|
- nonDeletedSceneElementsMap,
|
|
|
- zoom,
|
|
|
- true,
|
|
|
- true,
|
|
|
- ),
|
|
|
- ];
|
|
|
};
|
|
|
|
|
|
const gridAddressesEqual = (a: GridAddress, b: GridAddress): boolean =>
|