refactor: decoupling global Scene state part-1 (#7577)

This commit is contained in:
David Luzar 2024-01-22 00:23:02 +01:00 committed by GitHub
parent 740a165452
commit 0415c616b1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
31 changed files with 630 additions and 384 deletions

View file

@ -15,6 +15,7 @@ import {
ExcalidrawElement,
ExcalidrawTextElementWithContainer,
ExcalidrawImageElement,
ElementsMap,
} from "./types";
import type { Mutable } from "../utility-types";
import {
@ -41,7 +42,7 @@ import {
MaybeTransformHandleType,
TransformHandleDirection,
} from "./transformHandles";
import { AppState, Point, PointerDownState } from "../types";
import { Point, PointerDownState } from "../types";
import Scene from "../scene/Scene";
import {
getApproxMinLineWidth,
@ -68,10 +69,10 @@ export const normalizeAngle = (angle: number): number => {
// Returns true when transform (resizing/rotation) happened
export const transformElements = (
pointerDownState: PointerDownState,
originalElements: PointerDownState["originalElements"],
transformHandleType: MaybeTransformHandleType,
selectedElements: readonly NonDeletedExcalidrawElement[],
resizeArrowDirection: "origin" | "end",
elementsMap: ElementsMap,
shouldRotateWithDiscreteAngle: boolean,
shouldResizeFromCenter: boolean,
shouldMaintainAspectRatio: boolean,
@ -79,7 +80,6 @@ export const transformElements = (
pointerY: number,
centerX: number,
centerY: number,
appState: AppState,
) => {
if (selectedElements.length === 1) {
const [element] = selectedElements;
@ -89,7 +89,6 @@ export const transformElements = (
pointerX,
pointerY,
shouldRotateWithDiscreteAngle,
pointerDownState.originalElements,
);
updateBoundElements(element);
} else if (
@ -101,6 +100,7 @@ export const transformElements = (
) {
resizeSingleTextElement(
element,
elementsMap,
transformHandleType,
shouldResizeFromCenter,
pointerX,
@ -109,9 +109,10 @@ export const transformElements = (
updateBoundElements(element);
} else if (transformHandleType) {
resizeSingleElement(
pointerDownState.originalElements,
originalElements,
shouldMaintainAspectRatio,
element,
elementsMap,
transformHandleType,
shouldResizeFromCenter,
pointerX,
@ -123,7 +124,7 @@ export const transformElements = (
} else if (selectedElements.length > 1) {
if (transformHandleType === "rotation") {
rotateMultipleElements(
pointerDownState,
originalElements,
selectedElements,
pointerX,
pointerY,
@ -139,8 +140,9 @@ export const transformElements = (
transformHandleType === "se"
) {
resizeMultipleElements(
pointerDownState,
originalElements,
selectedElements,
elementsMap,
transformHandleType,
shouldResizeFromCenter,
pointerX,
@ -157,7 +159,6 @@ const rotateSingleElement = (
pointerX: number,
pointerY: number,
shouldRotateWithDiscreteAngle: boolean,
originalElements: Map<string, NonDeleted<ExcalidrawElement>>,
) => {
const [x1, y1, x2, y2] = getElementAbsoluteCoords(element);
const cx = (x1 + x2) / 2;
@ -207,6 +208,7 @@ const rescalePointsInElement = (
const measureFontSizeFromWidth = (
element: NonDeleted<ExcalidrawTextElement>,
elementsMap: ElementsMap,
nextWidth: number,
nextHeight: number,
): { size: number; baseline: number } | null => {
@ -215,7 +217,7 @@ const measureFontSizeFromWidth = (
const hasContainer = isBoundToContainer(element);
if (hasContainer) {
const container = getContainerElement(element);
const container = getContainerElement(element, elementsMap);
if (container) {
width = getBoundTextMaxWidth(container);
}
@ -257,6 +259,7 @@ const getSidesForTransformHandle = (
const resizeSingleTextElement = (
element: NonDeleted<ExcalidrawTextElement>,
elementsMap: ElementsMap,
transformHandleType: "nw" | "ne" | "sw" | "se",
shouldResizeFromCenter: boolean,
pointerX: number,
@ -303,7 +306,12 @@ const resizeSingleTextElement = (
if (scale > 0) {
const nextWidth = element.width * scale;
const nextHeight = element.height * scale;
const metrics = measureFontSizeFromWidth(element, nextWidth, nextHeight);
const metrics = measureFontSizeFromWidth(
element,
elementsMap,
nextWidth,
nextHeight,
);
if (metrics === null) {
return;
}
@ -342,6 +350,7 @@ export const resizeSingleElement = (
originalElements: PointerDownState["originalElements"],
shouldMaintainAspectRatio: boolean,
element: NonDeletedExcalidrawElement,
elementsMap: ElementsMap,
transformHandleDirection: TransformHandleDirection,
shouldResizeFromCenter: boolean,
pointerX: number,
@ -448,6 +457,7 @@ export const resizeSingleElement = (
const nextFont = measureFontSizeFromWidth(
boundTextElement,
elementsMap,
getBoundTextMaxWidth(updatedElement),
getBoundTextMaxHeight(updatedElement, boundTextElement),
);
@ -637,8 +647,9 @@ export const resizeSingleElement = (
};
export const resizeMultipleElements = (
pointerDownState: PointerDownState,
originalElements: PointerDownState["originalElements"],
selectedElements: readonly NonDeletedExcalidrawElement[],
elementsMap: ElementsMap,
transformHandleType: "nw" | "ne" | "sw" | "se",
shouldResizeFromCenter: boolean,
pointerX: number,
@ -658,7 +669,7 @@ export const resizeMultipleElements = (
}[],
element,
) => {
const origElement = pointerDownState.originalElements.get(element.id);
const origElement = originalElements.get(element.id);
if (origElement) {
acc.push({ orig: origElement, latest: element });
}
@ -679,7 +690,7 @@ export const resizeMultipleElements = (
if (!textId) {
return acc;
}
const text = pointerDownState.originalElements.get(textId) ?? null;
const text = originalElements.get(textId) ?? null;
if (!isBoundToContainer(text)) {
return acc;
}
@ -825,7 +836,12 @@ export const resizeMultipleElements = (
}
if (isTextElement(orig)) {
const metrics = measureFontSizeFromWidth(orig, width, height);
const metrics = measureFontSizeFromWidth(
orig,
elementsMap,
width,
height,
);
if (!metrics) {
return;
}
@ -833,7 +849,7 @@ export const resizeMultipleElements = (
update.baseline = metrics.baseline;
}
const boundTextElement = pointerDownState.originalElements.get(
const boundTextElement = originalElements.get(
getBoundTextElementId(orig) ?? "",
) as ExcalidrawTextElementWithContainer | undefined;
@ -884,7 +900,7 @@ export const resizeMultipleElements = (
};
const rotateMultipleElements = (
pointerDownState: PointerDownState,
originalElements: PointerDownState["originalElements"],
elements: readonly NonDeletedExcalidrawElement[],
pointerX: number,
pointerY: number,
@ -906,8 +922,7 @@ const rotateMultipleElements = (
const cx = (x1 + x2) / 2;
const cy = (y1 + y2) / 2;
const origAngle =
pointerDownState.originalElements.get(element.id)?.angle ??
element.angle;
originalElements.get(element.id)?.angle ?? element.angle;
const [rotatedCX, rotatedCY] = rotate(
cx,
cy,