feat: improve zoom-to-content when creating flowchart (#8368)

This commit is contained in:
David Luzar 2024-08-12 20:42:08 +02:00 committed by GitHub
parent 8420e1aa13
commit 4320a3cf41
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 107 additions and 30 deletions

View file

@ -24,7 +24,7 @@ import { CODES, KEYS } from "../keys";
import { getNormalizedZoom } from "../scene";
import { centerScrollOn } from "../scene/scroll";
import { getStateForZoom } from "../scene/zoom";
import type { AppState, NormalizedZoomValue } from "../types";
import type { AppState } from "../types";
import { getShortcutKey, updateActiveTool } from "../utils";
import { register } from "./register";
import { Tooltip } from "../components/Tooltip";
@ -38,6 +38,7 @@ import { DEFAULT_CANVAS_BACKGROUND_PICKS } from "../colors";
import type { SceneBounds } from "../element/bounds";
import { setCursor } from "../cursor";
import { StoreAction } from "../store";
import { clamp } from "../math";
export const actionChangeViewBackgroundColor = register({
name: "changeViewBackgroundColor",
@ -244,6 +245,7 @@ export const actionResetZoom = register({
const zoomValueToFitBoundsOnViewport = (
bounds: SceneBounds,
viewportDimensions: { width: number; height: number },
viewportZoomFactor: number = 1, // default to 1 if not provided
) => {
const [x1, y1, x2, y2] = bounds;
const commonBoundsWidth = x2 - x1;
@ -251,20 +253,21 @@ const zoomValueToFitBoundsOnViewport = (
const commonBoundsHeight = y2 - y1;
const zoomValueForHeight = viewportDimensions.height / commonBoundsHeight;
const smallestZoomValue = Math.min(zoomValueForWidth, zoomValueForHeight);
const adjustedZoomValue =
smallestZoomValue * clamp(viewportZoomFactor, 0.1, 1);
const zoomAdjustedToSteps =
Math.floor(smallestZoomValue / ZOOM_STEP) * ZOOM_STEP;
const clampedZoomValueToFitElements = Math.min(
Math.max(zoomAdjustedToSteps, MIN_ZOOM),
1,
);
return clampedZoomValueToFitElements as NormalizedZoomValue;
Math.floor(adjustedZoomValue / ZOOM_STEP) * ZOOM_STEP;
return getNormalizedZoom(Math.min(zoomAdjustedToSteps, 1));
};
export const zoomToFitBounds = ({
bounds,
appState,
fitToViewport = false,
viewportZoomFactor = 0.7,
viewportZoomFactor = 1,
}: {
bounds: SceneBounds;
appState: Readonly<AppState>;
@ -289,13 +292,10 @@ export const zoomToFitBounds = ({
Math.min(
appState.width / commonBoundsWidth,
appState.height / commonBoundsHeight,
) * Math.min(1, Math.max(viewportZoomFactor, 0.1));
) * clamp(viewportZoomFactor, 0.1, 1);
// Apply clamping to newZoomValue to be between 10% and 3000%
newZoomValue = Math.min(
Math.max(newZoomValue, MIN_ZOOM),
MAX_ZOOM,
) as NormalizedZoomValue;
newZoomValue = getNormalizedZoom(newZoomValue);
let appStateWidth = appState.width;
@ -314,10 +314,14 @@ export const zoomToFitBounds = ({
scrollX = (appStateWidth / 2) * (1 / newZoomValue) - centerX;
scrollY = (appState.height / 2) * (1 / newZoomValue) - centerY;
} else {
newZoomValue = zoomValueToFitBoundsOnViewport(bounds, {
width: appState.width,
height: appState.height,
});
newZoomValue = zoomValueToFitBoundsOnViewport(
bounds,
{
width: appState.width,
height: appState.height,
},
viewportZoomFactor,
);
const centerScroll = centerScrollOn({
scenePoint: { x: centerX, y: centerY },
@ -408,6 +412,7 @@ export const actionZoomToFitSelection = register({
userToFollow: null,
},
fitToViewport: true,
viewportZoomFactor: 0.7,
});
},
// NOTE this action should use shift-2 per figma, alas