fix: Centralized midpoint snap code
Signed-off-by: Mark Tolmacs <mark@lazycat.hu>
This commit is contained in:
@@ -269,6 +269,7 @@ export const handleFocusPointDrag = (
|
||||
newMode || "orbit",
|
||||
linearElementEditor.draggedFocusPointBinding,
|
||||
scene,
|
||||
appState.zoom,
|
||||
point,
|
||||
);
|
||||
}
|
||||
|
||||
+18
-116
@@ -60,6 +60,7 @@ import { updateElbowArrowPoints } from "./elbowArrow";
|
||||
import {
|
||||
deconstructDiamondElement,
|
||||
deconstructRectanguloidElement,
|
||||
getSnapOutlineMidPoint,
|
||||
projectFixedPointOntoDiagonal,
|
||||
} from "./utils";
|
||||
|
||||
@@ -175,6 +176,7 @@ export const bindOrUnbindBindingElement = (
|
||||
start,
|
||||
"start",
|
||||
scene,
|
||||
appState.zoom,
|
||||
appState.isBindingEnabled,
|
||||
);
|
||||
bindOrUnbindBindingElementEdge(
|
||||
@@ -182,6 +184,7 @@ export const bindOrUnbindBindingElement = (
|
||||
end,
|
||||
"end",
|
||||
scene,
|
||||
appState.zoom,
|
||||
appState.isBindingEnabled,
|
||||
);
|
||||
if (start.focusPoint || end.focusPoint) {
|
||||
@@ -226,6 +229,7 @@ const bindOrUnbindBindingElementEdge = (
|
||||
{ mode, element, focusPoint }: BindingStrategy,
|
||||
startOrEnd: "start" | "end",
|
||||
scene: Scene,
|
||||
zoom: AppState["zoom"],
|
||||
shouldSnapToOutline = true,
|
||||
): void => {
|
||||
if (mode === null) {
|
||||
@@ -238,6 +242,7 @@ const bindOrUnbindBindingElementEdge = (
|
||||
mode,
|
||||
startOrEnd,
|
||||
scene,
|
||||
zoom,
|
||||
focusPoint,
|
||||
shouldSnapToOutline,
|
||||
);
|
||||
@@ -1026,6 +1031,7 @@ export const bindBindingElement = (
|
||||
mode: BindMode,
|
||||
startOrEnd: "start" | "end",
|
||||
scene: Scene,
|
||||
zoom: AppState["zoom"],
|
||||
focusPoint?: GlobalPoint,
|
||||
shouldSnapToOutline = true,
|
||||
): void => {
|
||||
@@ -1042,6 +1048,7 @@ export const bindBindingElement = (
|
||||
hoveredElement,
|
||||
startOrEnd,
|
||||
elementsMap,
|
||||
zoom,
|
||||
shouldSnapToOutline,
|
||||
),
|
||||
};
|
||||
@@ -1266,6 +1273,7 @@ const updateArrowBindings = (
|
||||
strategy[strategyName].mode,
|
||||
strategyName,
|
||||
scene,
|
||||
appState.zoom,
|
||||
strategy[strategyName].focusPoint,
|
||||
);
|
||||
}
|
||||
@@ -1375,6 +1383,7 @@ export const bindPointToSnapToElementOutline = (
|
||||
bindableElement: ExcalidrawBindableElement,
|
||||
startOrEnd: "start" | "end",
|
||||
elementsMap: ElementsMap,
|
||||
zoom: AppState["zoom"],
|
||||
customIntersector?: LineSegment<GlobalPoint>,
|
||||
isMidpointSnappingEnabled = true,
|
||||
): GlobalPoint => {
|
||||
@@ -1417,7 +1426,13 @@ export const bindPointToSnapToElementOutline = (
|
||||
headingForPointFromElement(bindableElement, aabb, point),
|
||||
);
|
||||
const snapPoint = isMidpointSnappingEnabled
|
||||
? snapToMid(bindableElement, elementsMap, edgePoint, 0.05, arrowElement)
|
||||
? getSnapOutlineMidPoint(
|
||||
edgePoint,
|
||||
bindableElement,
|
||||
elementsMap,
|
||||
zoom,
|
||||
arrowElement,
|
||||
)
|
||||
: undefined;
|
||||
const resolved = snapPoint || point;
|
||||
const otherPoint = pointFrom<GlobalPoint>(
|
||||
@@ -1599,121 +1614,6 @@ export const avoidRectangularCorner = (
|
||||
return p;
|
||||
};
|
||||
|
||||
export const snapToMid = (
|
||||
bindTarget: ExcalidrawBindableElement,
|
||||
elementsMap: ElementsMap,
|
||||
p: GlobalPoint,
|
||||
tolerance: number = 0.05,
|
||||
arrowElement?: ExcalidrawArrowElement,
|
||||
): GlobalPoint | undefined => {
|
||||
const { x, y, width, height, angle } = bindTarget;
|
||||
const center = elementCenterPoint(bindTarget, elementsMap, -0.1, -0.1);
|
||||
const nonRotated = pointRotateRads(p, center, -angle as Radians);
|
||||
|
||||
const bindingGap = arrowElement ? getBindingGap(bindTarget, arrowElement) : 0;
|
||||
|
||||
// snap-to-center point is adaptive to element size, but we don't want to go
|
||||
// above and below certain px distance
|
||||
const verticalThreshold = clamp(tolerance * height, 5, 80);
|
||||
const horizontalThreshold = clamp(tolerance * width, 5, 80);
|
||||
|
||||
// Too close to the center makes it hard to resolve direction precisely
|
||||
if (pointDistance(center, nonRotated) < bindingGap) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (
|
||||
nonRotated[0] <= x + width / 2 &&
|
||||
nonRotated[1] > center[1] - verticalThreshold &&
|
||||
nonRotated[1] < center[1] + verticalThreshold
|
||||
) {
|
||||
// LEFT
|
||||
return pointRotateRads(
|
||||
pointFrom<GlobalPoint>(x - bindingGap, center[1]),
|
||||
center,
|
||||
angle,
|
||||
);
|
||||
} else if (
|
||||
nonRotated[1] <= y + height / 2 &&
|
||||
nonRotated[0] > center[0] - horizontalThreshold &&
|
||||
nonRotated[0] < center[0] + horizontalThreshold
|
||||
) {
|
||||
// TOP
|
||||
return pointRotateRads(
|
||||
pointFrom<GlobalPoint>(center[0], y - bindingGap),
|
||||
center,
|
||||
angle,
|
||||
);
|
||||
} else if (
|
||||
nonRotated[0] >= x + width / 2 &&
|
||||
nonRotated[1] > center[1] - verticalThreshold &&
|
||||
nonRotated[1] < center[1] + verticalThreshold
|
||||
) {
|
||||
// RIGHT
|
||||
return pointRotateRads(
|
||||
pointFrom<GlobalPoint>(x + width + bindingGap, center[1]),
|
||||
center,
|
||||
angle,
|
||||
);
|
||||
} else if (
|
||||
nonRotated[1] >= y + height / 2 &&
|
||||
nonRotated[0] > center[0] - horizontalThreshold &&
|
||||
nonRotated[0] < center[0] + horizontalThreshold
|
||||
) {
|
||||
// DOWN
|
||||
return pointRotateRads(
|
||||
pointFrom<GlobalPoint>(center[0], y + height + bindingGap),
|
||||
center,
|
||||
angle,
|
||||
);
|
||||
} else if (bindTarget.type === "diamond") {
|
||||
const distance = bindingGap;
|
||||
const topLeft = pointFrom<GlobalPoint>(
|
||||
x + width / 4 - distance,
|
||||
y + height / 4 - distance,
|
||||
);
|
||||
const topRight = pointFrom<GlobalPoint>(
|
||||
x + (3 * width) / 4 + distance,
|
||||
y + height / 4 - distance,
|
||||
);
|
||||
const bottomLeft = pointFrom<GlobalPoint>(
|
||||
x + width / 4 - distance,
|
||||
y + (3 * height) / 4 + distance,
|
||||
);
|
||||
const bottomRight = pointFrom<GlobalPoint>(
|
||||
x + (3 * width) / 4 + distance,
|
||||
y + (3 * height) / 4 + distance,
|
||||
);
|
||||
|
||||
if (
|
||||
pointDistance(topLeft, nonRotated) <
|
||||
Math.max(horizontalThreshold, verticalThreshold)
|
||||
) {
|
||||
return pointRotateRads(topLeft, center, angle);
|
||||
}
|
||||
if (
|
||||
pointDistance(topRight, nonRotated) <
|
||||
Math.max(horizontalThreshold, verticalThreshold)
|
||||
) {
|
||||
return pointRotateRads(topRight, center, angle);
|
||||
}
|
||||
if (
|
||||
pointDistance(bottomLeft, nonRotated) <
|
||||
Math.max(horizontalThreshold, verticalThreshold)
|
||||
) {
|
||||
return pointRotateRads(bottomLeft, center, angle);
|
||||
}
|
||||
if (
|
||||
pointDistance(bottomRight, nonRotated) <
|
||||
Math.max(horizontalThreshold, verticalThreshold)
|
||||
) {
|
||||
return pointRotateRads(bottomRight, center, angle);
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
};
|
||||
|
||||
const extractBinding = (
|
||||
arrow: ExcalidrawArrowElement,
|
||||
startOrEnd: "startBinding" | "endBinding",
|
||||
@@ -1913,6 +1813,7 @@ export const calculateFixedPointForElbowArrowBinding = (
|
||||
hoveredElement: ExcalidrawBindableElement,
|
||||
startOrEnd: "start" | "end",
|
||||
elementsMap: ElementsMap,
|
||||
zoom: AppState["zoom"],
|
||||
shouldSnapToOutline = true,
|
||||
isMidpointSnappingEnabled = true,
|
||||
): { fixedPoint: FixedPoint } => {
|
||||
@@ -1928,6 +1829,7 @@ export const calculateFixedPointForElbowArrowBinding = (
|
||||
hoveredElement,
|
||||
startOrEnd,
|
||||
elementsMap,
|
||||
zoom,
|
||||
undefined,
|
||||
isMidpointSnappingEnabled,
|
||||
)
|
||||
|
||||
@@ -1251,6 +1251,7 @@ const getElbowArrowData = (
|
||||
"start",
|
||||
arrow.startBinding?.fixedPoint,
|
||||
origStartGlobalPoint,
|
||||
options?.zoom || ({ value: 1 } as AppState["zoom"]),
|
||||
hoveredStartElement,
|
||||
elementsMap,
|
||||
options?.isDragging,
|
||||
@@ -1268,6 +1269,7 @@ const getElbowArrowData = (
|
||||
"end",
|
||||
arrow.endBinding?.fixedPoint,
|
||||
origEndGlobalPoint,
|
||||
options?.zoom || ({ value: 1 } as AppState["zoom"]),
|
||||
hoveredEndElement,
|
||||
elementsMap,
|
||||
options?.isDragging,
|
||||
@@ -2213,6 +2215,7 @@ const getGlobalPoint = (
|
||||
startOrEnd: "start" | "end",
|
||||
fixedPointRatio: [number, number] | undefined | null,
|
||||
initialPoint: GlobalPoint,
|
||||
zoom: AppState["zoom"],
|
||||
element?: ExcalidrawBindableElement | null,
|
||||
elementsMap?: ElementsMap,
|
||||
isDragging?: boolean,
|
||||
@@ -2226,6 +2229,7 @@ const getGlobalPoint = (
|
||||
element,
|
||||
startOrEnd,
|
||||
elementsMap,
|
||||
zoom,
|
||||
undefined,
|
||||
isMidpointSnappingEnabled,
|
||||
);
|
||||
|
||||
@@ -452,8 +452,16 @@ const createBindingArrow = (
|
||||
"orbit",
|
||||
"start",
|
||||
scene,
|
||||
appState.zoom,
|
||||
);
|
||||
bindBindingElement(
|
||||
bindingArrow,
|
||||
endBindingElement,
|
||||
"orbit",
|
||||
"end",
|
||||
scene,
|
||||
appState.zoom,
|
||||
);
|
||||
bindBindingElement(bindingArrow, endBindingElement, "orbit", "end", scene);
|
||||
|
||||
const changedElements = new Map<string, OrderedExcalidrawElement>();
|
||||
changedElements.set(
|
||||
|
||||
@@ -48,7 +48,6 @@ import {
|
||||
calculateFixedPointForNonElbowArrowBinding,
|
||||
getBindingStrategyForDraggingBindingElementEndpoints,
|
||||
isBindingEnabled,
|
||||
snapToMid,
|
||||
updateBoundPoint,
|
||||
} from "./binding";
|
||||
import {
|
||||
@@ -2200,13 +2199,15 @@ const pointDraggingUpdates = (
|
||||
? {
|
||||
element: suggestedBindingElement,
|
||||
midPoint: app.state.isMidpointSnappingEnabled
|
||||
? snapToMid(
|
||||
suggestedBindingElement,
|
||||
elementsMap,
|
||||
? getSnapOutlineMidPoint(
|
||||
pointFrom<GlobalPoint>(
|
||||
scenePointerX - linearElementEditor.pointerOffset.x,
|
||||
scenePointerY - linearElementEditor.pointerOffset.y,
|
||||
),
|
||||
suggestedBindingElement,
|
||||
elementsMap,
|
||||
app.state.zoom,
|
||||
element,
|
||||
)
|
||||
: undefined,
|
||||
}
|
||||
@@ -2313,6 +2314,7 @@ const pointDraggingUpdates = (
|
||||
start.element,
|
||||
elementsMap,
|
||||
app.state.zoom,
|
||||
element,
|
||||
),
|
||||
}
|
||||
: null;
|
||||
@@ -2352,6 +2354,7 @@ const pointDraggingUpdates = (
|
||||
end.element,
|
||||
elementsMap,
|
||||
app.state.zoom,
|
||||
element,
|
||||
),
|
||||
}
|
||||
: null;
|
||||
|
||||
@@ -17,6 +17,7 @@ import {
|
||||
} from "@excalidraw/common";
|
||||
|
||||
import type { MarkOptional } from "@excalidraw/common/utility-types";
|
||||
import type { Zoom } from "@excalidraw/excalidraw/types";
|
||||
|
||||
import { bindBindingElement } from "./binding";
|
||||
import {
|
||||
@@ -248,6 +249,7 @@ const bindLinearElementToElement = (
|
||||
end: ValidLinearElement["end"],
|
||||
elementStore: ElementStore,
|
||||
scene: Scene,
|
||||
zoom: Zoom,
|
||||
): {
|
||||
linearElement: ExcalidrawLinearElement;
|
||||
startBoundElement?: ExcalidrawElement;
|
||||
@@ -335,6 +337,7 @@ const bindLinearElementToElement = (
|
||||
"orbit",
|
||||
"start",
|
||||
scene,
|
||||
zoom,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -411,6 +414,7 @@ const bindLinearElementToElement = (
|
||||
"orbit",
|
||||
"end",
|
||||
scene,
|
||||
zoom,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -696,6 +700,7 @@ export const convertToExcalidrawElements = (
|
||||
originalEnd,
|
||||
elementStore,
|
||||
scene,
|
||||
{ value: 1 } as Zoom,
|
||||
);
|
||||
container = linearElement;
|
||||
elementStore.add(linearElement);
|
||||
@@ -721,6 +726,7 @@ export const convertToExcalidrawElements = (
|
||||
end,
|
||||
elementStore,
|
||||
scene,
|
||||
{ value: 1 } as Zoom,
|
||||
);
|
||||
|
||||
elementStore.add(linearElement);
|
||||
|
||||
+146
-21
@@ -8,6 +8,7 @@ import {
|
||||
|
||||
import {
|
||||
bezierEquation,
|
||||
clamp,
|
||||
curve,
|
||||
curveCatmullRomCubicApproxPoints,
|
||||
curveOffsetPoints,
|
||||
@@ -26,7 +27,7 @@ import {
|
||||
type GlobalPoint,
|
||||
} from "@excalidraw/math";
|
||||
|
||||
import type { Curve, LineSegment, LocalPoint } from "@excalidraw/math";
|
||||
import type { Curve, LineSegment, LocalPoint, Radians } from "@excalidraw/math";
|
||||
|
||||
import type {
|
||||
AppState,
|
||||
@@ -41,7 +42,7 @@ import { generateLinearCollisionShape } from "./shape";
|
||||
import { hitElementItself, isPointInElement } from "./collision";
|
||||
import { LinearElementEditor } from "./linearElementEditor";
|
||||
import { isRectangularElement } from "./typeChecks";
|
||||
import { maxBindingDistance_simple } from "./binding";
|
||||
import { getBindingGap, maxBindingDistance_simple } from "./binding";
|
||||
|
||||
import {
|
||||
getGlobalFixedPointForBindableElement,
|
||||
@@ -592,16 +593,135 @@ export const getSnapOutlineMidPoint = (
|
||||
element: ExcalidrawBindableElement,
|
||||
elementsMap: ElementsMap,
|
||||
zoom: AppState["zoom"],
|
||||
) => {
|
||||
arrow: { elbowed: boolean },
|
||||
): GlobalPoint | undefined => {
|
||||
const center = elementCenterPoint(element, elementsMap);
|
||||
const TOLERANCE = 0.05;
|
||||
const maxDistance = maxBindingDistance_simple(zoom) + element.strokeWidth / 2;
|
||||
const { x, y, width, height, angle } = element;
|
||||
|
||||
// snap-to-center point is adaptive to element size, but we don't want to go
|
||||
// above and below certain px distance
|
||||
const verticalThreshold = clamp(TOLERANCE * height, 5, maxDistance);
|
||||
const horizontalThreshold = clamp(TOLERANCE * width, 5, maxDistance);
|
||||
|
||||
if (arrow.elbowed) {
|
||||
const nonRotated = pointRotateRads(point, center, -angle as Radians);
|
||||
|
||||
const bindingGap = getBindingGap(element, arrow);
|
||||
|
||||
// Too close to the center makes it hard to resolve direction precisely
|
||||
if (pointDistance(center, nonRotated) < bindingGap) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (
|
||||
nonRotated[0] <= x + width / 2 &&
|
||||
nonRotated[1] > center[1] - verticalThreshold &&
|
||||
nonRotated[1] < center[1] + verticalThreshold
|
||||
) {
|
||||
// LEFT
|
||||
return pointRotateRads(
|
||||
pointFrom<GlobalPoint>(x - bindingGap, center[1]),
|
||||
center,
|
||||
angle,
|
||||
);
|
||||
} else if (
|
||||
nonRotated[1] <= y + height / 2 &&
|
||||
nonRotated[0] > center[0] - horizontalThreshold &&
|
||||
nonRotated[0] < center[0] + horizontalThreshold
|
||||
) {
|
||||
// TOP
|
||||
return pointRotateRads(
|
||||
pointFrom<GlobalPoint>(center[0], y - bindingGap),
|
||||
center,
|
||||
angle,
|
||||
);
|
||||
} else if (
|
||||
nonRotated[0] >= x + width / 2 &&
|
||||
nonRotated[1] > center[1] - verticalThreshold &&
|
||||
nonRotated[1] < center[1] + verticalThreshold
|
||||
) {
|
||||
// RIGHT
|
||||
return pointRotateRads(
|
||||
pointFrom<GlobalPoint>(x + width + bindingGap, center[1]),
|
||||
center,
|
||||
angle,
|
||||
);
|
||||
} else if (
|
||||
nonRotated[1] >= y + height / 2 &&
|
||||
nonRotated[0] > center[0] - horizontalThreshold &&
|
||||
nonRotated[0] < center[0] + horizontalThreshold
|
||||
) {
|
||||
// DOWN
|
||||
return pointRotateRads(
|
||||
pointFrom<GlobalPoint>(center[0], y + height + bindingGap),
|
||||
center,
|
||||
angle,
|
||||
);
|
||||
} else if (element.type === "diamond") {
|
||||
const distance = bindingGap;
|
||||
const topLeft = pointFrom<GlobalPoint>(
|
||||
x + width / 4 - distance,
|
||||
y + height / 4 - distance,
|
||||
);
|
||||
const topRight = pointFrom<GlobalPoint>(
|
||||
x + (3 * width) / 4 + distance,
|
||||
y + height / 4 - distance,
|
||||
);
|
||||
const bottomLeft = pointFrom<GlobalPoint>(
|
||||
x + width / 4 - distance,
|
||||
y + (3 * height) / 4 + distance,
|
||||
);
|
||||
const bottomRight = pointFrom<GlobalPoint>(
|
||||
x + (3 * width) / 4 + distance,
|
||||
y + (3 * height) / 4 + distance,
|
||||
);
|
||||
|
||||
if (
|
||||
pointDistance(topLeft, nonRotated) <
|
||||
Math.max(horizontalThreshold, verticalThreshold)
|
||||
) {
|
||||
return pointRotateRads(topLeft, center, angle);
|
||||
}
|
||||
if (
|
||||
pointDistance(topRight, nonRotated) <
|
||||
Math.max(horizontalThreshold, verticalThreshold)
|
||||
) {
|
||||
return pointRotateRads(topRight, center, angle);
|
||||
}
|
||||
if (
|
||||
pointDistance(bottomLeft, nonRotated) <
|
||||
Math.max(horizontalThreshold, verticalThreshold)
|
||||
) {
|
||||
return pointRotateRads(bottomLeft, center, angle);
|
||||
}
|
||||
if (
|
||||
pointDistance(bottomRight, nonRotated) <
|
||||
Math.max(horizontalThreshold, verticalThreshold)
|
||||
) {
|
||||
return pointRotateRads(bottomRight, center, angle);
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const sideMidpoints =
|
||||
element.type === "diamond"
|
||||
? getDiamondBaseCorners(element).map((curve) => {
|
||||
const point = bezierEquation(curve, 0.5);
|
||||
const rotatedPoint = pointRotateRads(point, center, element.angle);
|
||||
? getDiamondBaseCorners(element)
|
||||
.map((curve) => {
|
||||
const point = bezierEquation(curve, 0.5);
|
||||
const rotatedPoint = pointRotateRads(point, center, element.angle);
|
||||
|
||||
return pointFrom<GlobalPoint>(rotatedPoint[0], rotatedPoint[1]);
|
||||
})
|
||||
return pointFrom<GlobalPoint>(rotatedPoint[0], rotatedPoint[1]);
|
||||
})
|
||||
.map((midpoint) => {
|
||||
return pointFrom<GlobalPoint>(
|
||||
midpoint[0] + (midpoint[0] - center[0]) * 0.1,
|
||||
midpoint[1] + (midpoint[1] - center[1]) * 0.1,
|
||||
);
|
||||
})
|
||||
: [
|
||||
// RIGHT midpoint
|
||||
pointRotateRads(
|
||||
@@ -634,20 +754,24 @@ export const getSnapOutlineMidPoint = (
|
||||
element.angle,
|
||||
),
|
||||
];
|
||||
const candidate = sideMidpoints.find(
|
||||
(midpoint) =>
|
||||
pointDistance(point, midpoint) <=
|
||||
maxBindingDistance_simple(zoom) + element.strokeWidth / 2 &&
|
||||
!hitElementItself({
|
||||
point,
|
||||
element,
|
||||
threshold: 0,
|
||||
elementsMap,
|
||||
overrideShouldTestInside: true,
|
||||
}),
|
||||
);
|
||||
|
||||
return candidate;
|
||||
return sideMidpoints
|
||||
.map((midpoint, i) => {
|
||||
const threshold = i % 2 === 0 ? horizontalThreshold : verticalThreshold;
|
||||
|
||||
return pointDistance(midpoint, point) <= threshold ? midpoint : undefined;
|
||||
})
|
||||
.find(
|
||||
(midpoint) =>
|
||||
midpoint &&
|
||||
!hitElementItself({
|
||||
point,
|
||||
element,
|
||||
threshold: 0,
|
||||
elementsMap,
|
||||
overrideShouldTestInside: true,
|
||||
}),
|
||||
);
|
||||
};
|
||||
|
||||
export const projectFixedPointOntoDiagonal = (
|
||||
@@ -670,6 +794,7 @@ export const projectFixedPointOntoDiagonal = (
|
||||
element,
|
||||
elementsMap,
|
||||
zoom,
|
||||
arrow,
|
||||
);
|
||||
if (sideMidPoint) {
|
||||
return sideMidPoint;
|
||||
|
||||
@@ -16,6 +16,7 @@ import "@excalidraw/utils/test-utils";
|
||||
import { bindBindingElement } from "@excalidraw/element";
|
||||
|
||||
import type { LocalPoint } from "@excalidraw/math";
|
||||
import type { Zoom } from "@excalidraw/excalidraw/types";
|
||||
|
||||
import { Scene } from "../src/Scene";
|
||||
|
||||
@@ -187,8 +188,12 @@ describe("elbow arrow routing", () => {
|
||||
}) as ExcalidrawElbowArrowElement;
|
||||
API.setElements([rectangle1, rectangle2, arrow]);
|
||||
|
||||
bindBindingElement(arrow, rectangle1, "orbit", "start", h.scene);
|
||||
bindBindingElement(arrow, rectangle2, "orbit", "end", h.scene);
|
||||
bindBindingElement(arrow, rectangle1, "orbit", "start", h.scene, {
|
||||
value: 1,
|
||||
} as Zoom);
|
||||
bindBindingElement(arrow, rectangle2, "orbit", "end", h.scene, {
|
||||
value: 1,
|
||||
} as Zoom);
|
||||
|
||||
expect(arrow.startBinding).not.toBe(null);
|
||||
expect(arrow.endBinding).not.toBe(null);
|
||||
|
||||
@@ -1897,6 +1897,7 @@ export const actionChangeArrowType = register<keyof typeof ARROW_TYPE>({
|
||||
startElement,
|
||||
"start",
|
||||
elementsMap,
|
||||
appState.zoom,
|
||||
appState.isBindingEnabled,
|
||||
),
|
||||
}
|
||||
@@ -1911,6 +1912,7 @@ export const actionChangeArrowType = register<keyof typeof ARROW_TYPE>({
|
||||
endElement,
|
||||
"end",
|
||||
elementsMap,
|
||||
appState.zoom,
|
||||
appState.isBindingEnabled,
|
||||
),
|
||||
}
|
||||
@@ -1943,6 +1945,7 @@ export const actionChangeArrowType = register<keyof typeof ARROW_TYPE>({
|
||||
appState.bindMode === "inside" ? "inside" : "orbit",
|
||||
"start",
|
||||
app.scene,
|
||||
appState.zoom,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1957,6 +1960,7 @@ export const actionChangeArrowType = register<keyof typeof ARROW_TYPE>({
|
||||
appState.bindMode === "inside" ? "inside" : "orbit",
|
||||
"end",
|
||||
app.scene,
|
||||
appState.zoom,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7102,6 +7102,9 @@ class App extends React.Component<AppProps, AppState> {
|
||||
hoveredElement,
|
||||
elementsMap,
|
||||
this.state.zoom,
|
||||
{
|
||||
elbowed: this.state.currentItemArrowType === ARROW_TYPE.elbow,
|
||||
},
|
||||
),
|
||||
},
|
||||
});
|
||||
@@ -7296,6 +7299,7 @@ class App extends React.Component<AppProps, AppState> {
|
||||
hit,
|
||||
elementsMap,
|
||||
this.state.zoom,
|
||||
{ elbowed: this.state.currentItemArrowType === ARROW_TYPE.elbow },
|
||||
),
|
||||
},
|
||||
});
|
||||
@@ -9490,6 +9494,7 @@ class App extends React.Component<AppProps, AppState> {
|
||||
boundElement,
|
||||
elementsMap,
|
||||
this.state.zoom,
|
||||
element,
|
||||
),
|
||||
}
|
||||
: null,
|
||||
|
||||
@@ -17,7 +17,7 @@ import { EditorLocalStorage } from "../../data/EditorLocalStorage";
|
||||
|
||||
import type { MermaidToExcalidrawLibProps } from "./types";
|
||||
|
||||
import type { AppClassProperties, BinaryFiles } from "../../types";
|
||||
import type { AppClassProperties, BinaryFiles, Zoom } from "../../types";
|
||||
|
||||
export const resetPreview = ({
|
||||
canvasRef,
|
||||
|
||||
@@ -2374,7 +2374,7 @@ exports[`history > multiplayer undo/redo > conflicts in arrows and their bindabl
|
||||
"endBinding": {
|
||||
"elementId": "id1",
|
||||
"fixedPoint": [
|
||||
0,
|
||||
"0.50010",
|
||||
"0.50010",
|
||||
],
|
||||
"mode": "orbit",
|
||||
@@ -2382,7 +2382,7 @@ exports[`history > multiplayer undo/redo > conflicts in arrows and their bindabl
|
||||
"fillStyle": "solid",
|
||||
"frameId": null,
|
||||
"groupIds": [],
|
||||
"height": "439.20000",
|
||||
"height": "399.26547",
|
||||
"id": "id4",
|
||||
"index": "a2",
|
||||
"isDeleted": false,
|
||||
@@ -2396,8 +2396,8 @@ exports[`history > multiplayer undo/redo > conflicts in arrows and their bindabl
|
||||
0,
|
||||
],
|
||||
[
|
||||
488,
|
||||
"-439.20000",
|
||||
"488.00000",
|
||||
"-399.26547",
|
||||
],
|
||||
],
|
||||
"roughness": 1,
|
||||
@@ -2419,9 +2419,9 @@ exports[`history > multiplayer undo/redo > conflicts in arrows and their bindabl
|
||||
"type": "arrow",
|
||||
"updated": 1,
|
||||
"version": 11,
|
||||
"width": 488,
|
||||
"width": "488.00000",
|
||||
"x": 6,
|
||||
"y": "-5.39000",
|
||||
"y": "-4.89900",
|
||||
}
|
||||
`;
|
||||
|
||||
@@ -2542,7 +2542,7 @@ exports[`history > multiplayer undo/redo > conflicts in arrows and their bindabl
|
||||
"endBinding": {
|
||||
"elementId": "id1",
|
||||
"fixedPoint": [
|
||||
0,
|
||||
"0.50010",
|
||||
"0.50010",
|
||||
],
|
||||
"mode": "orbit",
|
||||
@@ -2550,7 +2550,7 @@ exports[`history > multiplayer undo/redo > conflicts in arrows and their bindabl
|
||||
"fillStyle": "solid",
|
||||
"frameId": null,
|
||||
"groupIds": [],
|
||||
"height": "439.20000",
|
||||
"height": "399.26547",
|
||||
"index": "a2",
|
||||
"isDeleted": false,
|
||||
"link": null,
|
||||
@@ -2562,8 +2562,8 @@ exports[`history > multiplayer undo/redo > conflicts in arrows and their bindabl
|
||||
0,
|
||||
],
|
||||
[
|
||||
488,
|
||||
"-439.20000",
|
||||
"488.00000",
|
||||
"-399.26547",
|
||||
],
|
||||
],
|
||||
"roughness": 1,
|
||||
@@ -2584,9 +2584,9 @@ exports[`history > multiplayer undo/redo > conflicts in arrows and their bindabl
|
||||
"strokeWidth": 2,
|
||||
"type": "arrow",
|
||||
"version": 11,
|
||||
"width": 488,
|
||||
"width": "488.00000",
|
||||
"x": 6,
|
||||
"y": "-5.39000",
|
||||
"y": "-4.89900",
|
||||
},
|
||||
"inserted": {
|
||||
"isDeleted": true,
|
||||
@@ -16703,7 +16703,7 @@ exports[`history > singleplayer undo/redo > should support bidirectional binding
|
||||
"fillStyle": "solid",
|
||||
"frameId": null,
|
||||
"groupIds": [],
|
||||
"height": 0,
|
||||
"height": "0.00661",
|
||||
"id": "id13",
|
||||
"index": "a3",
|
||||
"isDeleted": false,
|
||||
@@ -16718,7 +16718,7 @@ exports[`history > singleplayer undo/redo > should support bidirectional binding
|
||||
],
|
||||
[
|
||||
"88.00000",
|
||||
0,
|
||||
"-0.00661",
|
||||
],
|
||||
],
|
||||
"roughness": 1,
|
||||
@@ -16729,8 +16729,8 @@ exports[`history > singleplayer undo/redo > should support bidirectional binding
|
||||
"startBinding": {
|
||||
"elementId": "id0",
|
||||
"fixedPoint": [
|
||||
1,
|
||||
"0.50010",
|
||||
"0.50021",
|
||||
"0.50021",
|
||||
],
|
||||
"mode": "orbit",
|
||||
},
|
||||
@@ -16742,7 +16742,7 @@ exports[`history > singleplayer undo/redo > should support bidirectional binding
|
||||
"version": 10,
|
||||
"width": "88.00000",
|
||||
"x": 6,
|
||||
"y": "0.01000",
|
||||
"y": "0.01706",
|
||||
}
|
||||
`;
|
||||
|
||||
@@ -16787,8 +16787,8 @@ exports[`history > singleplayer undo/redo > should support bidirectional binding
|
||||
"startBinding": {
|
||||
"elementId": "id0",
|
||||
"fixedPoint": [
|
||||
1,
|
||||
"0.50010",
|
||||
"0.50021",
|
||||
"0.50021",
|
||||
],
|
||||
"mode": "orbit",
|
||||
},
|
||||
@@ -16807,8 +16807,8 @@ exports[`history > singleplayer undo/redo > should support bidirectional binding
|
||||
"startBinding": {
|
||||
"elementId": "id0",
|
||||
"fixedPoint": [
|
||||
1,
|
||||
"0.50010",
|
||||
"0.50021",
|
||||
"0.50021",
|
||||
],
|
||||
"mode": "orbit",
|
||||
},
|
||||
@@ -17121,7 +17121,7 @@ exports[`history > singleplayer undo/redo > should support bidirectional binding
|
||||
"fillStyle": "solid",
|
||||
"frameId": null,
|
||||
"groupIds": [],
|
||||
"height": 0,
|
||||
"height": "0.00661",
|
||||
"index": "a3",
|
||||
"isDeleted": false,
|
||||
"link": null,
|
||||
@@ -17134,7 +17134,7 @@ exports[`history > singleplayer undo/redo > should support bidirectional binding
|
||||
],
|
||||
[
|
||||
"88.00000",
|
||||
0,
|
||||
"-0.00661",
|
||||
],
|
||||
],
|
||||
"roughness": 1,
|
||||
@@ -17145,8 +17145,8 @@ exports[`history > singleplayer undo/redo > should support bidirectional binding
|
||||
"startBinding": {
|
||||
"elementId": "id0",
|
||||
"fixedPoint": [
|
||||
1,
|
||||
"0.50010",
|
||||
"0.50021",
|
||||
"0.50021",
|
||||
],
|
||||
"mode": "orbit",
|
||||
},
|
||||
@@ -17157,7 +17157,7 @@ exports[`history > singleplayer undo/redo > should support bidirectional binding
|
||||
"version": 7,
|
||||
"width": "88.00000",
|
||||
"x": 6,
|
||||
"y": "0.01000",
|
||||
"y": "0.01706",
|
||||
},
|
||||
"inserted": {
|
||||
"isDeleted": true,
|
||||
@@ -17451,7 +17451,7 @@ exports[`history > singleplayer undo/redo > should support bidirectional binding
|
||||
"fillStyle": "solid",
|
||||
"frameId": null,
|
||||
"groupIds": [],
|
||||
"height": 0,
|
||||
"height": "0.00661",
|
||||
"id": "id13",
|
||||
"index": "a3",
|
||||
"isDeleted": false,
|
||||
@@ -17466,7 +17466,7 @@ exports[`history > singleplayer undo/redo > should support bidirectional binding
|
||||
],
|
||||
[
|
||||
"88.00000",
|
||||
0,
|
||||
"-0.00661",
|
||||
],
|
||||
],
|
||||
"roughness": 1,
|
||||
@@ -17477,8 +17477,8 @@ exports[`history > singleplayer undo/redo > should support bidirectional binding
|
||||
"startBinding": {
|
||||
"elementId": "id0",
|
||||
"fixedPoint": [
|
||||
1,
|
||||
"0.50010",
|
||||
"0.50021",
|
||||
"0.50021",
|
||||
],
|
||||
"mode": "orbit",
|
||||
},
|
||||
@@ -17490,7 +17490,7 @@ exports[`history > singleplayer undo/redo > should support bidirectional binding
|
||||
"version": 10,
|
||||
"width": "88.00000",
|
||||
"x": 6,
|
||||
"y": "0.01000",
|
||||
"y": "0.01706",
|
||||
}
|
||||
`;
|
||||
|
||||
@@ -17759,7 +17759,7 @@ exports[`history > singleplayer undo/redo > should support bidirectional binding
|
||||
"fillStyle": "solid",
|
||||
"frameId": null,
|
||||
"groupIds": [],
|
||||
"height": 0,
|
||||
"height": "0.00661",
|
||||
"index": "a3",
|
||||
"isDeleted": false,
|
||||
"link": null,
|
||||
@@ -17772,7 +17772,7 @@ exports[`history > singleplayer undo/redo > should support bidirectional binding
|
||||
],
|
||||
[
|
||||
"88.00000",
|
||||
0,
|
||||
"-0.00661",
|
||||
],
|
||||
],
|
||||
"roughness": 1,
|
||||
@@ -17783,8 +17783,8 @@ exports[`history > singleplayer undo/redo > should support bidirectional binding
|
||||
"startBinding": {
|
||||
"elementId": "id0",
|
||||
"fixedPoint": [
|
||||
1,
|
||||
"0.50010",
|
||||
"0.50021",
|
||||
"0.50021",
|
||||
],
|
||||
"mode": "orbit",
|
||||
},
|
||||
@@ -17795,7 +17795,7 @@ exports[`history > singleplayer undo/redo > should support bidirectional binding
|
||||
"version": 10,
|
||||
"width": "88.00000",
|
||||
"x": 6,
|
||||
"y": "0.01000",
|
||||
"y": "0.01706",
|
||||
},
|
||||
"inserted": {
|
||||
"isDeleted": true,
|
||||
@@ -18097,7 +18097,7 @@ exports[`history > singleplayer undo/redo > should support bidirectional binding
|
||||
"fillStyle": "solid",
|
||||
"frameId": null,
|
||||
"groupIds": [],
|
||||
"height": 0,
|
||||
"height": "0.00661",
|
||||
"id": "id13",
|
||||
"index": "a3",
|
||||
"isDeleted": false,
|
||||
@@ -18112,7 +18112,7 @@ exports[`history > singleplayer undo/redo > should support bidirectional binding
|
||||
],
|
||||
[
|
||||
"88.00000",
|
||||
0,
|
||||
"-0.00661",
|
||||
],
|
||||
],
|
||||
"roughness": 1,
|
||||
@@ -18123,8 +18123,8 @@ exports[`history > singleplayer undo/redo > should support bidirectional binding
|
||||
"startBinding": {
|
||||
"elementId": "id0",
|
||||
"fixedPoint": [
|
||||
1,
|
||||
"0.50010",
|
||||
"0.50021",
|
||||
"0.50021",
|
||||
],
|
||||
"mode": "orbit",
|
||||
},
|
||||
@@ -18136,7 +18136,7 @@ exports[`history > singleplayer undo/redo > should support bidirectional binding
|
||||
"version": 10,
|
||||
"width": "88.00000",
|
||||
"x": 6,
|
||||
"y": "0.01000",
|
||||
"y": "0.01706",
|
||||
}
|
||||
`;
|
||||
|
||||
@@ -18405,7 +18405,7 @@ exports[`history > singleplayer undo/redo > should support bidirectional binding
|
||||
"fillStyle": "solid",
|
||||
"frameId": null,
|
||||
"groupIds": [],
|
||||
"height": 0,
|
||||
"height": "0.00661",
|
||||
"index": "a3",
|
||||
"isDeleted": false,
|
||||
"link": null,
|
||||
@@ -18418,7 +18418,7 @@ exports[`history > singleplayer undo/redo > should support bidirectional binding
|
||||
],
|
||||
[
|
||||
"88.00000",
|
||||
0,
|
||||
"-0.00661",
|
||||
],
|
||||
],
|
||||
"roughness": 1,
|
||||
@@ -18429,8 +18429,8 @@ exports[`history > singleplayer undo/redo > should support bidirectional binding
|
||||
"startBinding": {
|
||||
"elementId": "id0",
|
||||
"fixedPoint": [
|
||||
1,
|
||||
"0.50010",
|
||||
"0.50021",
|
||||
"0.50021",
|
||||
],
|
||||
"mode": "orbit",
|
||||
},
|
||||
@@ -18441,7 +18441,7 @@ exports[`history > singleplayer undo/redo > should support bidirectional binding
|
||||
"version": 10,
|
||||
"width": "88.00000",
|
||||
"x": 6,
|
||||
"y": "0.01000",
|
||||
"y": "0.01706",
|
||||
},
|
||||
"inserted": {
|
||||
"isDeleted": true,
|
||||
@@ -18741,7 +18741,7 @@ exports[`history > singleplayer undo/redo > should support bidirectional binding
|
||||
"fillStyle": "solid",
|
||||
"frameId": null,
|
||||
"groupIds": [],
|
||||
"height": 0,
|
||||
"height": "0.00661",
|
||||
"id": "id13",
|
||||
"index": "a3",
|
||||
"isDeleted": false,
|
||||
@@ -18756,7 +18756,7 @@ exports[`history > singleplayer undo/redo > should support bidirectional binding
|
||||
],
|
||||
[
|
||||
"88.00000",
|
||||
0,
|
||||
"-0.00661",
|
||||
],
|
||||
],
|
||||
"roughness": 1,
|
||||
@@ -18767,8 +18767,8 @@ exports[`history > singleplayer undo/redo > should support bidirectional binding
|
||||
"startBinding": {
|
||||
"elementId": "id0",
|
||||
"fixedPoint": [
|
||||
1,
|
||||
"0.50010",
|
||||
"0.50021",
|
||||
"0.50021",
|
||||
],
|
||||
"mode": "orbit",
|
||||
},
|
||||
@@ -18780,7 +18780,7 @@ exports[`history > singleplayer undo/redo > should support bidirectional binding
|
||||
"version": 10,
|
||||
"width": "88.00000",
|
||||
"x": 6,
|
||||
"y": "0.01000",
|
||||
"y": "0.01706",
|
||||
}
|
||||
`;
|
||||
|
||||
@@ -18841,8 +18841,8 @@ exports[`history > singleplayer undo/redo > should support bidirectional binding
|
||||
"startBinding": {
|
||||
"elementId": "id0",
|
||||
"fixedPoint": [
|
||||
1,
|
||||
"0.50010",
|
||||
"0.50021",
|
||||
"0.50021",
|
||||
],
|
||||
"mode": "orbit",
|
||||
},
|
||||
@@ -19135,7 +19135,7 @@ exports[`history > singleplayer undo/redo > should support bidirectional binding
|
||||
"fillStyle": "solid",
|
||||
"frameId": null,
|
||||
"groupIds": [],
|
||||
"height": 0,
|
||||
"height": "0.00661",
|
||||
"index": "a3",
|
||||
"isDeleted": false,
|
||||
"link": null,
|
||||
@@ -19148,7 +19148,7 @@ exports[`history > singleplayer undo/redo > should support bidirectional binding
|
||||
],
|
||||
[
|
||||
"88.00000",
|
||||
0,
|
||||
"-0.00661",
|
||||
],
|
||||
],
|
||||
"roughness": 1,
|
||||
@@ -19159,8 +19159,8 @@ exports[`history > singleplayer undo/redo > should support bidirectional binding
|
||||
"startBinding": {
|
||||
"elementId": "id0",
|
||||
"fixedPoint": [
|
||||
1,
|
||||
"0.50010",
|
||||
"0.50021",
|
||||
"0.50021",
|
||||
],
|
||||
"mode": "orbit",
|
||||
},
|
||||
@@ -19171,7 +19171,7 @@ exports[`history > singleplayer undo/redo > should support bidirectional binding
|
||||
"version": 7,
|
||||
"width": "88.00000",
|
||||
"x": 6,
|
||||
"y": "0.01000",
|
||||
"y": "0.01706",
|
||||
},
|
||||
"inserted": {
|
||||
"isDeleted": true,
|
||||
@@ -19493,7 +19493,7 @@ exports[`history > singleplayer undo/redo > should support bidirectional binding
|
||||
"fillStyle": "solid",
|
||||
"frameId": null,
|
||||
"groupIds": [],
|
||||
"height": 0,
|
||||
"height": "0.00661",
|
||||
"id": "id13",
|
||||
"index": "a3",
|
||||
"isDeleted": false,
|
||||
@@ -19508,7 +19508,7 @@ exports[`history > singleplayer undo/redo > should support bidirectional binding
|
||||
],
|
||||
[
|
||||
"88.00000",
|
||||
0,
|
||||
"-0.00661",
|
||||
],
|
||||
],
|
||||
"roughness": 1,
|
||||
@@ -19519,8 +19519,8 @@ exports[`history > singleplayer undo/redo > should support bidirectional binding
|
||||
"startBinding": {
|
||||
"elementId": "id0",
|
||||
"fixedPoint": [
|
||||
1,
|
||||
"0.50010",
|
||||
"0.50021",
|
||||
"0.50021",
|
||||
],
|
||||
"mode": "orbit",
|
||||
},
|
||||
@@ -19532,7 +19532,7 @@ exports[`history > singleplayer undo/redo > should support bidirectional binding
|
||||
"version": 11,
|
||||
"width": "88.00000",
|
||||
"x": 6,
|
||||
"y": "0.01000",
|
||||
"y": "0.01706",
|
||||
}
|
||||
`;
|
||||
|
||||
@@ -19604,8 +19604,8 @@ exports[`history > singleplayer undo/redo > should support bidirectional binding
|
||||
"startBinding": {
|
||||
"elementId": "id0",
|
||||
"fixedPoint": [
|
||||
1,
|
||||
"0.50010",
|
||||
"0.50021",
|
||||
"0.50021",
|
||||
],
|
||||
"mode": "orbit",
|
||||
},
|
||||
@@ -19883,7 +19883,7 @@ exports[`history > singleplayer undo/redo > should support bidirectional binding
|
||||
"fillStyle": "solid",
|
||||
"frameId": null,
|
||||
"groupIds": [],
|
||||
"height": 0,
|
||||
"height": "0.00661",
|
||||
"index": "a3",
|
||||
"isDeleted": false,
|
||||
"link": null,
|
||||
@@ -19896,7 +19896,7 @@ exports[`history > singleplayer undo/redo > should support bidirectional binding
|
||||
],
|
||||
[
|
||||
"88.00000",
|
||||
0,
|
||||
"-0.00661",
|
||||
],
|
||||
],
|
||||
"roughness": 1,
|
||||
@@ -19907,8 +19907,8 @@ exports[`history > singleplayer undo/redo > should support bidirectional binding
|
||||
"startBinding": {
|
||||
"elementId": "id0",
|
||||
"fixedPoint": [
|
||||
1,
|
||||
"0.50010",
|
||||
"0.50021",
|
||||
"0.50021",
|
||||
],
|
||||
"mode": "orbit",
|
||||
},
|
||||
@@ -19919,7 +19919,7 @@ exports[`history > singleplayer undo/redo > should support bidirectional binding
|
||||
"version": 7,
|
||||
"width": "88.00000",
|
||||
"x": 6,
|
||||
"y": "0.01000",
|
||||
"y": "0.01706",
|
||||
},
|
||||
"inserted": {
|
||||
"isDeleted": true,
|
||||
|
||||
@@ -182,14 +182,14 @@ exports[`move element > rectangles with binding arrow 7`] = `
|
||||
"elementId": "id3",
|
||||
"fixedPoint": [
|
||||
"-0.02000",
|
||||
"0.48010",
|
||||
"0.47928",
|
||||
],
|
||||
"mode": "orbit",
|
||||
},
|
||||
"fillStyle": "solid",
|
||||
"frameId": null,
|
||||
"groupIds": [],
|
||||
"height": "90.01760",
|
||||
"height": "93.60377",
|
||||
"id": "id6",
|
||||
"index": "a2",
|
||||
"isDeleted": false,
|
||||
@@ -204,7 +204,7 @@ exports[`move element > rectangles with binding arrow 7`] = `
|
||||
],
|
||||
[
|
||||
89,
|
||||
"90.01760",
|
||||
"93.60377",
|
||||
],
|
||||
],
|
||||
"roughness": 1,
|
||||
@@ -217,7 +217,7 @@ exports[`move element > rectangles with binding arrow 7`] = `
|
||||
"elementId": "id0",
|
||||
"fixedPoint": [
|
||||
"1.06000",
|
||||
"0.56011",
|
||||
"0.52181",
|
||||
],
|
||||
"mode": "orbit",
|
||||
},
|
||||
@@ -230,6 +230,6 @@ exports[`move element > rectangles with binding arrow 7`] = `
|
||||
"versionNonce": 271613161,
|
||||
"width": 89,
|
||||
"x": 106,
|
||||
"y": "56.01120",
|
||||
"y": "52.18052",
|
||||
}
|
||||
`;
|
||||
|
||||
@@ -1590,7 +1590,9 @@ describe("history", () => {
|
||||
expect(API.getUndoStack().length).toBe(5);
|
||||
expect(arrow.startBinding).toEqual({
|
||||
elementId: rect1.id,
|
||||
fixedPoint: expect.arrayContaining([1, 0.5001]),
|
||||
fixedPoint: expect.arrayContaining([
|
||||
0.5002127206977238, 0.5002127206977238,
|
||||
]),
|
||||
mode: "orbit",
|
||||
});
|
||||
expect(arrow.endBinding).toEqual({
|
||||
@@ -1613,7 +1615,9 @@ describe("history", () => {
|
||||
expect(API.getRedoStack().length).toBe(1);
|
||||
expect(arrow.startBinding).toEqual({
|
||||
elementId: rect1.id,
|
||||
fixedPoint: expect.arrayContaining([1, 0.5001]),
|
||||
fixedPoint: expect.arrayContaining([
|
||||
0.5002127206977238, 0.5002127206977238,
|
||||
]),
|
||||
mode: "orbit",
|
||||
});
|
||||
expect(arrow.endBinding).toEqual({
|
||||
@@ -1636,7 +1640,9 @@ describe("history", () => {
|
||||
expect(API.getRedoStack().length).toBe(0);
|
||||
expect(arrow.startBinding).toEqual({
|
||||
elementId: rect1.id,
|
||||
fixedPoint: expect.arrayContaining([1, 0.5001]),
|
||||
fixedPoint: expect.arrayContaining([
|
||||
0.5002127206977238, 0.5002127206977238,
|
||||
]),
|
||||
mode: "orbit",
|
||||
});
|
||||
expect(arrow.endBinding).toEqual({
|
||||
@@ -1667,7 +1673,9 @@ describe("history", () => {
|
||||
expect(API.getRedoStack().length).toBe(0);
|
||||
expect(arrow.startBinding).toEqual({
|
||||
elementId: rect1.id,
|
||||
fixedPoint: expect.arrayContaining([1, 0.5001]),
|
||||
fixedPoint: expect.arrayContaining([
|
||||
0.5002127206977238, 0.5002127206977238,
|
||||
]),
|
||||
mode: "orbit",
|
||||
});
|
||||
expect(arrow.endBinding).toEqual({
|
||||
@@ -1690,7 +1698,9 @@ describe("history", () => {
|
||||
expect(API.getRedoStack().length).toBe(1);
|
||||
expect(arrow.startBinding).toEqual({
|
||||
elementId: rect1.id,
|
||||
fixedPoint: expect.arrayContaining([1, 0.5001]),
|
||||
fixedPoint: expect.arrayContaining([
|
||||
0.5002127206977238, 0.5002127206977238,
|
||||
]),
|
||||
mode: "orbit",
|
||||
});
|
||||
expect(arrow.endBinding).toEqual({
|
||||
@@ -5132,7 +5142,7 @@ describe("history", () => {
|
||||
}),
|
||||
endBinding: expect.objectContaining({
|
||||
elementId: rect2.id,
|
||||
fixedPoint: expect.arrayContaining([0, 0.5001]),
|
||||
fixedPoint: expect.arrayContaining([0.5001, 0.5001]),
|
||||
}),
|
||||
isDeleted: true,
|
||||
}),
|
||||
|
||||
@@ -16,6 +16,8 @@ import * as StaticScene from "../renderer/staticScene";
|
||||
import { UI, Pointer, Keyboard } from "./helpers/ui";
|
||||
import { render, fireEvent, act, unmountComponent } from "./test-utils";
|
||||
|
||||
import type { Zoom } from "../types";
|
||||
|
||||
unmountComponent();
|
||||
|
||||
const renderInteractiveScene = vi.spyOn(
|
||||
@@ -88,6 +90,7 @@ describe("move element", () => {
|
||||
"orbit",
|
||||
"start",
|
||||
h.app.scene,
|
||||
{ value: 1 } as Zoom,
|
||||
);
|
||||
bindBindingElement(
|
||||
arrow.get() as NonDeleted<ExcalidrawArrowElement>,
|
||||
@@ -95,6 +98,7 @@ describe("move element", () => {
|
||||
"orbit",
|
||||
"end",
|
||||
h.app.scene,
|
||||
{ value: 1 } as Zoom,
|
||||
);
|
||||
});
|
||||
|
||||
@@ -111,10 +115,13 @@ describe("move element", () => {
|
||||
expect([rectA.x, rectA.y]).toEqual([0, 0]);
|
||||
expect([rectB.x, rectB.y]).toEqual([200, 0]);
|
||||
expect([[arrow.x, arrow.y]]).toCloselyEqualPoints(
|
||||
[[106.00000000000001, 55.6867741935484]],
|
||||
[[106, 52.18052313249668]],
|
||||
0,
|
||||
);
|
||||
expect([[arrow.width, arrow.height]]).toCloselyEqualPoints(
|
||||
[[88, 91.60376557808824]],
|
||||
0,
|
||||
);
|
||||
expect([[arrow.width, arrow.height]]).toCloselyEqualPoints([[88, 88]], 0);
|
||||
|
||||
renderInteractiveScene.mockClear();
|
||||
renderStaticScene.mockClear();
|
||||
@@ -133,10 +140,13 @@ describe("move element", () => {
|
||||
expect([rectA.x, rectA.y]).toEqual([0, 0]);
|
||||
expect([rectB.x, rectB.y]).toEqual([201, 2]);
|
||||
expect([[arrow.x, arrow.y]]).toCloselyEqualPoints(
|
||||
[[106, 55.6867741935484]],
|
||||
[[106, 52.18052313249668]],
|
||||
0,
|
||||
);
|
||||
expect([[arrow.width, arrow.height]]).toCloselyEqualPoints(
|
||||
[[89, 93.60376557808823]],
|
||||
0,
|
||||
);
|
||||
expect([[arrow.width, arrow.height]]).toCloselyEqualPoints([[89, 90]], 0);
|
||||
|
||||
h.elements.forEach((element) => expect(element).toMatchSnapshot());
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user