diff --git a/src/actions/actionCanvas.tsx b/src/actions/actionCanvas.tsx index d29b7c71..4a820085 100644 --- a/src/actions/actionCanvas.tsx +++ b/src/actions/actionCanvas.tsx @@ -3,6 +3,7 @@ import { getDefaultAppState } from "../appState"; import { ColorPicker } from "../components/ColorPicker"; import { resetZoom, trash, zoomIn, zoomOut } from "../components/icons"; import { ToolButton } from "../components/ToolButton"; +import { ZOOM_STEP } from "../constants"; import { getCommonBounds, getNonDeletedElements } from "../element"; import { newElementWith } from "../element/mutateElement"; import { ExcalidrawElement } from "../element/types"; @@ -75,8 +76,6 @@ export const actionClearCanvas = register({ ), }); -const ZOOM_STEP = 0.1; - export const actionZoomIn = register({ name: "zoomIn", perform: (_elements, appState) => { diff --git a/src/components/App.tsx b/src/components/App.tsx index 784916c2..338c09e4 100644 --- a/src/components/App.tsx +++ b/src/components/App.tsx @@ -52,6 +52,7 @@ import { TAP_TWICE_TIMEOUT, TEXT_TO_CENTER_SNAP_THRESHOLD, TOUCH_CTX_MENU_TIMEOUT, + ZOOM_STEP, } from "../constants"; import { loadFromBlob } from "../data"; import { isValidLibrary } from "../data/json"; @@ -3709,9 +3710,15 @@ class App extends React.Component { }, 1000); } + let newZoom = this.state.zoom.value - delta / 100; + // increase zoom steps the more zoomed-in we are (applies to >100% only) + newZoom += Math.log10(Math.max(1, this.state.zoom.value)) * -sign; + // round to nearest step + newZoom = Math.round(newZoom * ZOOM_STEP * 100) / (ZOOM_STEP * 100); + this.setState(({ zoom, offsetLeft, offsetTop }) => ({ zoom: getNewZoom( - getNormalizedZoom(zoom.value - delta / 100), + getNormalizedZoom(newZoom), zoom, { left: offsetLeft, top: offsetTop }, { diff --git a/src/constants.ts b/src/constants.ts index db408fd4..b037eb23 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -91,3 +91,5 @@ export const TOUCH_CTX_MENU_TIMEOUT = 500; export const TITLE_TIMEOUT = 10000; export const TOAST_TIMEOUT = 5000; export const VERSION_TIMEOUT = 30000; + +export const ZOOM_STEP = 0.1; diff --git a/src/scene/zoom.ts b/src/scene/zoom.ts index c239cc27..0a36418d 100644 --- a/src/scene/zoom.ts +++ b/src/scene/zoom.ts @@ -25,6 +25,6 @@ export const getNewZoom = ( export const getNormalizedZoom = (zoom: number): NormalizedZoomValue => { const normalizedZoom = parseFloat(zoom.toFixed(2)); - const clampedZoom = Math.max(0.1, Math.min(normalizedZoom, 2)); + const clampedZoom = Math.max(0.1, Math.min(normalizedZoom, 10)); return clampedZoom as NormalizedZoomValue; };