mirror of
https://github.com/excalidraw/excalidraw.git
synced 2025-05-03 10:00:07 -04:00
fix: Move a frame along with its children
This commit is contained in:
parent
7343285694
commit
820a8540b1
3 changed files with 67 additions and 35 deletions
|
@ -58,17 +58,13 @@ const MultiPosition = ({
|
||||||
}),
|
}),
|
||||||
[atomicUnits, elementsMap, property],
|
[atomicUnits, elementsMap, property],
|
||||||
);
|
);
|
||||||
const elementsWithFramesChildren = elements.reduce((accumulator: ExcalidrawElement[], element: ExcalidrawElement) => {
|
|
||||||
if (!isFrameLikeElement(element)) return [...accumulator, element];
|
|
||||||
return [...accumulator, element, ...getFrameChildren(elementsMap, element.id)];
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const value = new Set(positions).size === 1 ? positions[0] : "Mixed";
|
const value = new Set(positions).size === 1 ? positions[0] : "Mixed";
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<StatsDragInput
|
<StatsDragInput
|
||||||
label={property === "x" ? "X" : "Y"}
|
label={property === "x" ? "X" : "Y"}
|
||||||
elements={elementsWithFramesChildren}
|
elements={elements}
|
||||||
dragInputCallback={handlePositionChange}
|
dragInputCallback={handlePositionChange}
|
||||||
value={value}
|
value={value}
|
||||||
property={property}
|
property={property}
|
||||||
|
|
|
@ -35,8 +35,6 @@ const Position = ({
|
||||||
pointFrom(element.x + element.width / 2, element.y + element.height / 2),
|
pointFrom(element.x + element.width / 2, element.y + element.height / 2),
|
||||||
element.angle,
|
element.angle,
|
||||||
);
|
);
|
||||||
const children = isFrameLikeElement(element) ? getFrameChildren(elementsMap, element.id) : [];
|
|
||||||
const elements = children.length > 0 ? [element, ...children] : [element];
|
|
||||||
let value = round(property === "x" ? topLeftX : topLeftY, 2);
|
let value = round(property === "x" ? topLeftX : topLeftY, 2);
|
||||||
|
|
||||||
if (
|
if (
|
||||||
|
@ -57,7 +55,7 @@ const Position = ({
|
||||||
return (
|
return (
|
||||||
<StatsDragInput
|
<StatsDragInput
|
||||||
label={property === "x" ? "X" : "Y"}
|
label={property === "x" ? "X" : "Y"}
|
||||||
elements={elements}
|
elements={[element]}
|
||||||
dragInputCallback={handlePositionChange}
|
dragInputCallback={handlePositionChange}
|
||||||
scene={scene}
|
scene={scene}
|
||||||
value={value}
|
value={value}
|
||||||
|
|
|
@ -30,6 +30,7 @@ import type {
|
||||||
import type Scene from "@excalidraw/element/Scene";
|
import type Scene from "@excalidraw/element/Scene";
|
||||||
|
|
||||||
import type { AppState } from "../../types";
|
import type { AppState } from "../../types";
|
||||||
|
import { getFrameChildren } from "@excalidraw/element/frame";
|
||||||
|
|
||||||
export type StatsInputProperty =
|
export type StatsInputProperty =
|
||||||
| "x"
|
| "x"
|
||||||
|
@ -191,6 +192,60 @@ export const moveElement = (
|
||||||
{ informMutation: shouldInformMutation, isDragging: false },
|
{ informMutation: shouldInformMutation, isDragging: false },
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isFrameLikeElement(originalElement)) {
|
||||||
|
getFrameChildren(originalElementsMap, originalElement.id).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);
|
||||||
|
|
||||||
|
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 moveElements = (
|
export const moveElements = (
|
||||||
|
@ -371,22 +426,6 @@ export const handlePositionChange: DragInputCallbackType<
|
||||||
origElement.angle,
|
origElement.angle,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (isFrameChildElement(origElement)) {
|
|
||||||
const childNewTopLeftX = property === "x" ? nextValue + Math.abs(topLeftX) : topLeftX;
|
|
||||||
const childNewTopLeftY = property === "y" ? nextValue + Math.abs(topLeftY) : topLeftY;
|
|
||||||
|
|
||||||
moveElement(
|
|
||||||
childNewTopLeftX,
|
|
||||||
childNewTopLeftY,
|
|
||||||
origElement,
|
|
||||||
scene,
|
|
||||||
originalElementsMap,
|
|
||||||
false,
|
|
||||||
);
|
|
||||||
|
|
||||||
scene.triggerUpdate();
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
const newTopLeftX = property === "x" ? nextValue : topLeftX;
|
const newTopLeftX = property === "x" ? nextValue : topLeftX;
|
||||||
const newTopLeftY = property === "y" ? nextValue : topLeftY;
|
const newTopLeftY = property === "y" ? nextValue : topLeftY;
|
||||||
|
|
||||||
|
@ -401,7 +440,6 @@ export const handlePositionChange: DragInputCallbackType<
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
scene.triggerUpdate();
|
scene.triggerUpdate();
|
||||||
return;
|
return;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue