chore: Refactor binding gap calc
Signed-off-by: Mark Tolmacs <mark@lazycat.hu>
This commit is contained in:
@@ -91,7 +91,7 @@ export const isFocusPointVisible = (
|
||||
element: bindableElement,
|
||||
elementsMap,
|
||||
point: focusPoint,
|
||||
threshold: getBindingGap(bindableElement, arrow),
|
||||
threshold: getBindingGap(bindableElement),
|
||||
overrideShouldTestInside: true,
|
||||
})
|
||||
);
|
||||
|
||||
@@ -111,18 +111,13 @@ export type BindingStrategy =
|
||||
* IMPORTANT: currently must be > 0 (this also applies to the computed gap)
|
||||
*/
|
||||
export const BASE_BINDING_GAP = 5;
|
||||
export const BASE_BINDING_GAP_ELBOW = 5;
|
||||
export const BASE_ARROW_MIN_LENGTH = 10;
|
||||
export const FOCUS_POINT_SIZE = 10 / 1.5;
|
||||
|
||||
export const getBindingGap = (
|
||||
bindTarget: ExcalidrawBindableElement,
|
||||
opts: Pick<ExcalidrawArrowElement, "elbowed">,
|
||||
): number => {
|
||||
return (
|
||||
(opts.elbowed ? BASE_BINDING_GAP_ELBOW : BASE_BINDING_GAP) +
|
||||
bindTarget.strokeWidth / 2
|
||||
);
|
||||
return BASE_BINDING_GAP + bindTarget.strokeWidth / 2;
|
||||
};
|
||||
|
||||
export const maxBindingDistance_simple = (zoom?: AppState["zoom"]): number => {
|
||||
@@ -1416,7 +1411,7 @@ export const bindPointToSnapToElementOutline = (
|
||||
startOrEnd === "start" ? 1 : -2,
|
||||
elementsMap,
|
||||
);
|
||||
const bindingGap = getBindingGap(bindableElement, arrowElement);
|
||||
const bindingGap = getBindingGap(bindableElement);
|
||||
const aabb = aabbForElement(bindableElement, elementsMap);
|
||||
const bindableCenter = getCenterForBounds(aabb);
|
||||
|
||||
@@ -1477,7 +1472,7 @@ export const bindPointToSnapToElementOutline = (
|
||||
bindableElement,
|
||||
elementsMap,
|
||||
anotherIntersector,
|
||||
BASE_BINDING_GAP_ELBOW,
|
||||
BASE_BINDING_GAP,
|
||||
).sort(pointDistanceSq)[0];
|
||||
}
|
||||
} else {
|
||||
@@ -1536,7 +1531,7 @@ export const avoidRectangularCorner = (
|
||||
-bindTarget.angle as Radians,
|
||||
);
|
||||
|
||||
const bindingGap = getBindingGap(bindTarget, arrowElement);
|
||||
const bindingGap = getBindingGap(bindTarget);
|
||||
|
||||
if (nonRotatedPoint[0] < bindTarget.x && nonRotatedPoint[1] < bindTarget.y) {
|
||||
// Top left
|
||||
@@ -1714,7 +1709,7 @@ export const updateBoundPoint = (
|
||||
otherBindable,
|
||||
elementsMap,
|
||||
intersector,
|
||||
getBindingGap(otherBindable, arrow),
|
||||
getBindingGap(otherBindable),
|
||||
).sort(
|
||||
(a, b) => pointDistanceSq(a, focusPoint) - pointDistanceSq(b, focusPoint),
|
||||
)[0];
|
||||
@@ -1724,7 +1719,7 @@ export const updateBoundPoint = (
|
||||
bindableElement,
|
||||
elementsMap,
|
||||
intersector,
|
||||
getBindingGap(bindableElement, arrow),
|
||||
getBindingGap(bindableElement),
|
||||
).sort(
|
||||
(a, b) =>
|
||||
pointDistanceSq(a, otherFocusPointOrArrowPoint) -
|
||||
@@ -1752,7 +1747,7 @@ export const updateBoundPoint = (
|
||||
element: otherBindable,
|
||||
point: outlinePoint,
|
||||
elementsMap,
|
||||
threshold: getBindingGap(otherBindable, arrow),
|
||||
threshold: getBindingGap(otherBindable),
|
||||
overrideShouldTestInside: true,
|
||||
})
|
||||
) {
|
||||
|
||||
@@ -316,7 +316,7 @@ export const getAllHoveredElementAtPoint = (
|
||||
element,
|
||||
point,
|
||||
elementsMap,
|
||||
threshold: tolerance ?? getBindingGap(element, arrow),
|
||||
threshold: tolerance ?? getBindingGap(element),
|
||||
overrideShouldTestInside: true,
|
||||
})
|
||||
) {
|
||||
|
||||
@@ -30,7 +30,7 @@ import {
|
||||
getHeadingForElbowArrowSnap,
|
||||
getGlobalFixedPointForBindableElement,
|
||||
getBindingGap,
|
||||
BASE_BINDING_GAP_ELBOW,
|
||||
BASE_BINDING_GAP,
|
||||
} from "./binding";
|
||||
import { distanceToElement } from "./distance";
|
||||
import {
|
||||
@@ -1311,8 +1311,8 @@ const getElbowArrowData = (
|
||||
offsetFromHeading(
|
||||
startHeading,
|
||||
arrow.startArrowhead
|
||||
? getBindingGap(hoveredStartElement, { elbowed: true }) * 6
|
||||
: getBindingGap(hoveredStartElement, { elbowed: true }) * 2,
|
||||
? getBindingGap(hoveredStartElement) * 6
|
||||
: getBindingGap(hoveredStartElement) * 2,
|
||||
1,
|
||||
),
|
||||
)
|
||||
@@ -1324,8 +1324,8 @@ const getElbowArrowData = (
|
||||
offsetFromHeading(
|
||||
endHeading,
|
||||
arrow.endArrowhead
|
||||
? getBindingGap(hoveredEndElement, { elbowed: true }) * 6
|
||||
: getBindingGap(hoveredEndElement, { elbowed: true }) * 2,
|
||||
? getBindingGap(hoveredEndElement) * 6
|
||||
: getBindingGap(hoveredEndElement) * 2,
|
||||
1,
|
||||
),
|
||||
)
|
||||
@@ -1372,8 +1372,8 @@ const getElbowArrowData = (
|
||||
? 0
|
||||
: BASE_PADDING -
|
||||
(arrow.startArrowhead
|
||||
? BASE_BINDING_GAP_ELBOW * 6
|
||||
: BASE_BINDING_GAP_ELBOW * 2),
|
||||
? BASE_BINDING_GAP * 6
|
||||
: BASE_BINDING_GAP * 2),
|
||||
BASE_PADDING,
|
||||
),
|
||||
boundsOverlap
|
||||
@@ -1388,8 +1388,8 @@ const getElbowArrowData = (
|
||||
? 0
|
||||
: BASE_PADDING -
|
||||
(arrow.endArrowhead
|
||||
? BASE_BINDING_GAP_ELBOW * 6
|
||||
: BASE_BINDING_GAP_ELBOW * 2),
|
||||
? BASE_BINDING_GAP * 6
|
||||
: BASE_BINDING_GAP * 2),
|
||||
BASE_PADDING,
|
||||
),
|
||||
boundsOverlap,
|
||||
|
||||
+137
-133
@@ -588,104 +588,101 @@ const getDiagonalsForBindableElement = (
|
||||
return [diagonalOne, diagonalTwo];
|
||||
};
|
||||
|
||||
export const getHighlightedMidpointIndex = (
|
||||
point: GlobalPoint,
|
||||
const getSnappedMidpointIndexForElbowArrow = (
|
||||
element: ExcalidrawBindableElement,
|
||||
elementsMap: ElementsMap,
|
||||
zoom: AppState["zoom"],
|
||||
arrow: { elbowed: boolean },
|
||||
): number => {
|
||||
const center = elementCenterPoint(element, elementsMap);
|
||||
const TOLERANCE = 0.05;
|
||||
const maxDistance = maxBindingDistance_simple(zoom) + element.strokeWidth / 2;
|
||||
point: GlobalPoint,
|
||||
center: GlobalPoint,
|
||||
horizontalThreshold: number,
|
||||
verticalThreshold: number,
|
||||
) => {
|
||||
const { x, y, width, height, angle } = element;
|
||||
const nonRotated = pointRotateRads(point, center, -angle as Radians);
|
||||
|
||||
// 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);
|
||||
|
||||
if (pointDistance(center, nonRotated) < bindingGap) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (
|
||||
nonRotated[0] <= x + width / 2 &&
|
||||
nonRotated[1] > center[1] - verticalThreshold &&
|
||||
nonRotated[1] < center[1] + verticalThreshold
|
||||
) {
|
||||
return 2;
|
||||
} else if (
|
||||
nonRotated[1] <= y + height / 2 &&
|
||||
nonRotated[0] > center[0] - horizontalThreshold &&
|
||||
nonRotated[0] < center[0] + horizontalThreshold
|
||||
) {
|
||||
return 3;
|
||||
} else if (
|
||||
nonRotated[0] >= x + width / 2 &&
|
||||
nonRotated[1] > center[1] - verticalThreshold &&
|
||||
nonRotated[1] < center[1] + verticalThreshold
|
||||
) {
|
||||
return 0;
|
||||
} else if (
|
||||
nonRotated[1] >= y + height / 2 &&
|
||||
nonRotated[0] > center[0] - horizontalThreshold &&
|
||||
nonRotated[0] < center[0] + horizontalThreshold
|
||||
) {
|
||||
return 1;
|
||||
} 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(bottomLeft, nonRotated) <
|
||||
Math.max(horizontalThreshold, verticalThreshold)
|
||||
) {
|
||||
return 1;
|
||||
}
|
||||
if (
|
||||
pointDistance(bottomRight, nonRotated) <
|
||||
Math.max(horizontalThreshold, verticalThreshold)
|
||||
) {
|
||||
return 0;
|
||||
}
|
||||
if (
|
||||
pointDistance(topLeft, nonRotated) <
|
||||
Math.max(horizontalThreshold, verticalThreshold)
|
||||
) {
|
||||
return 2;
|
||||
}
|
||||
if (
|
||||
pointDistance(topRight, nonRotated) <
|
||||
Math.max(horizontalThreshold, verticalThreshold)
|
||||
) {
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
const bindingGap = getBindingGap(element);
|
||||
|
||||
if (pointDistance(center, nonRotated) < bindingGap) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (
|
||||
nonRotated[0] <= x + width / 2 &&
|
||||
nonRotated[1] > center[1] - verticalThreshold &&
|
||||
nonRotated[1] < center[1] + verticalThreshold
|
||||
) {
|
||||
return 2;
|
||||
} else if (
|
||||
nonRotated[1] <= y + height / 2 &&
|
||||
nonRotated[0] > center[0] - horizontalThreshold &&
|
||||
nonRotated[0] < center[0] + horizontalThreshold
|
||||
) {
|
||||
return 3;
|
||||
} else if (
|
||||
nonRotated[0] >= x + width / 2 &&
|
||||
nonRotated[1] > center[1] - verticalThreshold &&
|
||||
nonRotated[1] < center[1] + verticalThreshold
|
||||
) {
|
||||
return 0;
|
||||
} else if (
|
||||
nonRotated[1] >= y + height / 2 &&
|
||||
nonRotated[0] > center[0] - horizontalThreshold &&
|
||||
nonRotated[0] < center[0] + horizontalThreshold
|
||||
) {
|
||||
return 1;
|
||||
} 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(bottomLeft, nonRotated) <
|
||||
Math.max(horizontalThreshold, verticalThreshold)
|
||||
) {
|
||||
return 1;
|
||||
}
|
||||
if (
|
||||
pointDistance(bottomRight, nonRotated) <
|
||||
Math.max(horizontalThreshold, verticalThreshold)
|
||||
) {
|
||||
return 0;
|
||||
}
|
||||
if (
|
||||
pointDistance(topLeft, nonRotated) <
|
||||
Math.max(horizontalThreshold, verticalThreshold)
|
||||
) {
|
||||
return 2;
|
||||
}
|
||||
if (
|
||||
pointDistance(topRight, nonRotated) <
|
||||
Math.max(horizontalThreshold, verticalThreshold)
|
||||
) {
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
};
|
||||
|
||||
const getSnappedMidpointIndexForSimpleArrow = (
|
||||
element: ExcalidrawBindableElement,
|
||||
point: GlobalPoint,
|
||||
elementsMap: ElementsMap,
|
||||
horizontalThreshold: number,
|
||||
verticalThreshold: number,
|
||||
) => {
|
||||
const baseMidpoints = getAllMidpoints(element, elementsMap);
|
||||
|
||||
for (let i = 0; i < baseMidpoints.length; i++) {
|
||||
@@ -708,41 +705,6 @@ export const getHighlightedMidpointIndex = (
|
||||
return -1;
|
||||
};
|
||||
|
||||
export const getSnapOutlineMidPoint = (
|
||||
point: GlobalPoint,
|
||||
element: ExcalidrawBindableElement,
|
||||
elementsMap: ElementsMap,
|
||||
zoom: AppState["zoom"],
|
||||
arrow: { elbowed: boolean },
|
||||
): GlobalPoint | undefined => {
|
||||
const center = elementCenterPoint(element, elementsMap);
|
||||
const baseMidpoints = getAllMidpoints(element, elementsMap);
|
||||
|
||||
const sideMidpoints =
|
||||
element.type === "diamond"
|
||||
? baseMidpoints.map((midpoint) => {
|
||||
return pointFrom<GlobalPoint>(
|
||||
midpoint[0] + (midpoint[0] - center[0]) * 0.1,
|
||||
midpoint[1] + (midpoint[1] - center[1]) * 0.1,
|
||||
);
|
||||
})
|
||||
: baseMidpoints;
|
||||
|
||||
const idx = getHighlightedMidpointIndex(
|
||||
point,
|
||||
element,
|
||||
elementsMap,
|
||||
zoom,
|
||||
arrow,
|
||||
);
|
||||
|
||||
if (idx === -1) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return sideMidpoints[idx];
|
||||
};
|
||||
|
||||
export const getAllMidpoints = (
|
||||
element: ExcalidrawBindableElement,
|
||||
elementsMap: ElementsMap,
|
||||
@@ -750,10 +712,9 @@ export const getAllMidpoints = (
|
||||
const center = elementCenterPoint(element, elementsMap);
|
||||
|
||||
if (element.type === "diamond") {
|
||||
return getDiamondBaseCorners(element).map((curve) => {
|
||||
const point = bezierEquation(curve, 0.5);
|
||||
return pointRotateRads(point, center, element.angle);
|
||||
});
|
||||
return getDiamondBaseCorners(element).map((curve) =>
|
||||
pointRotateRads(bezierEquation(curve, 0.5), center, element.angle),
|
||||
);
|
||||
}
|
||||
|
||||
return [
|
||||
@@ -770,6 +731,52 @@ export const getAllMidpoints = (
|
||||
);
|
||||
};
|
||||
|
||||
export const getSnapOutlineMidPoint = (
|
||||
point: GlobalPoint,
|
||||
element: ExcalidrawBindableElement,
|
||||
elementsMap: ElementsMap,
|
||||
zoom: AppState["zoom"],
|
||||
arrow: { elbowed: boolean },
|
||||
): GlobalPoint | undefined => {
|
||||
const center = elementCenterPoint(element, elementsMap);
|
||||
const baseMidpoints = getAllMidpoints(element, elementsMap);
|
||||
const sideMidpoints =
|
||||
element.type === "diamond"
|
||||
? baseMidpoints.map((midpoint) => {
|
||||
return pointFrom<GlobalPoint>(
|
||||
midpoint[0] + (midpoint[0] - center[0]) * 0.1,
|
||||
midpoint[1] + (midpoint[1] - center[1]) * 0.1,
|
||||
);
|
||||
})
|
||||
: baseMidpoints;
|
||||
|
||||
const TOLERANCE = 0.05;
|
||||
const maxDistance = maxBindingDistance_simple(zoom) + element.strokeWidth / 2;
|
||||
const verticalThreshold = clamp(TOLERANCE * element.height, 5, maxDistance);
|
||||
const horizontalThreshold = clamp(TOLERANCE * element.width, 5, maxDistance);
|
||||
const idx = arrow.elbowed
|
||||
? getSnappedMidpointIndexForElbowArrow(
|
||||
element,
|
||||
point,
|
||||
center,
|
||||
horizontalThreshold,
|
||||
verticalThreshold,
|
||||
)
|
||||
: getSnappedMidpointIndexForSimpleArrow(
|
||||
element,
|
||||
point,
|
||||
elementsMap,
|
||||
horizontalThreshold,
|
||||
verticalThreshold,
|
||||
);
|
||||
|
||||
if (idx === -1) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return sideMidpoints[idx];
|
||||
};
|
||||
|
||||
export const projectFixedPointOntoDiagonal = (
|
||||
arrow: ExcalidrawArrowElement,
|
||||
point: GlobalPoint,
|
||||
@@ -780,9 +787,6 @@ export const projectFixedPointOntoDiagonal = (
|
||||
isMidpointSnappingEnabled: boolean = true,
|
||||
): GlobalPoint | null => {
|
||||
invariant(arrow.points.length >= 2, "Arrow must have at least two points");
|
||||
if (arrow.width < 3 && arrow.height < 3) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (isMidpointSnappingEnabled) {
|
||||
const sideMidPoint = getSnapOutlineMidPoint(
|
||||
|
||||
@@ -24,13 +24,11 @@ import {
|
||||
deconstructRectanguloidElement,
|
||||
elementCenterPoint,
|
||||
getAllMidpoints,
|
||||
getHighlightedMidpointIndex,
|
||||
FOCUS_POINT_SIZE,
|
||||
getOmitSidesForEditorInterface,
|
||||
getTransformHandles,
|
||||
getTransformHandlesFromCoords,
|
||||
hasBoundingBox,
|
||||
hitElementItself,
|
||||
isArrowElement,
|
||||
isBindableElement,
|
||||
isElbowArrow,
|
||||
@@ -412,74 +410,42 @@ const renderBindingHighlightForBindableElement_simple = (
|
||||
break;
|
||||
}
|
||||
|
||||
// Draw midpoint indicators
|
||||
if (
|
||||
appState.isMidpointSnappingEnabled &&
|
||||
(isFrameLikeElement(suggestedBinding.element) ||
|
||||
isBindableElement(suggestedBinding.element))
|
||||
) {
|
||||
// Draw midpoint indicators
|
||||
const linearElement = appState.selectedLinearElement;
|
||||
const arrow =
|
||||
linearElement?.elementId &&
|
||||
LinearElementEditor.getElement(linearElement?.elementId, elementsMap);
|
||||
const cursorIsInsideBindable =
|
||||
pointerCoords &&
|
||||
hitElementItself({
|
||||
point: pointerCoords,
|
||||
element: suggestedBinding.element,
|
||||
elementsMap,
|
||||
threshold: 0,
|
||||
overrideShouldTestInside: true,
|
||||
});
|
||||
context.save();
|
||||
|
||||
const isElbow =
|
||||
(arrow && isElbowArrow(arrow)) ||
|
||||
(appState.activeTool.type === "arrow" &&
|
||||
appState.currentItemArrowType === "elbow");
|
||||
const midpointRadius = 4 / appState.zoom.value;
|
||||
|
||||
if (!cursorIsInsideBindable || isElbow) {
|
||||
context.save();
|
||||
|
||||
const midpoints = getAllMidpoints(suggestedBinding.element, elementsMap);
|
||||
|
||||
const highlightedIdx = pointerCoords
|
||||
? getHighlightedMidpointIndex(
|
||||
pointerCoords,
|
||||
suggestedBinding.element,
|
||||
elementsMap,
|
||||
appState.zoom,
|
||||
{ elbowed: isElbow },
|
||||
)
|
||||
: -1;
|
||||
|
||||
const midpointRadius = 4 / appState.zoom.value;
|
||||
|
||||
midpoints.forEach((midpoint, idx) => {
|
||||
const isHighlighted =
|
||||
highlightedIdx === idx && (!cursorIsInsideBindable || isElbow);
|
||||
|
||||
if (isHighlighted) {
|
||||
context.fillStyle =
|
||||
appState.theme === THEME.DARK
|
||||
? `rgba(3, 93, 161, 1)`
|
||||
: `rgba(106, 189, 252, 1)`;
|
||||
|
||||
context.beginPath();
|
||||
context.arc(midpoint[0], midpoint[1], midpointRadius, 0, 2 * Math.PI);
|
||||
context.fill();
|
||||
} else {
|
||||
context.fillStyle =
|
||||
appState.theme === THEME.DARK
|
||||
? `rgba(0, 0, 0, 0.8)`
|
||||
: `rgba(65, 65, 65, 0.5)`;
|
||||
context.beginPath();
|
||||
context.arc(midpoint[0], midpoint[1], midpointRadius, 0, 2 * Math.PI);
|
||||
context.fill();
|
||||
}
|
||||
});
|
||||
|
||||
context.restore();
|
||||
// Render base midpoints
|
||||
const midpoints = getAllMidpoints(suggestedBinding.element, elementsMap);
|
||||
for (const midpoint of midpoints) {
|
||||
context.fillStyle =
|
||||
appState.theme === THEME.DARK
|
||||
? `rgba(0, 0, 0, 0.8)`
|
||||
: `rgba(65, 65, 65, 0.5)`;
|
||||
context.beginPath();
|
||||
context.arc(midpoint[0], midpoint[1], midpointRadius, 0, 2 * Math.PI);
|
||||
context.fill();
|
||||
}
|
||||
|
||||
// Render the highlighted midpoint if any
|
||||
const midpoint = appState.suggestedBinding?.midPoint;
|
||||
if (midpoint) {
|
||||
context.fillStyle =
|
||||
appState.theme === THEME.DARK
|
||||
? `rgba(3, 93, 161, 1)`
|
||||
: `rgba(106, 189, 252, 1)`;
|
||||
|
||||
context.beginPath();
|
||||
context.arc(midpoint[0], midpoint[1], midpointRadius, 0, 2 * Math.PI);
|
||||
context.fill();
|
||||
}
|
||||
|
||||
context.restore();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -16703,7 +16703,7 @@ exports[`history > singleplayer undo/redo > should support bidirectional binding
|
||||
"fillStyle": "solid",
|
||||
"frameId": null,
|
||||
"groupIds": [],
|
||||
"height": "0.00661",
|
||||
"height": 0,
|
||||
"id": "id13",
|
||||
"index": "a3",
|
||||
"isDeleted": false,
|
||||
@@ -16718,7 +16718,7 @@ exports[`history > singleplayer undo/redo > should support bidirectional binding
|
||||
],
|
||||
[
|
||||
"88.00000",
|
||||
"-0.00661",
|
||||
0,
|
||||
],
|
||||
],
|
||||
"roughness": 1,
|
||||
@@ -16729,8 +16729,8 @@ exports[`history > singleplayer undo/redo > should support bidirectional binding
|
||||
"startBinding": {
|
||||
"elementId": "id0",
|
||||
"fixedPoint": [
|
||||
"0.50021",
|
||||
"0.50021",
|
||||
1,
|
||||
"0.50010",
|
||||
],
|
||||
"mode": "orbit",
|
||||
},
|
||||
@@ -16742,7 +16742,7 @@ exports[`history > singleplayer undo/redo > should support bidirectional binding
|
||||
"version": 10,
|
||||
"width": "88.00000",
|
||||
"x": 6,
|
||||
"y": "0.01706",
|
||||
"y": "0.01000",
|
||||
}
|
||||
`;
|
||||
|
||||
@@ -16787,8 +16787,8 @@ exports[`history > singleplayer undo/redo > should support bidirectional binding
|
||||
"startBinding": {
|
||||
"elementId": "id0",
|
||||
"fixedPoint": [
|
||||
"0.50021",
|
||||
"0.50021",
|
||||
1,
|
||||
"0.50010",
|
||||
],
|
||||
"mode": "orbit",
|
||||
},
|
||||
@@ -16807,8 +16807,8 @@ exports[`history > singleplayer undo/redo > should support bidirectional binding
|
||||
"startBinding": {
|
||||
"elementId": "id0",
|
||||
"fixedPoint": [
|
||||
"0.50021",
|
||||
"0.50021",
|
||||
1,
|
||||
"0.50010",
|
||||
],
|
||||
"mode": "orbit",
|
||||
},
|
||||
@@ -17121,7 +17121,7 @@ exports[`history > singleplayer undo/redo > should support bidirectional binding
|
||||
"fillStyle": "solid",
|
||||
"frameId": null,
|
||||
"groupIds": [],
|
||||
"height": "0.00661",
|
||||
"height": 0,
|
||||
"index": "a3",
|
||||
"isDeleted": false,
|
||||
"link": null,
|
||||
@@ -17134,7 +17134,7 @@ exports[`history > singleplayer undo/redo > should support bidirectional binding
|
||||
],
|
||||
[
|
||||
"88.00000",
|
||||
"-0.00661",
|
||||
0,
|
||||
],
|
||||
],
|
||||
"roughness": 1,
|
||||
@@ -17145,8 +17145,8 @@ exports[`history > singleplayer undo/redo > should support bidirectional binding
|
||||
"startBinding": {
|
||||
"elementId": "id0",
|
||||
"fixedPoint": [
|
||||
"0.50021",
|
||||
"0.50021",
|
||||
1,
|
||||
"0.50010",
|
||||
],
|
||||
"mode": "orbit",
|
||||
},
|
||||
@@ -17157,7 +17157,7 @@ exports[`history > singleplayer undo/redo > should support bidirectional binding
|
||||
"version": 7,
|
||||
"width": "88.00000",
|
||||
"x": 6,
|
||||
"y": "0.01706",
|
||||
"y": "0.01000",
|
||||
},
|
||||
"inserted": {
|
||||
"isDeleted": true,
|
||||
@@ -17451,7 +17451,7 @@ exports[`history > singleplayer undo/redo > should support bidirectional binding
|
||||
"fillStyle": "solid",
|
||||
"frameId": null,
|
||||
"groupIds": [],
|
||||
"height": "0.00661",
|
||||
"height": 0,
|
||||
"id": "id13",
|
||||
"index": "a3",
|
||||
"isDeleted": false,
|
||||
@@ -17466,7 +17466,7 @@ exports[`history > singleplayer undo/redo > should support bidirectional binding
|
||||
],
|
||||
[
|
||||
"88.00000",
|
||||
"-0.00661",
|
||||
0,
|
||||
],
|
||||
],
|
||||
"roughness": 1,
|
||||
@@ -17477,8 +17477,8 @@ exports[`history > singleplayer undo/redo > should support bidirectional binding
|
||||
"startBinding": {
|
||||
"elementId": "id0",
|
||||
"fixedPoint": [
|
||||
"0.50021",
|
||||
"0.50021",
|
||||
1,
|
||||
"0.50010",
|
||||
],
|
||||
"mode": "orbit",
|
||||
},
|
||||
@@ -17490,7 +17490,7 @@ exports[`history > singleplayer undo/redo > should support bidirectional binding
|
||||
"version": 10,
|
||||
"width": "88.00000",
|
||||
"x": 6,
|
||||
"y": "0.01706",
|
||||
"y": "0.01000",
|
||||
}
|
||||
`;
|
||||
|
||||
@@ -17759,7 +17759,7 @@ exports[`history > singleplayer undo/redo > should support bidirectional binding
|
||||
"fillStyle": "solid",
|
||||
"frameId": null,
|
||||
"groupIds": [],
|
||||
"height": "0.00661",
|
||||
"height": 0,
|
||||
"index": "a3",
|
||||
"isDeleted": false,
|
||||
"link": null,
|
||||
@@ -17772,7 +17772,7 @@ exports[`history > singleplayer undo/redo > should support bidirectional binding
|
||||
],
|
||||
[
|
||||
"88.00000",
|
||||
"-0.00661",
|
||||
0,
|
||||
],
|
||||
],
|
||||
"roughness": 1,
|
||||
@@ -17783,8 +17783,8 @@ exports[`history > singleplayer undo/redo > should support bidirectional binding
|
||||
"startBinding": {
|
||||
"elementId": "id0",
|
||||
"fixedPoint": [
|
||||
"0.50021",
|
||||
"0.50021",
|
||||
1,
|
||||
"0.50010",
|
||||
],
|
||||
"mode": "orbit",
|
||||
},
|
||||
@@ -17795,7 +17795,7 @@ exports[`history > singleplayer undo/redo > should support bidirectional binding
|
||||
"version": 10,
|
||||
"width": "88.00000",
|
||||
"x": 6,
|
||||
"y": "0.01706",
|
||||
"y": "0.01000",
|
||||
},
|
||||
"inserted": {
|
||||
"isDeleted": true,
|
||||
@@ -18097,7 +18097,7 @@ exports[`history > singleplayer undo/redo > should support bidirectional binding
|
||||
"fillStyle": "solid",
|
||||
"frameId": null,
|
||||
"groupIds": [],
|
||||
"height": "0.00661",
|
||||
"height": 0,
|
||||
"id": "id13",
|
||||
"index": "a3",
|
||||
"isDeleted": false,
|
||||
@@ -18112,7 +18112,7 @@ exports[`history > singleplayer undo/redo > should support bidirectional binding
|
||||
],
|
||||
[
|
||||
"88.00000",
|
||||
"-0.00661",
|
||||
0,
|
||||
],
|
||||
],
|
||||
"roughness": 1,
|
||||
@@ -18123,8 +18123,8 @@ exports[`history > singleplayer undo/redo > should support bidirectional binding
|
||||
"startBinding": {
|
||||
"elementId": "id0",
|
||||
"fixedPoint": [
|
||||
"0.50021",
|
||||
"0.50021",
|
||||
1,
|
||||
"0.50010",
|
||||
],
|
||||
"mode": "orbit",
|
||||
},
|
||||
@@ -18136,7 +18136,7 @@ exports[`history > singleplayer undo/redo > should support bidirectional binding
|
||||
"version": 10,
|
||||
"width": "88.00000",
|
||||
"x": 6,
|
||||
"y": "0.01706",
|
||||
"y": "0.01000",
|
||||
}
|
||||
`;
|
||||
|
||||
@@ -18405,7 +18405,7 @@ exports[`history > singleplayer undo/redo > should support bidirectional binding
|
||||
"fillStyle": "solid",
|
||||
"frameId": null,
|
||||
"groupIds": [],
|
||||
"height": "0.00661",
|
||||
"height": 0,
|
||||
"index": "a3",
|
||||
"isDeleted": false,
|
||||
"link": null,
|
||||
@@ -18418,7 +18418,7 @@ exports[`history > singleplayer undo/redo > should support bidirectional binding
|
||||
],
|
||||
[
|
||||
"88.00000",
|
||||
"-0.00661",
|
||||
0,
|
||||
],
|
||||
],
|
||||
"roughness": 1,
|
||||
@@ -18429,8 +18429,8 @@ exports[`history > singleplayer undo/redo > should support bidirectional binding
|
||||
"startBinding": {
|
||||
"elementId": "id0",
|
||||
"fixedPoint": [
|
||||
"0.50021",
|
||||
"0.50021",
|
||||
1,
|
||||
"0.50010",
|
||||
],
|
||||
"mode": "orbit",
|
||||
},
|
||||
@@ -18441,7 +18441,7 @@ exports[`history > singleplayer undo/redo > should support bidirectional binding
|
||||
"version": 10,
|
||||
"width": "88.00000",
|
||||
"x": 6,
|
||||
"y": "0.01706",
|
||||
"y": "0.01000",
|
||||
},
|
||||
"inserted": {
|
||||
"isDeleted": true,
|
||||
@@ -18741,7 +18741,7 @@ exports[`history > singleplayer undo/redo > should support bidirectional binding
|
||||
"fillStyle": "solid",
|
||||
"frameId": null,
|
||||
"groupIds": [],
|
||||
"height": "0.00661",
|
||||
"height": 0,
|
||||
"id": "id13",
|
||||
"index": "a3",
|
||||
"isDeleted": false,
|
||||
@@ -18756,7 +18756,7 @@ exports[`history > singleplayer undo/redo > should support bidirectional binding
|
||||
],
|
||||
[
|
||||
"88.00000",
|
||||
"-0.00661",
|
||||
0,
|
||||
],
|
||||
],
|
||||
"roughness": 1,
|
||||
@@ -18767,8 +18767,8 @@ exports[`history > singleplayer undo/redo > should support bidirectional binding
|
||||
"startBinding": {
|
||||
"elementId": "id0",
|
||||
"fixedPoint": [
|
||||
"0.50021",
|
||||
"0.50021",
|
||||
1,
|
||||
"0.50010",
|
||||
],
|
||||
"mode": "orbit",
|
||||
},
|
||||
@@ -18780,7 +18780,7 @@ exports[`history > singleplayer undo/redo > should support bidirectional binding
|
||||
"version": 10,
|
||||
"width": "88.00000",
|
||||
"x": 6,
|
||||
"y": "0.01706",
|
||||
"y": "0.01000",
|
||||
}
|
||||
`;
|
||||
|
||||
@@ -18841,8 +18841,8 @@ exports[`history > singleplayer undo/redo > should support bidirectional binding
|
||||
"startBinding": {
|
||||
"elementId": "id0",
|
||||
"fixedPoint": [
|
||||
"0.50021",
|
||||
"0.50021",
|
||||
1,
|
||||
"0.50010",
|
||||
],
|
||||
"mode": "orbit",
|
||||
},
|
||||
@@ -19135,7 +19135,7 @@ exports[`history > singleplayer undo/redo > should support bidirectional binding
|
||||
"fillStyle": "solid",
|
||||
"frameId": null,
|
||||
"groupIds": [],
|
||||
"height": "0.00661",
|
||||
"height": 0,
|
||||
"index": "a3",
|
||||
"isDeleted": false,
|
||||
"link": null,
|
||||
@@ -19148,7 +19148,7 @@ exports[`history > singleplayer undo/redo > should support bidirectional binding
|
||||
],
|
||||
[
|
||||
"88.00000",
|
||||
"-0.00661",
|
||||
0,
|
||||
],
|
||||
],
|
||||
"roughness": 1,
|
||||
@@ -19159,8 +19159,8 @@ exports[`history > singleplayer undo/redo > should support bidirectional binding
|
||||
"startBinding": {
|
||||
"elementId": "id0",
|
||||
"fixedPoint": [
|
||||
"0.50021",
|
||||
"0.50021",
|
||||
1,
|
||||
"0.50010",
|
||||
],
|
||||
"mode": "orbit",
|
||||
},
|
||||
@@ -19171,7 +19171,7 @@ exports[`history > singleplayer undo/redo > should support bidirectional binding
|
||||
"version": 7,
|
||||
"width": "88.00000",
|
||||
"x": 6,
|
||||
"y": "0.01706",
|
||||
"y": "0.01000",
|
||||
},
|
||||
"inserted": {
|
||||
"isDeleted": true,
|
||||
@@ -19493,7 +19493,7 @@ exports[`history > singleplayer undo/redo > should support bidirectional binding
|
||||
"fillStyle": "solid",
|
||||
"frameId": null,
|
||||
"groupIds": [],
|
||||
"height": "0.00661",
|
||||
"height": 0,
|
||||
"id": "id13",
|
||||
"index": "a3",
|
||||
"isDeleted": false,
|
||||
@@ -19508,7 +19508,7 @@ exports[`history > singleplayer undo/redo > should support bidirectional binding
|
||||
],
|
||||
[
|
||||
"88.00000",
|
||||
"-0.00661",
|
||||
0,
|
||||
],
|
||||
],
|
||||
"roughness": 1,
|
||||
@@ -19519,8 +19519,8 @@ exports[`history > singleplayer undo/redo > should support bidirectional binding
|
||||
"startBinding": {
|
||||
"elementId": "id0",
|
||||
"fixedPoint": [
|
||||
"0.50021",
|
||||
"0.50021",
|
||||
1,
|
||||
"0.50010",
|
||||
],
|
||||
"mode": "orbit",
|
||||
},
|
||||
@@ -19532,7 +19532,7 @@ exports[`history > singleplayer undo/redo > should support bidirectional binding
|
||||
"version": 11,
|
||||
"width": "88.00000",
|
||||
"x": 6,
|
||||
"y": "0.01706",
|
||||
"y": "0.01000",
|
||||
}
|
||||
`;
|
||||
|
||||
@@ -19604,8 +19604,8 @@ exports[`history > singleplayer undo/redo > should support bidirectional binding
|
||||
"startBinding": {
|
||||
"elementId": "id0",
|
||||
"fixedPoint": [
|
||||
"0.50021",
|
||||
"0.50021",
|
||||
1,
|
||||
"0.50010",
|
||||
],
|
||||
"mode": "orbit",
|
||||
},
|
||||
@@ -19883,7 +19883,7 @@ exports[`history > singleplayer undo/redo > should support bidirectional binding
|
||||
"fillStyle": "solid",
|
||||
"frameId": null,
|
||||
"groupIds": [],
|
||||
"height": "0.00661",
|
||||
"height": 0,
|
||||
"index": "a3",
|
||||
"isDeleted": false,
|
||||
"link": null,
|
||||
@@ -19896,7 +19896,7 @@ exports[`history > singleplayer undo/redo > should support bidirectional binding
|
||||
],
|
||||
[
|
||||
"88.00000",
|
||||
"-0.00661",
|
||||
0,
|
||||
],
|
||||
],
|
||||
"roughness": 1,
|
||||
@@ -19907,8 +19907,8 @@ exports[`history > singleplayer undo/redo > should support bidirectional binding
|
||||
"startBinding": {
|
||||
"elementId": "id0",
|
||||
"fixedPoint": [
|
||||
"0.50021",
|
||||
"0.50021",
|
||||
1,
|
||||
"0.50010",
|
||||
],
|
||||
"mode": "orbit",
|
||||
},
|
||||
@@ -19919,7 +19919,7 @@ exports[`history > singleplayer undo/redo > should support bidirectional binding
|
||||
"version": 7,
|
||||
"width": "88.00000",
|
||||
"x": 6,
|
||||
"y": "0.01706",
|
||||
"y": "0.01000",
|
||||
},
|
||||
"inserted": {
|
||||
"isDeleted": true,
|
||||
|
||||
@@ -182,14 +182,14 @@ exports[`move element > rectangles with binding arrow 7`] = `
|
||||
"elementId": "id3",
|
||||
"fixedPoint": [
|
||||
"-0.02000",
|
||||
"0.47928",
|
||||
"0.48010",
|
||||
],
|
||||
"mode": "orbit",
|
||||
},
|
||||
"fillStyle": "solid",
|
||||
"frameId": null,
|
||||
"groupIds": [],
|
||||
"height": "93.60377",
|
||||
"height": "90.01760",
|
||||
"id": "id6",
|
||||
"index": "a2",
|
||||
"isDeleted": false,
|
||||
@@ -204,7 +204,7 @@ exports[`move element > rectangles with binding arrow 7`] = `
|
||||
],
|
||||
[
|
||||
89,
|
||||
"93.60377",
|
||||
"90.01760",
|
||||
],
|
||||
],
|
||||
"roughness": 1,
|
||||
@@ -217,7 +217,7 @@ exports[`move element > rectangles with binding arrow 7`] = `
|
||||
"elementId": "id0",
|
||||
"fixedPoint": [
|
||||
"1.06000",
|
||||
"0.52181",
|
||||
"0.56011",
|
||||
],
|
||||
"mode": "orbit",
|
||||
},
|
||||
@@ -230,6 +230,6 @@ exports[`move element > rectangles with binding arrow 7`] = `
|
||||
"versionNonce": 271613161,
|
||||
"width": 89,
|
||||
"x": 106,
|
||||
"y": "52.18052",
|
||||
"y": "56.01120",
|
||||
}
|
||||
`;
|
||||
|
||||
@@ -1590,9 +1590,7 @@ describe("history", () => {
|
||||
expect(API.getUndoStack().length).toBe(5);
|
||||
expect(arrow.startBinding).toEqual({
|
||||
elementId: rect1.id,
|
||||
fixedPoint: expect.arrayContaining([
|
||||
0.5002127206977238, 0.5002127206977238,
|
||||
]),
|
||||
fixedPoint: expect.arrayContaining([1, 0.5001]),
|
||||
mode: "orbit",
|
||||
});
|
||||
expect(arrow.endBinding).toEqual({
|
||||
@@ -1615,9 +1613,7 @@ describe("history", () => {
|
||||
expect(API.getRedoStack().length).toBe(1);
|
||||
expect(arrow.startBinding).toEqual({
|
||||
elementId: rect1.id,
|
||||
fixedPoint: expect.arrayContaining([
|
||||
0.5002127206977238, 0.5002127206977238,
|
||||
]),
|
||||
fixedPoint: expect.arrayContaining([1, 0.5001]),
|
||||
mode: "orbit",
|
||||
});
|
||||
expect(arrow.endBinding).toEqual({
|
||||
@@ -1640,9 +1636,7 @@ describe("history", () => {
|
||||
expect(API.getRedoStack().length).toBe(0);
|
||||
expect(arrow.startBinding).toEqual({
|
||||
elementId: rect1.id,
|
||||
fixedPoint: expect.arrayContaining([
|
||||
0.5002127206977238, 0.5002127206977238,
|
||||
]),
|
||||
fixedPoint: expect.arrayContaining([1, 0.5001]),
|
||||
mode: "orbit",
|
||||
});
|
||||
expect(arrow.endBinding).toEqual({
|
||||
@@ -1673,9 +1667,7 @@ describe("history", () => {
|
||||
expect(API.getRedoStack().length).toBe(0);
|
||||
expect(arrow.startBinding).toEqual({
|
||||
elementId: rect1.id,
|
||||
fixedPoint: expect.arrayContaining([
|
||||
0.5002127206977238, 0.5002127206977238,
|
||||
]),
|
||||
fixedPoint: expect.arrayContaining([1, 0.5001]),
|
||||
mode: "orbit",
|
||||
});
|
||||
expect(arrow.endBinding).toEqual({
|
||||
@@ -1698,9 +1690,7 @@ describe("history", () => {
|
||||
expect(API.getRedoStack().length).toBe(1);
|
||||
expect(arrow.startBinding).toEqual({
|
||||
elementId: rect1.id,
|
||||
fixedPoint: expect.arrayContaining([
|
||||
0.5002127206977238, 0.5002127206977238,
|
||||
]),
|
||||
fixedPoint: expect.arrayContaining([1, 0.5001]),
|
||||
mode: "orbit",
|
||||
});
|
||||
expect(arrow.endBinding).toEqual({
|
||||
|
||||
@@ -115,11 +115,11 @@ 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, 52.18052313249668]],
|
||||
[[106, 56.011199999998695]],
|
||||
0,
|
||||
);
|
||||
expect([[arrow.width, arrow.height]]).toCloselyEqualPoints(
|
||||
[[88, 91.60376557808824]],
|
||||
[[88, 88.01760000000121]],
|
||||
0,
|
||||
);
|
||||
|
||||
@@ -140,11 +140,11 @@ 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, 52.18052313249668]],
|
||||
[[106, 56.011199999998695]],
|
||||
0,
|
||||
);
|
||||
expect([[arrow.width, arrow.height]]).toCloselyEqualPoints(
|
||||
[[89, 93.60376557808823]],
|
||||
[[89, 90.01760000000121]],
|
||||
0,
|
||||
);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user