Compare commits

...

5 Commits

Author SHA1 Message Date
Daniel J. Geiger
60bab6a428 feat: Widen ActionName and ShortcutName to include custom.${string} 2023-11-22 15:27:47 -06:00
Barnabás Molnár
7c9cf30909 fix: make zoomToFit fitToViewport account for sidebar (#7298) 2023-11-17 15:56:19 +01:00
David Luzar
1e37dbd60e feat: change frame resizing behavior (#7307) 2023-11-17 14:37:43 +01:00
David Luzar
f8d5c2a1b6 build: allow a range of major node versions (#7306) 2023-11-17 14:23:19 +01:00
Aakansha Doshi
23b24ea5c3 build: use caret for specifying node version to avoid major upgrades automatically (#7297) 2023-11-16 16:18:38 +05:30
5 changed files with 31 additions and 36 deletions

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",

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, {

View File

@@ -2,11 +2,12 @@ import { isDarwin } from "../constants";
import { t } from "../i18n"; import { t } from "../i18n";
import { SubtypeOf } from "../utility-types"; import { SubtypeOf } from "../utility-types";
import { getShortcutKey } from "../utils"; import { getShortcutKey } from "../utils";
import { ActionName } from "./types"; import { ActionName, CustomActionName } from "./types";
export type ShortcutName = export type ShortcutName =
| SubtypeOf< | SubtypeOf<
ActionName, ActionName,
| CustomActionName
| "toggleTheme" | "toggleTheme"
| "loadScene" | "loadScene"
| "clearCanvas" | "clearCanvas"
@@ -40,6 +41,15 @@ export type ShortcutName =
| "saveScene" | "saveScene"
| "imageExport"; | "imageExport";
export const registerCustomShortcuts = (
shortcuts: Record<CustomActionName, string[]>,
) => {
for (const key in shortcuts) {
const shortcut = key as CustomActionName;
shortcutMap[shortcut] = shortcuts[shortcut];
}
};
const shortcutMap: Record<ShortcutName, string[]> = { const shortcutMap: Record<ShortcutName, string[]> = {
toggleTheme: [getShortcutKey("Shift+Alt+D")], toggleTheme: [getShortcutKey("Shift+Alt+D")],
saveScene: [getShortcutKey("CtrlOrCmd+S")], saveScene: [getShortcutKey("CtrlOrCmd+S")],

View File

@@ -35,7 +35,11 @@ type ActionFn = (
export type UpdaterFn = (res: ActionResult) => void; export type UpdaterFn = (res: ActionResult) => void;
export type ActionFilterFn = (action: Action) => void; export type ActionFilterFn = (action: Action) => void;
export const makeCustomActionName = (name: string) =>
`custom.${name}` as CustomActionName;
export type CustomActionName = `custom.${string}`;
export type ActionName = export type ActionName =
| CustomActionName
| "copy" | "copy"
| "cut" | "cut"
| "paste" | "paste"

View File

@@ -8317,39 +8317,6 @@ class App extends React.Component<AppProps, AppState> {
const elementsToHighlight = new Set<ExcalidrawElement>(); const elementsToHighlight = new Set<ExcalidrawElement>();
selectedFrames.forEach((frame) => { selectedFrames.forEach((frame) => {
const elementsInFrame = getFrameChildren(
this.scene.getNonDeletedElements(),
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( getElementsInResizingFrame(
this.scene.getNonDeletedElements(), this.scene.getNonDeletedElements(),
frame, frame,