|
@@ -1,7 +1,12 @@
|
|
|
-import { getCommonBounds } from "../../element";
|
|
|
+import { getCommonBounds, isTextElement } from "../../element";
|
|
|
+import { updateBoundElements } from "../../element/binding";
|
|
|
import { mutateElement } from "../../element/mutateElement";
|
|
|
import { rescalePointsInElement } from "../../element/resizeElements";
|
|
|
-import type { ExcalidrawElement } from "../../element/types";
|
|
|
+import {
|
|
|
+ getBoundTextElement,
|
|
|
+ handleBindTextResize,
|
|
|
+} from "../../element/textElement";
|
|
|
+import type { ElementsMap, ExcalidrawElement } from "../../element/types";
|
|
|
import DragInput from "./DragInput";
|
|
|
import type { DragInputCallbackType } from "./DragInput";
|
|
|
import { getStepSizedValue } from "./utils";
|
|
@@ -9,6 +14,7 @@ import { getStepSizedValue } from "./utils";
|
|
|
interface MultiDimensionProps {
|
|
|
property: "width" | "height";
|
|
|
elements: ExcalidrawElement[];
|
|
|
+ elementsMap: ElementsMap;
|
|
|
}
|
|
|
|
|
|
const STEP_SIZE = 10;
|
|
@@ -32,18 +38,66 @@ const getResizedUpdates = (
|
|
|
x,
|
|
|
y,
|
|
|
...rescalePointsInElement(stateAtStart, nextWidth, nextHeight, false),
|
|
|
+ ...(isTextElement(stateAtStart)
|
|
|
+ ? { fontSize: stateAtStart.fontSize * scale }
|
|
|
+ : {}),
|
|
|
};
|
|
|
};
|
|
|
|
|
|
-const MultiDimension = ({ property, elements }: MultiDimensionProps) => {
|
|
|
- const handleDimensionChange: DragInputCallbackType = (
|
|
|
+const resizeElement = (
|
|
|
+ anchorX: number,
|
|
|
+ anchorY: number,
|
|
|
+ property: MultiDimensionProps["property"],
|
|
|
+ scale: number,
|
|
|
+ latestElement: ExcalidrawElement,
|
|
|
+ origElement: ExcalidrawElement,
|
|
|
+ elementsMap: ElementsMap,
|
|
|
+ originalElementsMap: ElementsMap,
|
|
|
+ shouldInformMutation: boolean,
|
|
|
+) => {
|
|
|
+ const updates = getResizedUpdates(anchorX, anchorY, scale, origElement);
|
|
|
+
|
|
|
+ mutateElement(latestElement, updates, shouldInformMutation);
|
|
|
+ const boundTextElement = getBoundTextElement(
|
|
|
+ origElement,
|
|
|
+ originalElementsMap,
|
|
|
+ );
|
|
|
+ if (boundTextElement) {
|
|
|
+ const newFontSize = boundTextElement.fontSize * scale;
|
|
|
+ updateBoundElements(latestElement, elementsMap, {
|
|
|
+ newSize: { width: updates.width, height: updates.height },
|
|
|
+ });
|
|
|
+ const latestBoundTextElement = elementsMap.get(boundTextElement.id);
|
|
|
+ if (latestBoundTextElement && isTextElement(latestBoundTextElement)) {
|
|
|
+ mutateElement(
|
|
|
+ latestBoundTextElement,
|
|
|
+ {
|
|
|
+ fontSize: newFontSize,
|
|
|
+ },
|
|
|
+ shouldInformMutation,
|
|
|
+ );
|
|
|
+ handleBindTextResize(
|
|
|
+ latestElement,
|
|
|
+ elementsMap,
|
|
|
+ property === "width" ? "e" : "s",
|
|
|
+ true,
|
|
|
+ );
|
|
|
+ }
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+const MultiDimension = ({
|
|
|
+ property,
|
|
|
+ elements,
|
|
|
+ elementsMap,
|
|
|
+}: MultiDimensionProps) => {
|
|
|
+ const handleDimensionChange: DragInputCallbackType = ({
|
|
|
accumulatedChange,
|
|
|
- instantChange,
|
|
|
stateAtStart,
|
|
|
- shouldKeepAspectRatio,
|
|
|
+ originalElementsMap,
|
|
|
shouldChangeByStepSize,
|
|
|
nextValue,
|
|
|
- ) => {
|
|
|
+ }) => {
|
|
|
const [x1, y1, x2, y2] = getCommonBounds(stateAtStart);
|
|
|
const initialWidth = x2 - x1;
|
|
|
const initialHeight = y2 - y1;
|
|
@@ -60,15 +114,21 @@ const MultiDimension = ({ property, elements }: MultiDimensionProps) => {
|
|
|
|
|
|
let i = 0;
|
|
|
while (i < stateAtStart.length) {
|
|
|
- const element = elements[i];
|
|
|
+ const latestElement = elements[i];
|
|
|
const origElement = stateAtStart[i];
|
|
|
|
|
|
// it should never happen that element and origElement are different
|
|
|
// but check just in case
|
|
|
- if (element.id === origElement.id) {
|
|
|
- mutateElement(
|
|
|
- element,
|
|
|
- getResizedUpdates(anchorX, anchorY, scale, origElement),
|
|
|
+ if (latestElement.id === origElement.id) {
|
|
|
+ resizeElement(
|
|
|
+ anchorX,
|
|
|
+ anchorY,
|
|
|
+ property,
|
|
|
+ scale,
|
|
|
+ latestElement,
|
|
|
+ origElement,
|
|
|
+ elementsMap,
|
|
|
+ originalElementsMap,
|
|
|
i === stateAtStart.length - 1,
|
|
|
);
|
|
|
}
|
|
@@ -113,13 +173,19 @@ const MultiDimension = ({ property, elements }: MultiDimensionProps) => {
|
|
|
|
|
|
let i = 0;
|
|
|
while (i < stateAtStart.length) {
|
|
|
- const element = elements[i];
|
|
|
+ const latestElement = elements[i];
|
|
|
const origElement = stateAtStart[i];
|
|
|
|
|
|
- if (element.id === origElement.id) {
|
|
|
- mutateElement(
|
|
|
- element,
|
|
|
- getResizedUpdates(anchorX, anchorY, scale, origElement),
|
|
|
+ if (latestElement.id === origElement.id) {
|
|
|
+ resizeElement(
|
|
|
+ anchorX,
|
|
|
+ anchorY,
|
|
|
+ property,
|
|
|
+ scale,
|
|
|
+ latestElement,
|
|
|
+ origElement,
|
|
|
+ elementsMap,
|
|
|
+ originalElementsMap,
|
|
|
i === stateAtStart.length - 1,
|
|
|
);
|
|
|
}
|