|
@@ -5,7 +5,6 @@ import {
|
|
|
ExcalidrawFreeDrawElement,
|
|
|
NonDeleted,
|
|
|
ExcalidrawTextElementWithContainer,
|
|
|
- ElementsMapOrArray,
|
|
|
ElementsMap,
|
|
|
} from "./types";
|
|
|
import { distance2d, rotate, rotatePoint } from "../math";
|
|
@@ -25,7 +24,7 @@ import { getBoundTextElement, getContainerElement } from "./textElement";
|
|
|
import { LinearElementEditor } from "./linearElementEditor";
|
|
|
import { Mutable } from "../utility-types";
|
|
|
import { ShapeCache } from "../scene/ShapeCache";
|
|
|
-import Scene from "../scene/Scene";
|
|
|
+import { arrayToMap } from "../utils";
|
|
|
|
|
|
export type RectangleBox = {
|
|
|
x: number;
|
|
@@ -63,7 +62,7 @@ export class ElementBounds {
|
|
|
}
|
|
|
>();
|
|
|
|
|
|
- static getBounds(element: ExcalidrawElement) {
|
|
|
+ static getBounds(element: ExcalidrawElement, elementsMap: ElementsMap) {
|
|
|
const cachedBounds = ElementBounds.boundsCache.get(element);
|
|
|
|
|
|
if (
|
|
@@ -75,23 +74,12 @@ export class ElementBounds {
|
|
|
) {
|
|
|
return cachedBounds.bounds;
|
|
|
}
|
|
|
- const scene = Scene.getScene(element);
|
|
|
- const bounds = ElementBounds.calculateBounds(
|
|
|
- element,
|
|
|
- scene?.getNonDeletedElementsMap() || new Map(),
|
|
|
- );
|
|
|
+ const bounds = ElementBounds.calculateBounds(element, elementsMap);
|
|
|
|
|
|
- // hack to ensure that downstream checks could retrieve element Scene
|
|
|
- // so as to have correctly calculated bounds
|
|
|
- // FIXME remove when we get rid of all the id:Scene / element:Scene mapping
|
|
|
- const shouldCache = !!scene;
|
|
|
-
|
|
|
- if (shouldCache) {
|
|
|
- ElementBounds.boundsCache.set(element, {
|
|
|
- version: element.version,
|
|
|
- bounds,
|
|
|
- });
|
|
|
- }
|
|
|
+ ElementBounds.boundsCache.set(element, {
|
|
|
+ version: element.version,
|
|
|
+ bounds,
|
|
|
+ });
|
|
|
|
|
|
return bounds;
|
|
|
}
|
|
@@ -748,11 +736,17 @@ const getLinearElementRotatedBounds = (
|
|
|
return coords;
|
|
|
};
|
|
|
|
|
|
-export const getElementBounds = (element: ExcalidrawElement): Bounds => {
|
|
|
- return ElementBounds.getBounds(element);
|
|
|
+export const getElementBounds = (
|
|
|
+ element: ExcalidrawElement,
|
|
|
+ elementsMap: ElementsMap,
|
|
|
+): Bounds => {
|
|
|
+ return ElementBounds.getBounds(element, elementsMap);
|
|
|
};
|
|
|
-export const getCommonBounds = (elements: ElementsMapOrArray): Bounds => {
|
|
|
- if ("size" in elements ? !elements.size : !elements.length) {
|
|
|
+
|
|
|
+export const getCommonBounds = (
|
|
|
+ elements: readonly ExcalidrawElement[],
|
|
|
+): Bounds => {
|
|
|
+ if (!elements.length) {
|
|
|
return [0, 0, 0, 0];
|
|
|
}
|
|
|
|
|
@@ -761,8 +755,10 @@ export const getCommonBounds = (elements: ElementsMapOrArray): Bounds => {
|
|
|
let minY = Infinity;
|
|
|
let maxY = -Infinity;
|
|
|
|
|
|
+ const elementsMap = arrayToMap(elements);
|
|
|
+
|
|
|
elements.forEach((element) => {
|
|
|
- const [x1, y1, x2, y2] = getElementBounds(element);
|
|
|
+ const [x1, y1, x2, y2] = getElementBounds(element, elementsMap);
|
|
|
minX = Math.min(minX, x1);
|
|
|
minY = Math.min(minY, y1);
|
|
|
maxX = Math.max(maxX, x2);
|
|
@@ -868,9 +864,9 @@ export const getClosestElementBounds = (
|
|
|
|
|
|
let minDistance = Infinity;
|
|
|
let closestElement = elements[0];
|
|
|
-
|
|
|
+ const elementsMap = arrayToMap(elements);
|
|
|
elements.forEach((element) => {
|
|
|
- const [x1, y1, x2, y2] = getElementBounds(element);
|
|
|
+ const [x1, y1, x2, y2] = getElementBounds(element, elementsMap);
|
|
|
const distance = distance2d((x1 + x2) / 2, (y1 + y2) / 2, from.x, from.y);
|
|
|
|
|
|
if (distance < minDistance) {
|
|
@@ -879,7 +875,7 @@ export const getClosestElementBounds = (
|
|
|
}
|
|
|
});
|
|
|
|
|
|
- return getElementBounds(closestElement);
|
|
|
+ return getElementBounds(closestElement, elementsMap);
|
|
|
};
|
|
|
|
|
|
export interface BoundingBox {
|