resize linear & freedraw

This commit is contained in:
Ryan Di 2024-06-04 19:34:17 +08:00
parent 09e249ae57
commit be65ac7f22
3 changed files with 63 additions and 57 deletions

View File

@ -3,6 +3,7 @@ import DragInput from "./DragInput";
import type { DragInputCallbackType } from "./DragInput";
import { getStepSizedValue, isPropertyEditable } from "./utils";
import { mutateElement } from "../../element/mutateElement";
import { rescalePointsInElement } from "../../element/resizeElements";
interface DimensionDragInputProps {
property: "width" | "height";
@ -50,6 +51,28 @@ export const newOrigin = (
};
};
const getResizedUpdates = (
nextWidth: number,
nextHeight: number,
latestState: ExcalidrawElement,
stateAtStart: ExcalidrawElement,
) => {
return {
...newOrigin(
latestState.x,
latestState.y,
latestState.width,
latestState.height,
nextWidth,
nextHeight,
latestState.angle,
),
width: nextWidth,
height: nextHeight,
...rescalePointsInElement(stateAtStart, nextWidth, nextHeight, true),
};
};
const DimensionDragInput = ({ property, element }: DimensionDragInputProps) => {
const handleDimensionChange: DragInputCallbackType = (
accumulatedChange,
@ -83,19 +106,10 @@ const DimensionDragInput = ({ property, element }: DimensionDragInputProps) => {
0,
);
mutateElement(element, {
...newOrigin(
element.x,
element.y,
element.width,
element.height,
nextWidth,
nextHeight,
element.angle,
),
width: nextWidth,
height: nextHeight,
});
mutateElement(
element,
getResizedUpdates(nextWidth, nextHeight, element, _stateAtStart),
);
return;
}
const changeInWidth = property === "width" ? accumulatedChange : 0;
@ -127,19 +141,10 @@ const DimensionDragInput = ({ property, element }: DimensionDragInputProps) => {
}
}
mutateElement(element, {
width: nextWidth,
height: nextHeight,
...newOrigin(
_stateAtStart.x,
_stateAtStart.y,
_stateAtStart.width,
_stateAtStart.height,
nextWidth,
nextHeight,
_stateAtStart.angle,
),
});
mutateElement(
element,
getResizedUpdates(nextWidth, nextHeight, element, _stateAtStart),
);
}
};

View File

@ -1,5 +1,6 @@
import { getCommonBounds } from "../../element";
import { mutateElement } from "../../element/mutateElement";
import { rescalePointsInElement } from "../../element/resizeElements";
import type { ExcalidrawElement } from "../../element/types";
import DragInput from "./DragInput";
import type { DragInputCallbackType } from "./DragInput";
@ -12,6 +13,28 @@ interface MultiDimensionProps {
const STEP_SIZE = 10;
const getResizedUpdates = (
anchorX: number,
anchorY: number,
scale: number,
stateAtStart: ExcalidrawElement,
) => {
const offsetX = stateAtStart.x - anchorX;
const offsetY = stateAtStart.y - anchorY;
const nextWidth = stateAtStart.width * scale;
const nextHeight = stateAtStart.height * scale;
const x = anchorX + offsetX * scale;
const y = anchorY + offsetY * scale;
return {
width: nextWidth,
height: nextHeight,
x,
y,
...rescalePointsInElement(stateAtStart, nextWidth, nextHeight, false),
};
};
const MultiDimension = ({ property, elements }: MultiDimensionProps) => {
const handleDimensionChange: DragInputCallbackType = (
accumulatedChange,
@ -43,21 +66,9 @@ const MultiDimension = ({ property, elements }: MultiDimensionProps) => {
// it should never happen that element and origElement are different
// but check just in case
if (element.id === origElement.id) {
const offsetX = origElement.x - anchorX;
const offsetY = origElement.y - anchorY;
const nextWidth = origElement.width * scale;
const nextHeight = origElement.height * scale;
const x = anchorX + offsetX * scale;
const y = anchorY + offsetY * scale;
mutateElement(
element,
{
width: nextWidth,
height: nextHeight,
x,
y,
},
getResizedUpdates(anchorX, anchorY, scale, origElement),
i === stateAtStart.length - 1,
);
}
@ -105,23 +116,13 @@ const MultiDimension = ({ property, elements }: MultiDimensionProps) => {
const element = elements[i];
const origElement = stateAtStart[i];
const offsetX = origElement.x - anchorX;
const offsetY = origElement.y - anchorY;
const nextWidth = origElement.width * scale;
const nextHeight = origElement.height * scale;
const x = anchorX + offsetX * scale;
const y = anchorY + offsetY * scale;
mutateElement(
element,
{
width: nextWidth,
height: nextHeight,
x,
y,
},
i === stateAtStart.length - 1,
);
if (element.id === origElement.id) {
mutateElement(
element,
getResizedUpdates(anchorX, anchorY, scale, origElement),
i === stateAtStart.length - 1,
);
}
i++;
}
};

View File

@ -182,7 +182,7 @@ const rotateSingleElement = (
}
};
const rescalePointsInElement = (
export const rescalePointsInElement = (
element: NonDeletedExcalidrawElement,
width: number,
height: number,