Skip to content

Zoom percentage fix and zoom out more - #1869

Open
SebastianEggli wants to merge 2 commits into
CyberTimon:mainfrom
SebastianEggli:feat/editor-zoom-out-ori
Open

SebastianEggli wants to merge 2 commits into
CyberTimon:mainfrom
SebastianEggli:feat/editor-zoom-out-ori

Conversation

@SebastianEggli

Copy link
Copy Markdown

Description

  • Zoom out further, needed for large images/small screens
  • Zoom percentage math fixed, now displays the correct zoom percentage at the bottom

Type of Change

  • Bug fix
  • New feature
  • Breaking change
  • Performance improvement
  • Code refactoring
  • Documentation update
  • UI/UX improvement
  • Build/CI or Dependency update

Changes Made

  • Zoom out further, necessary for large images/smaller screens (minimum zoom 10% → 1%; finer slider steps; keyboard steps scale proportionally below 20% so they don't overshoot)
  • Fixed zoom percentage indicator to display the actual percentage
    • New src/utils/zoom.ts with the shared math: percent = renderScale × transformScale × dpr. Also contains the 1%–200% limits, zoom steps, and zoomReferenceSize (the cropped/oriented size the editor draws).
    • The editor store keeps the fitted render scale (baseRenderSize.renderScale). BottomBar, useEditorActions.handleZoomChange and useKeyboardShortcuts (step, cycle, in/out) all use it instead of originalSize.
    • The editor's transform min/max and "zoom to pixel on click" use the same helpers.
    • The 1%–200% limits now apply to on-screen pixels on every display.
  • New useDevicePixelRatio hook, used by the editor, bottom bar and settings panel. The readout and limits update when the window moves to another monitor or the OS scale changes. The settings panel's previous listener only caught the first change.
  • Added vitest as a dev dependency and an npm test script.

Testing

  • These changes were tested locally by a human and confirmed to work.
  • I haven't added any automated tests to the code because the codebase currently lacks a test suite.

Added src/utils/zoom.test.ts, run with npm test, about 2,000 cases. It's table-driven across:

  • Monitors: 1366×768, FHD at 100% and 125%, QHD, 3440×1440 ultrawide, 4K at 150% and 200%, 5K Retina, and GNOME X11 fractional scaling
  • Images: landscape, a tall portrait scan, square, and a small image that fits at over 100%
  • Edit states: none, rotated 90°/270°, 50% crop, crop plus rotation, and a portrait crop

Each combination checks that 100% is 1:1, that a typed percent reads back the same, fit, and the limits. Two regression tests reproduce the old 67% and "magnified while showing 100%" errors.

Manual check: open a 1-pixel black/white checkerboard image and type 100. The pattern looks crisp and even, with no stripes or blur, and the readout stays at 100%, including after rotating and cropping.

Test Configuration:

  • OS: Ubuntu 24.04.5 LTS (X11, GNOME)
  • Hardware: AMD Ryzen 7 1800X, Nvidia RTX 3050, 27" 2560×1440 display

Checklist

  • My code follows the project's code style
  • I haven't added unnecessary AI-generated code comments
  • My changes generate no new warnings or errors

AI Disclaimer:

Please state the involvement of AI in this PR:

  • This PR is created by an AI agent
  • This PR is mostly AI-generated but edited/merged together by a human
  • This PR was handwritten with AI assistance (spell check, logic suggestions, error resolving)
  • This PR contains only blood, sweat, and coffee (AI-free)

SebastianEggli and others added 2 commits October 7, 2026 20:26
Lower the minimum editor zoom from 10% to 1% via a shared
MIN_ZOOM_PERCENT constant, use a finer slider step, and step zoom
proportionally below 20% so keyboard zoom doesn't overshoot.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…mage

The zoom readout, percent input and keyboard shortcuts compared the on-screen
size to the uncropped, unrotated original, while the editor renders the
cropped/oriented image. Typing 100% on a cropped image magnified it by
origW/cropW while still reading 100%, and on a 90° rotated 3:2 image the
readout jumped to ~67%.

Centralize the math in utils/zoom.ts (physical percent = renderScale *
transformScale * dpr), store the fit render scale, clamp 1%-200% in physical
pixels for every DPR, and track devicePixelRatio reactively via a new
useDevicePixelRatio hook.

Add vitest with table-driven tests across monitor profiles, images and
crop/rotation states, plus regression cases for the old formulas.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant