mirror of
https://github.com/excalidraw/excalidraw.git
synced 2025-05-03 10:00:07 -04:00
Bounds refactor and duplication removal
This commit is contained in:
parent
7b4e989d65
commit
91b6057d9c
28 changed files with 431 additions and 147 deletions
|
@ -1,8 +1,8 @@
|
|||
import type { Bounds } from "../excalidraw/element/bounds";
|
||||
import type { Bounds } from "../excalidraw/element/types";
|
||||
import { API } from "../excalidraw/tests/helpers/api";
|
||||
import {
|
||||
elementPartiallyOverlapsWithOrContainsBBox,
|
||||
elementsOverlappingBBox,
|
||||
elementPartiallyOverlapsWithOrContainsBounds,
|
||||
elementsOverlappingBounds,
|
||||
isElementInsideBBox,
|
||||
} from "./withinBounds";
|
||||
|
||||
|
@ -99,13 +99,13 @@ describe("elementPartiallyOverlapsWithOrContainsBBox()", () => {
|
|||
|
||||
// bbox contains element
|
||||
expect(
|
||||
elementPartiallyOverlapsWithOrContainsBBox(
|
||||
elementPartiallyOverlapsWithOrContainsBounds(
|
||||
makeElement(0, 0, 100, 100),
|
||||
bbox,
|
||||
),
|
||||
).toBe(true);
|
||||
expect(
|
||||
elementPartiallyOverlapsWithOrContainsBBox(
|
||||
elementPartiallyOverlapsWithOrContainsBounds(
|
||||
makeElement(10, 10, 90, 90),
|
||||
bbox,
|
||||
),
|
||||
|
@ -113,7 +113,7 @@ describe("elementPartiallyOverlapsWithOrContainsBBox()", () => {
|
|||
|
||||
// element contains bbox
|
||||
expect(
|
||||
elementPartiallyOverlapsWithOrContainsBBox(
|
||||
elementPartiallyOverlapsWithOrContainsBounds(
|
||||
makeElement(-10, -10, 110, 110),
|
||||
bbox,
|
||||
),
|
||||
|
@ -121,28 +121,28 @@ describe("elementPartiallyOverlapsWithOrContainsBBox()", () => {
|
|||
|
||||
// element overlaps bbox from top-left
|
||||
expect(
|
||||
elementPartiallyOverlapsWithOrContainsBBox(
|
||||
elementPartiallyOverlapsWithOrContainsBounds(
|
||||
makeElement(-10, -10, 100, 100),
|
||||
bbox,
|
||||
),
|
||||
).toBe(true);
|
||||
// element overlaps bbox from top-right
|
||||
expect(
|
||||
elementPartiallyOverlapsWithOrContainsBBox(
|
||||
elementPartiallyOverlapsWithOrContainsBounds(
|
||||
makeElement(90, -10, 100, 100),
|
||||
bbox,
|
||||
),
|
||||
).toBe(true);
|
||||
// element overlaps bbox from bottom-left
|
||||
expect(
|
||||
elementPartiallyOverlapsWithOrContainsBBox(
|
||||
elementPartiallyOverlapsWithOrContainsBounds(
|
||||
makeElement(-10, 90, 100, 100),
|
||||
bbox,
|
||||
),
|
||||
).toBe(true);
|
||||
// element overlaps bbox from bottom-right
|
||||
expect(
|
||||
elementPartiallyOverlapsWithOrContainsBBox(
|
||||
elementPartiallyOverlapsWithOrContainsBounds(
|
||||
makeElement(90, 90, 100, 100),
|
||||
bbox,
|
||||
),
|
||||
|
@ -154,7 +154,7 @@ describe("elementPartiallyOverlapsWithOrContainsBBox()", () => {
|
|||
|
||||
// outside diagonally
|
||||
expect(
|
||||
elementPartiallyOverlapsWithOrContainsBBox(
|
||||
elementPartiallyOverlapsWithOrContainsBounds(
|
||||
makeElement(110, 110, 100, 100),
|
||||
bbox,
|
||||
),
|
||||
|
@ -162,28 +162,28 @@ describe("elementPartiallyOverlapsWithOrContainsBBox()", () => {
|
|||
|
||||
// outside on the left
|
||||
expect(
|
||||
elementPartiallyOverlapsWithOrContainsBBox(
|
||||
elementPartiallyOverlapsWithOrContainsBounds(
|
||||
makeElement(-110, 10, 50, 50),
|
||||
bbox,
|
||||
),
|
||||
).toBe(false);
|
||||
// outside on the right
|
||||
expect(
|
||||
elementPartiallyOverlapsWithOrContainsBBox(
|
||||
elementPartiallyOverlapsWithOrContainsBounds(
|
||||
makeElement(110, 10, 50, 50),
|
||||
bbox,
|
||||
),
|
||||
).toBe(false);
|
||||
// outside on the top
|
||||
expect(
|
||||
elementPartiallyOverlapsWithOrContainsBBox(
|
||||
elementPartiallyOverlapsWithOrContainsBounds(
|
||||
makeElement(10, -110, 50, 50),
|
||||
bbox,
|
||||
),
|
||||
).toBe(false);
|
||||
// outside on the bottom
|
||||
expect(
|
||||
elementPartiallyOverlapsWithOrContainsBBox(
|
||||
elementPartiallyOverlapsWithOrContainsBounds(
|
||||
makeElement(10, 110, 50, 50),
|
||||
bbox,
|
||||
),
|
||||
|
@ -201,7 +201,7 @@ describe("elementsOverlappingBBox()", () => {
|
|||
const rectOverlappingTopLeft = makeElement(-10, -10, 50, 50);
|
||||
|
||||
expect(
|
||||
elementsOverlappingBBox({
|
||||
elementsOverlappingBounds({
|
||||
bounds: bbox,
|
||||
type: "overlap",
|
||||
elements: [
|
||||
|
@ -223,7 +223,7 @@ describe("elementsOverlappingBBox()", () => {
|
|||
const rectOverlappingTopLeft = makeElement(-10, -10, 50, 50);
|
||||
|
||||
expect(
|
||||
elementsOverlappingBBox({
|
||||
elementsOverlappingBounds({
|
||||
bounds: bbox,
|
||||
type: "contain",
|
||||
elements: [
|
||||
|
@ -245,7 +245,7 @@ describe("elementsOverlappingBBox()", () => {
|
|||
const rectOverlappingTopLeft = makeElement(-10, -10, 50, 50);
|
||||
|
||||
expect(
|
||||
elementsOverlappingBBox({
|
||||
elementsOverlappingBounds({
|
||||
bounds: bbox,
|
||||
type: "inside",
|
||||
elements: [
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import type {
|
||||
Bounds,
|
||||
ExcalidrawElement,
|
||||
ExcalidrawFreeDrawElement,
|
||||
ExcalidrawLinearElement,
|
||||
|
@ -11,7 +12,6 @@ import {
|
|||
isLinearElement,
|
||||
isTextElement,
|
||||
} from "../excalidraw/element/typeChecks";
|
||||
import type { Bounds } from "../excalidraw/element/bounds";
|
||||
import { getElementBounds } from "../excalidraw/element/bounds";
|
||||
import { arrayToMap } from "../excalidraw/utils";
|
||||
import type { LocalPoint } from "../math";
|
||||
|
@ -22,15 +22,10 @@ import {
|
|||
rangeInclusive,
|
||||
} from "../math";
|
||||
|
||||
type Element = NonDeletedExcalidrawElement;
|
||||
type Elements = readonly NonDeletedExcalidrawElement[];
|
||||
|
||||
type Points = readonly LocalPoint[];
|
||||
|
||||
/** @returns vertices relative to element's top-left [0,0] position */
|
||||
const getNonLinearElementRelativePoints = (
|
||||
element: Exclude<
|
||||
Element,
|
||||
NonDeletedExcalidrawElement,
|
||||
ExcalidrawLinearElement | ExcalidrawFreeDrawElement
|
||||
>,
|
||||
): [
|
||||
|
@ -56,14 +51,16 @@ const getNonLinearElementRelativePoints = (
|
|||
};
|
||||
|
||||
/** @returns vertices relative to element's top-left [0,0] position */
|
||||
const getElementRelativePoints = (element: ExcalidrawElement): Points => {
|
||||
const getElementRelativePoints = (
|
||||
element: ExcalidrawElement,
|
||||
): readonly LocalPoint[] => {
|
||||
if (isLinearElement(element) || isFreeDrawElement(element)) {
|
||||
return element.points;
|
||||
}
|
||||
return getNonLinearElementRelativePoints(element);
|
||||
};
|
||||
|
||||
const getMinMaxPoints = (points: Points) => {
|
||||
const getMinMaxPoints = (points: readonly LocalPoint[]) => {
|
||||
const ret = points.reduce(
|
||||
(limits, [x, y]) => {
|
||||
limits.minY = Math.min(limits.minY, y);
|
||||
|
@ -90,7 +87,7 @@ const getMinMaxPoints = (points: Points) => {
|
|||
return ret;
|
||||
};
|
||||
|
||||
const getRotatedBBox = (element: Element): Bounds => {
|
||||
const getRotatedBBox = (element: NonDeletedExcalidrawElement): Bounds => {
|
||||
const points = getElementRelativePoints(element);
|
||||
|
||||
const { cx, cy } = getMinMaxPoints(points);
|
||||
|
@ -110,7 +107,7 @@ const getRotatedBBox = (element: Element): Bounds => {
|
|||
};
|
||||
|
||||
export const isElementInsideBBox = (
|
||||
element: Element,
|
||||
element: NonDeletedExcalidrawElement,
|
||||
bbox: Bounds,
|
||||
eitherDirection = false,
|
||||
): boolean => {
|
||||
|
@ -138,8 +135,8 @@ export const isElementInsideBBox = (
|
|||
);
|
||||
};
|
||||
|
||||
export const elementPartiallyOverlapsWithOrContainsBBox = (
|
||||
element: Element,
|
||||
export const elementPartiallyOverlapsWithOrContainsBounds = (
|
||||
element: NonDeletedExcalidrawElement,
|
||||
bbox: Bounds,
|
||||
): boolean => {
|
||||
const elementBBox = getRotatedBBox(element);
|
||||
|
@ -158,13 +155,13 @@ export const elementPartiallyOverlapsWithOrContainsBBox = (
|
|||
);
|
||||
};
|
||||
|
||||
export const elementsOverlappingBBox = ({
|
||||
export const elementsOverlappingBounds = ({
|
||||
elements,
|
||||
bounds,
|
||||
type,
|
||||
errorMargin = 0,
|
||||
}: {
|
||||
elements: Elements;
|
||||
elements: readonly NonDeletedExcalidrawElement[];
|
||||
bounds: Bounds | ExcalidrawElement;
|
||||
/** safety offset. Defaults to 0. */
|
||||
errorMargin?: number;
|
||||
|
@ -194,7 +191,7 @@ export const elementsOverlappingBBox = ({
|
|||
|
||||
const isOverlaping =
|
||||
type === "overlap"
|
||||
? elementPartiallyOverlapsWithOrContainsBBox(element, adjustedBBox)
|
||||
? elementPartiallyOverlapsWithOrContainsBounds(element, adjustedBBox)
|
||||
: type === "inside"
|
||||
? isElementInsideBBox(element, adjustedBBox)
|
||||
: isElementInsideBBox(element, adjustedBBox, true);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue