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:
Steven Nguyen 2020-04-18 15:50:30 +02:00 committed by GitHub
parent ff0ecb5e33
commit 2bfb0c20c3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 73 additions and 3 deletions

View file

@ -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],
});