fix: make bounds independent of scene (#7679)

* fix: make bounds independent of scene

* pass only elements to getCommonBounds

* lint

* pass elementsMap to getVisibleAndNonSelectedElements
This commit is contained in:
Aakansha Doshi
2024-02-19 19:39:14 +05:30
committed by GitHub
parent 9013c84524
commit 79d9dc2f8f
11 changed files with 106 additions and 59 deletions
+23 -27
View File
@@ -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 {