mirror of
https://github.com/excalidraw/excalidraw.git
synced 2025-02-18 13:29:36 +01:00
Add a button to show all content, if the zoom allows it. (#1406)
* add zoom center action button * enhance zoom calculation and scroll to center * add zoom out and center button * filter deleted elements * improve complexity * add key shortcut * calculate zoom value * don't render zoomCenter action * offset from top to account for shape menu * change shortcut & add to shortcut dialog * decrease offset * revert offset * change hotkey & description * rename to zoomToFit * change shortcut label & position Co-authored-by: dwelle <luzar.david@gmail.com>
This commit is contained in:
parent
ff0ecb5e33
commit
2bfb0c20c3
@ -4,13 +4,14 @@ import { getDefaultAppState } from "../appState";
|
||||
import { trash, zoomIn, zoomOut, resetZoom } from "../components/icons";
|
||||
import { ToolButton } from "../components/ToolButton";
|
||||
import { t } from "../i18n";
|
||||
import { getNormalizedZoom } from "../scene";
|
||||
import { getNormalizedZoom, calculateScrollCenter } from "../scene";
|
||||
import { KEYS } from "../keys";
|
||||
import { getShortcutKey } from "../utils";
|
||||
import useIsMobile from "../is-mobile";
|
||||
import { register } from "./register";
|
||||
import { newElementWith } from "../element/mutateElement";
|
||||
import { AppState } from "../types";
|
||||
import { AppState, FlooredNumber } from "../types";
|
||||
import { getCommonBounds } from "../element";
|
||||
|
||||
export const actionChangeViewBackgroundColor = register({
|
||||
name: "changeViewBackgroundColor",
|
||||
@ -73,6 +74,7 @@ const ZOOM_STEP = 0.1;
|
||||
const KEY_CODES = {
|
||||
MINUS: "Minus",
|
||||
EQUAL: "Equal",
|
||||
ONE: "Digit1",
|
||||
ZERO: "Digit0",
|
||||
NUM_SUBTRACT: "NumpadSubtract",
|
||||
NUM_ADD: "NumpadAdd",
|
||||
@ -159,3 +161,64 @@ export const actionResetZoom = register({
|
||||
(event.code === KEY_CODES.ZERO || event.code === KEY_CODES.NUM_ZERO) &&
|
||||
(event[KEYS.CTRL_OR_CMD] || event.shiftKey),
|
||||
});
|
||||
|
||||
const calculateZoom = (
|
||||
commonBounds: number[],
|
||||
currentZoom: number,
|
||||
{
|
||||
scrollX,
|
||||
scrollY,
|
||||
}: {
|
||||
scrollX: FlooredNumber;
|
||||
scrollY: FlooredNumber;
|
||||
},
|
||||
): number => {
|
||||
const { innerWidth, innerHeight } = window;
|
||||
const [x, y] = commonBounds;
|
||||
const zoomX = -innerWidth / (2 * scrollX + 2 * x - innerWidth);
|
||||
const zoomY = -innerHeight / (2 * scrollY + 2 * y - innerHeight);
|
||||
const margin = 0.01;
|
||||
let newZoom;
|
||||
|
||||
if (zoomX < zoomY) {
|
||||
newZoom = zoomX - margin;
|
||||
} else if (zoomY <= zoomX) {
|
||||
newZoom = zoomY - margin;
|
||||
} else {
|
||||
newZoom = currentZoom;
|
||||
}
|
||||
|
||||
if (newZoom <= 0.1) {
|
||||
return 0.1;
|
||||
}
|
||||
if (newZoom >= 1) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return newZoom;
|
||||
};
|
||||
|
||||
export const actionZoomToFit = register({
|
||||
name: "zoomToFit",
|
||||
perform: (elements, appState) => {
|
||||
const nonDeletedElements = elements.filter((element) => !element.isDeleted);
|
||||
const scrollCenter = calculateScrollCenter(nonDeletedElements);
|
||||
const commonBounds = getCommonBounds(nonDeletedElements);
|
||||
const zoom = calculateZoom(commonBounds, appState.zoom, scrollCenter);
|
||||
|
||||
return {
|
||||
appState: {
|
||||
...appState,
|
||||
scrollX: scrollCenter.scrollX,
|
||||
scrollY: scrollCenter.scrollY,
|
||||
zoom,
|
||||
},
|
||||
commitToHistory: false,
|
||||
};
|
||||
},
|
||||
keyTest: (event) =>
|
||||
event.code === KEY_CODES.ONE &&
|
||||
event.shiftKey &&
|
||||
!event.altKey &&
|
||||
!event[KEYS.CTRL_OR_CMD],
|
||||
});
|
||||
|
@ -25,6 +25,7 @@ export {
|
||||
actionZoomIn,
|
||||
actionZoomOut,
|
||||
actionResetZoom,
|
||||
actionZoomToFit,
|
||||
} from "./actionCanvas";
|
||||
|
||||
export { actionFinalize } from "./actionFinalize";
|
||||
|
@ -48,6 +48,7 @@ export type ActionName =
|
||||
| "zoomIn"
|
||||
| "zoomOut"
|
||||
| "resetZoom"
|
||||
| "zoomToFit"
|
||||
| "changeFontFamily"
|
||||
| "changeTextAlign"
|
||||
| "toggleFullScreen"
|
||||
|
@ -228,6 +228,10 @@ export const ShortcutsDialog = ({ onClose }: { onClose?: () => void }) => {
|
||||
label={t("buttons.resetZoom")}
|
||||
shortcuts={[getShortcutKey("CtrlOrCmd+0")]}
|
||||
/>
|
||||
<Shortcut
|
||||
label={t("shortcutsDialog.zoomToFit")}
|
||||
shortcuts={["Shift+1"]}
|
||||
/>
|
||||
<Shortcut
|
||||
label={t("buttons.toggleFullScreen")}
|
||||
shortcuts={["F"]}
|
||||
|
@ -150,7 +150,8 @@
|
||||
"howto": "Follow our guides",
|
||||
"github": "Found an issue? Submit",
|
||||
"textNewLine": "Add new line (text)",
|
||||
"textFinish": "Finish editing (text)"
|
||||
"textFinish": "Finish editing (text)",
|
||||
"zoomToFit": "Zoom to fit all elements"
|
||||
},
|
||||
"encrypted": {
|
||||
"tooltip": "Your drawings are end-to-end encrypted so Excalidraw's servers will never see them.\nClick the icon to learn more..."
|
||||
|
Loading…
Reference in New Issue
Block a user