mirror of
https://github.com/excalidraw/excalidraw.git
synced 2025-05-03 10:00:07 -04:00
fix: When moving a frame through the stats inputs or drags move along its children (#9433)
Some checks failed
Tests / test (push) Failing after 1m9s
Some checks failed
Tests / test (push) Failing after 1m9s
Co-authored-by: Mark Tolmacs <mark@lazycat.hu>
This commit is contained in:
parent
192c4e7658
commit
6e655cdb24
3 changed files with 72 additions and 6 deletions
|
@ -10,7 +10,12 @@ import type { ElementsMap, ExcalidrawElement } from "@excalidraw/element/types";
|
||||||
import type Scene from "@excalidraw/element/Scene";
|
import type Scene from "@excalidraw/element/Scene";
|
||||||
|
|
||||||
import StatsDragInput from "./DragInput";
|
import StatsDragInput from "./DragInput";
|
||||||
import { getAtomicUnits, getStepSizedValue, isPropertyEditable } from "./utils";
|
import {
|
||||||
|
getAtomicUnits,
|
||||||
|
getStepSizedValue,
|
||||||
|
isPropertyEditable,
|
||||||
|
STEP_SIZE,
|
||||||
|
} from "./utils";
|
||||||
import { getElementsInAtomicUnit, moveElement } from "./utils";
|
import { getElementsInAtomicUnit, moveElement } from "./utils";
|
||||||
|
|
||||||
import type { DragInputCallbackType } from "./DragInput";
|
import type { DragInputCallbackType } from "./DragInput";
|
||||||
|
@ -26,8 +31,6 @@ interface MultiPositionProps {
|
||||||
appState: AppState;
|
appState: AppState;
|
||||||
}
|
}
|
||||||
|
|
||||||
const STEP_SIZE = 10;
|
|
||||||
|
|
||||||
const moveElements = (
|
const moveElements = (
|
||||||
property: MultiPositionProps["property"],
|
property: MultiPositionProps["property"],
|
||||||
changeInTopX: number,
|
changeInTopX: number,
|
||||||
|
|
|
@ -11,7 +11,7 @@ import type { ElementsMap, ExcalidrawElement } from "@excalidraw/element/types";
|
||||||
import type Scene from "@excalidraw/element/Scene";
|
import type Scene from "@excalidraw/element/Scene";
|
||||||
|
|
||||||
import StatsDragInput from "./DragInput";
|
import StatsDragInput from "./DragInput";
|
||||||
import { getStepSizedValue, moveElement } from "./utils";
|
import { getStepSizedValue, moveElement, STEP_SIZE } from "./utils";
|
||||||
|
|
||||||
import type { DragInputCallbackType } from "./DragInput";
|
import type { DragInputCallbackType } from "./DragInput";
|
||||||
import type { AppState } from "../../types";
|
import type { AppState } from "../../types";
|
||||||
|
@ -24,8 +24,6 @@ interface PositionProps {
|
||||||
appState: AppState;
|
appState: AppState;
|
||||||
}
|
}
|
||||||
|
|
||||||
const STEP_SIZE = 10;
|
|
||||||
|
|
||||||
const handlePositionChange: DragInputCallbackType<"x" | "y"> = ({
|
const handlePositionChange: DragInputCallbackType<"x" | "y"> = ({
|
||||||
accumulatedChange,
|
accumulatedChange,
|
||||||
instantChange,
|
instantChange,
|
||||||
|
|
|
@ -12,6 +12,8 @@ import {
|
||||||
isInGroup,
|
isInGroup,
|
||||||
} from "@excalidraw/element/groups";
|
} from "@excalidraw/element/groups";
|
||||||
|
|
||||||
|
import { getFrameChildren } from "@excalidraw/element/frame";
|
||||||
|
|
||||||
import type { Radians } from "@excalidraw/math";
|
import type { Radians } from "@excalidraw/math";
|
||||||
|
|
||||||
import type {
|
import type {
|
||||||
|
@ -36,6 +38,7 @@ export type StatsInputProperty =
|
||||||
| "gridStep";
|
| "gridStep";
|
||||||
|
|
||||||
export const SMALLEST_DELTA = 0.01;
|
export const SMALLEST_DELTA = 0.01;
|
||||||
|
export const STEP_SIZE = 10;
|
||||||
|
|
||||||
export const isPropertyEditable = (
|
export const isPropertyEditable = (
|
||||||
element: ExcalidrawElement,
|
element: ExcalidrawElement,
|
||||||
|
@ -169,6 +172,68 @@ export const moveElement = (
|
||||||
{ informMutation: shouldInformMutation, isDragging: false },
|
{ informMutation: shouldInformMutation, isDragging: false },
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isFrameLikeElement(originalElement)) {
|
||||||
|
const originalChildren = getFrameChildren(
|
||||||
|
originalElementsMap,
|
||||||
|
originalElement.id,
|
||||||
|
);
|
||||||
|
originalChildren.forEach((child) => {
|
||||||
|
const latestChildElement = elementsMap.get(child.id);
|
||||||
|
|
||||||
|
if (!latestChildElement) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const [childCX, childCY] = [
|
||||||
|
child.x + child.width / 2,
|
||||||
|
child.y + child.height / 2,
|
||||||
|
];
|
||||||
|
const [childTopLeftX, childTopLeftY] = pointRotateRads(
|
||||||
|
pointFrom(child.x, child.y),
|
||||||
|
pointFrom(childCX, childCY),
|
||||||
|
child.angle,
|
||||||
|
);
|
||||||
|
|
||||||
|
const childNewTopLeftX = Math.round(childTopLeftX + changeInX);
|
||||||
|
const childNewTopLeftY = Math.round(childTopLeftY + changeInY);
|
||||||
|
|
||||||
|
const [childX, childY] = pointRotateRads(
|
||||||
|
pointFrom(childNewTopLeftX, childNewTopLeftY),
|
||||||
|
pointFrom(childCX + changeInX, childCY + changeInY),
|
||||||
|
-child.angle as Radians,
|
||||||
|
);
|
||||||
|
|
||||||
|
scene.mutateElement(
|
||||||
|
latestChildElement,
|
||||||
|
{
|
||||||
|
x: childX,
|
||||||
|
y: childY,
|
||||||
|
},
|
||||||
|
{ informMutation: shouldInformMutation, isDragging: false },
|
||||||
|
);
|
||||||
|
updateBindings(latestChildElement, scene, {
|
||||||
|
simultaneouslyUpdated: originalChildren,
|
||||||
|
});
|
||||||
|
|
||||||
|
const boundTextElement = getBoundTextElement(
|
||||||
|
latestChildElement,
|
||||||
|
originalElementsMap,
|
||||||
|
);
|
||||||
|
if (boundTextElement) {
|
||||||
|
const latestBoundTextElement = elementsMap.get(boundTextElement.id);
|
||||||
|
latestBoundTextElement &&
|
||||||
|
scene.mutateElement(
|
||||||
|
latestBoundTextElement,
|
||||||
|
{
|
||||||
|
x: boundTextElement.x + changeInX,
|
||||||
|
y: boundTextElement.y + changeInY,
|
||||||
|
},
|
||||||
|
{ informMutation: shouldInformMutation, isDragging: false },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getAtomicUnits = (
|
export const getAtomicUnits = (
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue