mirror of
https://github.com/excalidraw/excalidraw.git
synced 2025-05-03 10:00:07 -04:00
fix: remove scene from getElementAbsoluteCoords and dependent functions and use elementsMap (#7663)
* fix: remove scene from getElementAbsoluteCoords and dependent functions and use elementsMap * lint * fix * use non deleted elements where possible * use non deleted elements map in actions * pass elementsMap instead of array to elementOverlapsWithFrame * lint * fix * pass elementsMap to getElementsCorners * pass elementsMap to getEligibleElementsForBinding * pass elementsMap in bindOrUnbindSelectedElements and unbindLinearElements * pass elementsMap in elementsAreInFrameBounds,elementOverlapsWithFrame,isCursorInFrame,getElementsInResizingFrame * pass elementsMap in getElementsWithinSelection, getElementsCompletelyInFrame, isElementContainingFrame, getElementsInNewFrame * pass elementsMap to getElementWithTransformHandleType * pass elementsMap to getVisibleGaps, getMaximumGroups,getReferenceSnapPoints,snapDraggedElements * lint * pass elementsMap to bindTextToShapeAfterDuplication,bindLinearElementToElement,getTextBindableContainerAtPosition * revert changes for bindTextToShapeAfterDuplication
This commit is contained in:
parent
73bf50e8a8
commit
47f87f4ecb
36 changed files with 779 additions and 270 deletions
|
@ -5,6 +5,7 @@ import { getTransformHandles } from "../element/transformHandles";
|
|||
import { API } from "./helpers/api";
|
||||
import { KEYS } from "../keys";
|
||||
import { actionWrapTextInContainer } from "../actions/actionBoundText";
|
||||
import { arrayToMap } from "../utils";
|
||||
|
||||
const { h } = window;
|
||||
|
||||
|
@ -91,8 +92,12 @@ describe("element binding", () => {
|
|||
expect(arrow.startBinding?.elementId).toBe(rectLeft.id);
|
||||
expect(arrow.endBinding?.elementId).toBe(rectRight.id);
|
||||
|
||||
const rotation = getTransformHandles(arrow, h.state.zoom, "mouse")
|
||||
.rotation!;
|
||||
const rotation = getTransformHandles(
|
||||
arrow,
|
||||
h.state.zoom,
|
||||
arrayToMap(h.elements),
|
||||
"mouse",
|
||||
).rotation!;
|
||||
const rotationHandleX = rotation[0] + rotation[2] / 2;
|
||||
const rotationHandleY = rotation[1] + rotation[3] / 2;
|
||||
mouse.down(rotationHandleX, rotationHandleY);
|
||||
|
|
|
@ -27,7 +27,7 @@ import * as blob from "../data/blob";
|
|||
import { KEYS } from "../keys";
|
||||
import { getBoundTextElementPosition } from "../element/textElement";
|
||||
import { createPasteEvent } from "../clipboard";
|
||||
import { cloneJSON } from "../utils";
|
||||
import { arrayToMap, cloneJSON } from "../utils";
|
||||
|
||||
const { h } = window;
|
||||
const mouse = new Pointer("mouse");
|
||||
|
@ -194,9 +194,10 @@ const checkElementsBoundingBox = async (
|
|||
element2: ExcalidrawElement,
|
||||
toleranceInPx: number = 0,
|
||||
) => {
|
||||
const [x1, y1, x2, y2] = getElementAbsoluteCoords(element1);
|
||||
const elementsMap = arrayToMap([element1, element2]);
|
||||
const [x1, y1, x2, y2] = getElementAbsoluteCoords(element1, elementsMap);
|
||||
|
||||
const [x12, y12, x22, y22] = getElementAbsoluteCoords(element2);
|
||||
const [x12, y12, x22, y22] = getElementAbsoluteCoords(element2, elementsMap);
|
||||
|
||||
await waitFor(() => {
|
||||
// Check if width and height did not change
|
||||
|
@ -853,7 +854,11 @@ describe("mutliple elements", () => {
|
|||
h.app.actionManager.executeAction(actionFlipVertical);
|
||||
|
||||
const arrowText = h.elements[1] as ExcalidrawTextElementWithContainer;
|
||||
const arrowTextPos = getBoundTextElementPosition(arrow.get(), arrowText)!;
|
||||
const arrowTextPos = getBoundTextElementPosition(
|
||||
arrow.get(),
|
||||
arrowText,
|
||||
arrayToMap(h.elements),
|
||||
)!;
|
||||
const rectText = h.elements[3] as ExcalidrawTextElementWithContainer;
|
||||
|
||||
expect(arrow.x).toBeCloseTo(180);
|
||||
|
|
|
@ -32,6 +32,7 @@ import {
|
|||
import { getCommonBounds, getElementPointsCoords } from "../../element/bounds";
|
||||
import { rotatePoint } from "../../math";
|
||||
import { getTextEditor } from "../queries/dom";
|
||||
import { arrayToMap } from "../../utils";
|
||||
|
||||
const { h } = window;
|
||||
|
||||
|
@ -286,9 +287,12 @@ const transform = (
|
|||
let handleCoords: TransformHandle | undefined;
|
||||
|
||||
if (elements.length === 1) {
|
||||
handleCoords = getTransformHandles(elements[0], h.state.zoom, "mouse")[
|
||||
handle
|
||||
];
|
||||
handleCoords = getTransformHandles(
|
||||
elements[0],
|
||||
h.state.zoom,
|
||||
arrayToMap(h.elements),
|
||||
"mouse",
|
||||
)[handle];
|
||||
} else {
|
||||
const [x1, y1, x2, y2] = getCommonBounds(elements);
|
||||
const isFrameSelected = elements.some(isFrameLikeElement);
|
||||
|
|
|
@ -343,6 +343,8 @@ describe("Test Linear Elements", () => {
|
|||
});
|
||||
|
||||
it("should update all the midpoints when element position changed", async () => {
|
||||
const elementsMap = arrayToMap(h.elements);
|
||||
|
||||
createThreePointerLinearElement("line", {
|
||||
type: ROUNDNESS.PROPORTIONAL_RADIUS,
|
||||
});
|
||||
|
@ -351,7 +353,10 @@ describe("Test Linear Elements", () => {
|
|||
expect(line.points.length).toEqual(3);
|
||||
enterLineEditingMode(line);
|
||||
|
||||
const points = LinearElementEditor.getPointsGlobalCoordinates(line);
|
||||
const points = LinearElementEditor.getPointsGlobalCoordinates(
|
||||
line,
|
||||
elementsMap,
|
||||
);
|
||||
expect([line.x, line.y]).toEqual(points[0]);
|
||||
|
||||
const midPoints = LinearElementEditor.getEditorMidPoints(
|
||||
|
@ -465,7 +470,11 @@ describe("Test Linear Elements", () => {
|
|||
});
|
||||
|
||||
it("should update only the first segment midpoint when its point is dragged", async () => {
|
||||
const points = LinearElementEditor.getPointsGlobalCoordinates(line);
|
||||
const elementsMap = arrayToMap(h.elements);
|
||||
const points = LinearElementEditor.getPointsGlobalCoordinates(
|
||||
line,
|
||||
elementsMap,
|
||||
);
|
||||
const midPoints = LinearElementEditor.getEditorMidPoints(
|
||||
line,
|
||||
h.app.scene.getNonDeletedElementsMap(),
|
||||
|
@ -482,7 +491,10 @@ describe("Test Linear Elements", () => {
|
|||
);
|
||||
expect(renderStaticScene.mock.calls.length).toMatchInlineSnapshot(`8`);
|
||||
|
||||
const newPoints = LinearElementEditor.getPointsGlobalCoordinates(line);
|
||||
const newPoints = LinearElementEditor.getPointsGlobalCoordinates(
|
||||
line,
|
||||
elementsMap,
|
||||
);
|
||||
expect([newPoints[0][0], newPoints[0][1]]).toEqual([
|
||||
points[0][0] - delta,
|
||||
points[0][1] - delta,
|
||||
|
@ -499,7 +511,11 @@ describe("Test Linear Elements", () => {
|
|||
});
|
||||
|
||||
it("should hide midpoints in the segment when points moved close", async () => {
|
||||
const points = LinearElementEditor.getPointsGlobalCoordinates(line);
|
||||
const elementsMap = arrayToMap(h.elements);
|
||||
const points = LinearElementEditor.getPointsGlobalCoordinates(
|
||||
line,
|
||||
elementsMap,
|
||||
);
|
||||
const midPoints = LinearElementEditor.getEditorMidPoints(
|
||||
line,
|
||||
h.app.scene.getNonDeletedElementsMap(),
|
||||
|
@ -516,7 +532,10 @@ describe("Test Linear Elements", () => {
|
|||
);
|
||||
expect(renderStaticScene.mock.calls.length).toMatchInlineSnapshot(`8`);
|
||||
|
||||
const newPoints = LinearElementEditor.getPointsGlobalCoordinates(line);
|
||||
const newPoints = LinearElementEditor.getPointsGlobalCoordinates(
|
||||
line,
|
||||
elementsMap,
|
||||
);
|
||||
expect([newPoints[0][0], newPoints[0][1]]).toEqual([
|
||||
points[0][0] + delta,
|
||||
points[0][1] + delta,
|
||||
|
@ -535,7 +554,10 @@ describe("Test Linear Elements", () => {
|
|||
it("should remove the midpoint when one of the points in the segment is deleted", async () => {
|
||||
const line = h.elements[0] as ExcalidrawLinearElement;
|
||||
enterLineEditingMode(line);
|
||||
const points = LinearElementEditor.getPointsGlobalCoordinates(line);
|
||||
const points = LinearElementEditor.getPointsGlobalCoordinates(
|
||||
line,
|
||||
arrayToMap(h.elements),
|
||||
);
|
||||
|
||||
// dragging line from last segment midpoint
|
||||
drag(lastSegmentMidpoint, [
|
||||
|
@ -637,7 +659,11 @@ describe("Test Linear Elements", () => {
|
|||
});
|
||||
|
||||
it("should update all the midpoints when its point is dragged", async () => {
|
||||
const points = LinearElementEditor.getPointsGlobalCoordinates(line);
|
||||
const elementsMap = arrayToMap(h.elements);
|
||||
const points = LinearElementEditor.getPointsGlobalCoordinates(
|
||||
line,
|
||||
elementsMap,
|
||||
);
|
||||
const midPoints = LinearElementEditor.getEditorMidPoints(
|
||||
line,
|
||||
h.app.scene.getNonDeletedElementsMap(),
|
||||
|
@ -649,7 +675,10 @@ describe("Test Linear Elements", () => {
|
|||
// Drag from first point
|
||||
drag(hitCoords, [hitCoords[0] - delta, hitCoords[1] - delta]);
|
||||
|
||||
const newPoints = LinearElementEditor.getPointsGlobalCoordinates(line);
|
||||
const newPoints = LinearElementEditor.getPointsGlobalCoordinates(
|
||||
line,
|
||||
elementsMap,
|
||||
);
|
||||
expect([newPoints[0][0], newPoints[0][1]]).toEqual([
|
||||
points[0][0] - delta,
|
||||
points[0][1] - delta,
|
||||
|
@ -678,7 +707,11 @@ describe("Test Linear Elements", () => {
|
|||
});
|
||||
|
||||
it("should hide midpoints in the segment when points moved close", async () => {
|
||||
const points = LinearElementEditor.getPointsGlobalCoordinates(line);
|
||||
const elementsMap = arrayToMap(h.elements);
|
||||
const points = LinearElementEditor.getPointsGlobalCoordinates(
|
||||
line,
|
||||
elementsMap,
|
||||
);
|
||||
const midPoints = LinearElementEditor.getEditorMidPoints(
|
||||
line,
|
||||
h.app.scene.getNonDeletedElementsMap(),
|
||||
|
@ -695,7 +728,10 @@ describe("Test Linear Elements", () => {
|
|||
);
|
||||
expect(renderStaticScene.mock.calls.length).toMatchInlineSnapshot(`8`);
|
||||
|
||||
const newPoints = LinearElementEditor.getPointsGlobalCoordinates(line);
|
||||
const newPoints = LinearElementEditor.getPointsGlobalCoordinates(
|
||||
line,
|
||||
elementsMap,
|
||||
);
|
||||
expect([newPoints[0][0], newPoints[0][1]]).toEqual([
|
||||
points[0][0] + delta,
|
||||
points[0][1] + delta,
|
||||
|
@ -712,6 +748,8 @@ describe("Test Linear Elements", () => {
|
|||
});
|
||||
|
||||
it("should update all the midpoints when a point is deleted", async () => {
|
||||
const elementsMap = arrayToMap(h.elements);
|
||||
|
||||
drag(lastSegmentMidpoint, [
|
||||
lastSegmentMidpoint[0] + delta,
|
||||
lastSegmentMidpoint[1] + delta,
|
||||
|
@ -723,7 +761,10 @@ describe("Test Linear Elements", () => {
|
|||
h.app.scene.getNonDeletedElementsMap(),
|
||||
h.state,
|
||||
);
|
||||
const points = LinearElementEditor.getPointsGlobalCoordinates(line);
|
||||
const points = LinearElementEditor.getPointsGlobalCoordinates(
|
||||
line,
|
||||
elementsMap,
|
||||
);
|
||||
|
||||
// delete 3rd point
|
||||
deletePoint(points[2]);
|
||||
|
@ -837,6 +878,7 @@ describe("Test Linear Elements", () => {
|
|||
const position = LinearElementEditor.getBoundTextElementPosition(
|
||||
container,
|
||||
textElement,
|
||||
arrayToMap(h.elements),
|
||||
);
|
||||
expect(position).toMatchInlineSnapshot(`
|
||||
{
|
||||
|
@ -859,6 +901,7 @@ describe("Test Linear Elements", () => {
|
|||
const position = LinearElementEditor.getBoundTextElementPosition(
|
||||
container,
|
||||
textElement,
|
||||
arrayToMap(h.elements),
|
||||
);
|
||||
expect(position).toMatchInlineSnapshot(`
|
||||
{
|
||||
|
@ -893,6 +936,7 @@ describe("Test Linear Elements", () => {
|
|||
const position = LinearElementEditor.getBoundTextElementPosition(
|
||||
container,
|
||||
textElement,
|
||||
arrayToMap(h.elements),
|
||||
);
|
||||
expect(position).toMatchInlineSnapshot(`
|
||||
{
|
||||
|
@ -1012,8 +1056,13 @@ describe("Test Linear Elements", () => {
|
|||
);
|
||||
expect(container.width).toBe(70);
|
||||
expect(container.height).toBe(50);
|
||||
expect(getBoundTextElementPosition(container, textElement))
|
||||
.toMatchInlineSnapshot(`
|
||||
expect(
|
||||
getBoundTextElementPosition(
|
||||
container,
|
||||
textElement,
|
||||
arrayToMap(h.elements),
|
||||
),
|
||||
).toMatchInlineSnapshot(`
|
||||
{
|
||||
"x": 75,
|
||||
"y": 60,
|
||||
|
@ -1051,8 +1100,13 @@ describe("Test Linear Elements", () => {
|
|||
}
|
||||
`);
|
||||
|
||||
expect(getBoundTextElementPosition(container, textElement))
|
||||
.toMatchInlineSnapshot(`
|
||||
expect(
|
||||
getBoundTextElementPosition(
|
||||
container,
|
||||
textElement,
|
||||
arrayToMap(h.elements),
|
||||
),
|
||||
).toMatchInlineSnapshot(`
|
||||
{
|
||||
"x": 271.11716195150507,
|
||||
"y": 45,
|
||||
|
@ -1090,7 +1144,8 @@ describe("Test Linear Elements", () => {
|
|||
arrow,
|
||||
);
|
||||
expect(container.width).toBe(40);
|
||||
expect(getBoundTextElementPosition(container, textElement))
|
||||
const elementsMap = arrayToMap(h.elements);
|
||||
expect(getBoundTextElementPosition(container, textElement, elementsMap))
|
||||
.toMatchInlineSnapshot(`
|
||||
{
|
||||
"x": 25,
|
||||
|
@ -1102,7 +1157,10 @@ describe("Test Linear Elements", () => {
|
|||
collaboration made
|
||||
easy"
|
||||
`);
|
||||
const points = LinearElementEditor.getPointsGlobalCoordinates(container);
|
||||
const points = LinearElementEditor.getPointsGlobalCoordinates(
|
||||
container,
|
||||
elementsMap,
|
||||
);
|
||||
|
||||
// Drag from last point
|
||||
drag(points[1], [points[1][0] + 300, points[1][1]]);
|
||||
|
@ -1115,7 +1173,7 @@ describe("Test Linear Elements", () => {
|
|||
}
|
||||
`);
|
||||
|
||||
expect(getBoundTextElementPosition(container, textElement))
|
||||
expect(getBoundTextElementPosition(container, textElement, elementsMap))
|
||||
.toMatchInlineSnapshot(`
|
||||
{
|
||||
"x": 75,
|
||||
|
|
|
@ -13,6 +13,7 @@ import {
|
|||
import { UI, Pointer, Keyboard } from "./helpers/ui";
|
||||
import { KEYS } from "../keys";
|
||||
import { vi } from "vitest";
|
||||
import { arrayToMap } from "../utils";
|
||||
|
||||
// Unmount ReactDOM from root
|
||||
ReactDOM.unmountComponentAtNode(document.getElementById("root")!);
|
||||
|
@ -75,12 +76,13 @@ describe("move element", () => {
|
|||
const rectA = UI.createElement("rectangle", { size: 100 });
|
||||
const rectB = UI.createElement("rectangle", { x: 200, y: 0, size: 300 });
|
||||
const line = UI.createElement("line", { x: 110, y: 50, size: 80 });
|
||||
|
||||
const elementsMap = arrayToMap(h.elements);
|
||||
// bind line to two rectangles
|
||||
bindOrUnbindLinearElement(
|
||||
line.get() as NonDeleted<ExcalidrawLinearElement>,
|
||||
rectA.get() as ExcalidrawRectangleElement,
|
||||
rectB.get() as ExcalidrawRectangleElement,
|
||||
elementsMap,
|
||||
);
|
||||
|
||||
// select the second rectangles
|
||||
|
|
|
@ -13,6 +13,7 @@ import { API } from "./helpers/api";
|
|||
import { KEYS } from "../keys";
|
||||
import { isLinearElement } from "../element/typeChecks";
|
||||
import { LinearElementEditor } from "../element/linearElementEditor";
|
||||
import { arrayToMap } from "../utils";
|
||||
|
||||
ReactDOM.unmountComponentAtNode(document.getElementById("root")!);
|
||||
|
||||
|
@ -301,10 +302,12 @@ describe("arrow element", () => {
|
|||
],
|
||||
});
|
||||
const label = await UI.editText(arrow, "Hello");
|
||||
const elementsMap = arrayToMap(h.elements);
|
||||
UI.resize(arrow, "se", [50, 30]);
|
||||
let labelPos = LinearElementEditor.getBoundTextElementPosition(
|
||||
arrow,
|
||||
label,
|
||||
elementsMap,
|
||||
);
|
||||
|
||||
expect(labelPos.x + label.width / 2).toBeCloseTo(
|
||||
|
@ -317,7 +320,11 @@ describe("arrow element", () => {
|
|||
expect(label.fontSize).toEqual(20);
|
||||
|
||||
UI.resize(arrow, "w", [20, 0]);
|
||||
labelPos = LinearElementEditor.getBoundTextElementPosition(arrow, label);
|
||||
labelPos = LinearElementEditor.getBoundTextElementPosition(
|
||||
arrow,
|
||||
label,
|
||||
elementsMap,
|
||||
);
|
||||
|
||||
expect(labelPos.x + label.width / 2).toBeCloseTo(
|
||||
arrow.x + arrow.points[2][0],
|
||||
|
@ -743,15 +750,17 @@ describe("multiple selection", () => {
|
|||
const selectionTop = 20 - topArrowLabel.height / 2;
|
||||
const move = [80, 0] as [number, number];
|
||||
const scale = move[0] / selectionWidth + 1;
|
||||
|
||||
const elementsMap = arrayToMap(h.elements);
|
||||
UI.resize([topArrow.get(), bottomArrow.get()], "se", move);
|
||||
const topArrowLabelPos = LinearElementEditor.getBoundTextElementPosition(
|
||||
topArrow,
|
||||
topArrowLabel,
|
||||
elementsMap,
|
||||
);
|
||||
const bottomArrowLabelPos = LinearElementEditor.getBoundTextElementPosition(
|
||||
bottomArrow,
|
||||
bottomArrowLabel,
|
||||
elementsMap,
|
||||
);
|
||||
|
||||
expect(topArrow.x).toBeCloseTo(0);
|
||||
|
@ -944,12 +953,13 @@ describe("multiple selection", () => {
|
|||
const scaleX = move[0] / selectionWidth + 1;
|
||||
const scaleY = -scaleX;
|
||||
const lineOrigBounds = getBoundsFromPoints(line);
|
||||
|
||||
const elementsMap = arrayToMap(h.elements);
|
||||
UI.resize([line, image, rectangle, boundArrow], "se", move);
|
||||
const lineNewBounds = getBoundsFromPoints(line);
|
||||
const arrowLabelPos = LinearElementEditor.getBoundTextElementPosition(
|
||||
boundArrow,
|
||||
arrowLabel,
|
||||
elementsMap,
|
||||
);
|
||||
|
||||
expect(line.x).toBeCloseTo(60 * scaleX);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue