Compare commits

...
3 changed files with 36 additions and 68 deletions
+1 -1
View File
@@ -96,7 +96,7 @@
"vitest-canvas-mock": "0.3.2" "vitest-canvas-mock": "0.3.2"
}, },
"engines": { "engines": {
"node": ">=18.0.0" "node": "18.0.0 - 20.x.x"
}, },
"homepage": ".", "homepage": ".",
"name": "excalidraw", "name": "excalidraw",
+15 -1
View File
@@ -265,7 +265,21 @@ export const zoomToFit = ({
30.0, 30.0,
) as NormalizedZoomValue; ) as NormalizedZoomValue;
scrollX = (appState.width / 2) * (1 / newZoomValue) - centerX; let appStateWidth = appState.width;
if (appState.openSidebar) {
const sidebarDOMElem = document.querySelector(
".sidebar",
) as HTMLElement | null;
const sidebarWidth = sidebarDOMElem?.offsetWidth ?? 0;
const isRTL = document.documentElement.getAttribute("dir") === "rtl";
appStateWidth = !isRTL
? appState.width - sidebarWidth
: appState.width + sidebarWidth;
}
scrollX = (appStateWidth / 2) * (1 / newZoomValue) - centerX;
scrollY = (appState.height / 2) * (1 / newZoomValue) - centerY; scrollY = (appState.height / 2) * (1 / newZoomValue) - centerY;
} else { } else {
newZoomValue = zoomValueToFitBoundsOnViewport(commonBounds, { newZoomValue = zoomValueToFitBoundsOnViewport(commonBounds, {
+19 -65
View File
@@ -8238,27 +8238,8 @@ class App extends React.Component<AppProps, AppState> {
event[KEYS.CTRL_OR_CMD] ? null : this.state.gridSize, event[KEYS.CTRL_OR_CMD] ? null : this.state.gridSize,
); );
const frameElementsOffsetsMap = new Map< const resizingSingleFrameOnly =
string, selectedElements.length === 1 && selectedFrames.length === 1;
{
x: number;
y: number;
}
>();
selectedFrames.forEach((frame) => {
const elementsInFrame = getFrameChildren(
this.scene.getNonDeletedElements(),
frame.id,
);
elementsInFrame.forEach((element) => {
frameElementsOffsetsMap.set(frame.id + element.id, {
x: element.x - frame.x,
y: element.y - frame.y,
});
});
});
// check needed for avoiding flickering when a key gets pressed // check needed for avoiding flickering when a key gets pressed
// during dragging // during dragging
@@ -8299,7 +8280,12 @@ class App extends React.Component<AppProps, AppState> {
transformElements( transformElements(
pointerDownState, pointerDownState,
transformHandleType, transformHandleType,
selectedElements, resizingSingleFrameOnly
? selectedElements
: this.scene.getSelectedElements({
selectedElementIds: this.state.selectedElementIds,
includeElementsInFrames: true,
}),
pointerDownState.resize.arrowDirection, pointerDownState.resize.arrowDirection,
shouldRotateWithDiscreteAngle(event), shouldRotateWithDiscreteAngle(event),
shouldResizeFromCenter(event), shouldResizeFromCenter(event),
@@ -8315,51 +8301,19 @@ class App extends React.Component<AppProps, AppState> {
) { ) {
this.maybeSuggestBindingForAll(selectedElements); this.maybeSuggestBindingForAll(selectedElements);
const elementsToHighlight = new Set<ExcalidrawElement>(); // highlight frame children ONLY when resizing a single frame
selectedFrames.forEach((frame) => { if (resizingSingleFrameOnly) {
const elementsInFrame = getFrameChildren( const selectedFrame = selectedFrames[0];
this.scene.getNonDeletedElements(), if (selectedFrame) {
frame.id,
);
// keep elements' positions relative to their frames on frames resizing
if (transformHandleType) {
if (transformHandleType.includes("w")) {
elementsInFrame.forEach((element) => {
mutateElement(element, {
x:
frame.x +
(frameElementsOffsetsMap.get(frame.id + element.id)?.x || 0),
y:
frame.y +
(frameElementsOffsetsMap.get(frame.id + element.id)?.y || 0),
});
});
}
if (transformHandleType.includes("n")) {
elementsInFrame.forEach((element) => {
mutateElement(element, {
x:
frame.x +
(frameElementsOffsetsMap.get(frame.id + element.id)?.x || 0),
y:
frame.y +
(frameElementsOffsetsMap.get(frame.id + element.id)?.y || 0),
});
});
}
}
getElementsInResizingFrame(
this.scene.getNonDeletedElements(),
frame,
this.state,
).forEach((element) => elementsToHighlight.add(element));
});
this.setState({ this.setState({
elementsToHighlight: [...elementsToHighlight], elementsToHighlight: getElementsInResizingFrame(
this.scene.getNonDeletedElements(),
selectedFrame,
this.state,
),
}); });
}
}
return true; return true;
} }