Skip to content

Zoom improvements - #1390

Merged
allanlasser merged 21 commits into
mainfrom
1084-zoom
Aug 31, 2026
Merged

Zoom improvements#1390
allanlasser merged 21 commits into
mainfrom
1084-zoom

Conversation

@dnass

@dnass dnass commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Closes #1084 and #1389. Introduces a new default zoom mode for documents, Auto, and zoom in/zoom out buttons to step between zoom levels.

Key changes:

  • Auto zoom mode is added as the new default. This mode sizes the document so that its widest page fills 100% of the viewer. When the viewer width changes (from a window resize or toggling a sidebar), the zoom level changes too.
  • Fit width and Fit height zoom modes are removed. Both of these sized pages individually to fill the viewer; removing them means that every page of the document is presented at a uniform zoom level.
  • Zoom in and zoom out buttons accompany the zoom level select menu. These step through the same preset values available in the menu, in any mode. When auto zoom is active, the buttons will snap to the next lowest or highest preset zoom level.
  • Also fixed Changing zoom level duplicates textLayer content #1389, where a page's text layer content was duplicated rather than replaced on re-rendering.

Update:

  • Adds a compact mobile toolbar layout that removes the zoom select menu, the word "Page" from the pagination controls, and the label from the sections menu. Also adds an "auto zoom" button, though this might be unclear/unnecessary.
image
  • Implements pinch-to-zoom on mobile devices
  • Viewer UIs (section headers, page numbers/actions/notes, and annotations) are horizontally sticky in the viewport when the document overflows.
image

@dnass
dnass requested review from allanlasser and eyeseast August 12, 2026 19:51
@github-actions

github-actions Bot commented Aug 12, 2026

Copy link
Copy Markdown

Preview removed.

@github-actions

github-actions Bot commented Aug 12, 2026

Copy link
Copy Markdown

Coverage Report

Status Category Percentage Covered / Total
🔵 Lines 50.41% 3845 / 7627
🔵 Statements 48.77% 4468 / 9161
🔵 Functions 43.61% 1422 / 3260
🔵 Branches 47.72% 1953 / 4092
File Coverage
File Stmts Branches Functions Lines Uncovered Lines
Changed Files
src/lib/api/types.d.ts 0% 0% 0% 0%
src/lib/components/common/Paginator.svelte 71.18% 43.75% 73.91% 67.44% 83, 91-109, 122, 153-159, 142
src/lib/components/icons/ZoomFit16.svelte 100% 100% 100% 100%
src/lib/components/toolbars/PaginationToolbar.svelte 76.47% 72.72% 73.52% 72.22% 61-69, 94-97, 109, 114-119, 105, 133
src/lib/components/viewer/AnnotationLayer.svelte 49.49% 21.42% 56.66% 46.75% 86, 108-174, 199-213, 241, 259-269
src/lib/components/viewer/PDF.svelte 73.07% 50% 79.16% 62.16% 39, 42-49, 54, 62-71, 99-98
src/lib/components/viewer/PDFPage.svelte 39.53% 21.05% 48% 39.24% 129-241, 261, 270-273, 291-293, 301, 308, 311
src/lib/components/viewer/Page.svelte 57.14% 9.09% 77.77% 57.14% 106-127
src/lib/components/viewer/Zoom.svelte 94.59% 100% 95.65% 96.77% 72, 97
src/lib/state/viewer.svelte.ts 97.61% 94.73% 100% 97.22% 27
src/lib/utils/pinX.svelte.ts 100% 50% 100% 100%
src/lib/utils/viewer.ts 100% 93.42% 100% 100%
Generated in workflow #1344 for commit 7e7ad6a by the Vitest Coverage Report Action

@allanlasser

allanlasser commented Aug 12, 2026

Copy link
Copy Markdown
Member

The zoom logic behaves great, but our mobile UI still needs some consideration. Users will primarily encounter this at narrow screen widths when our viewer is embedded into other pages:

Screenshot 2026-08-12 at 16 01 36

A few possible solutions here:

  1. Change flex rules so pagination doesn't take up the full row and zoom can slot beside.
  2. Don't give mobile users a dropdown, and just let them use + / - for zoom (handling pinch-to-zoom and mapping to a zoom operation, if possible, could help here).
  3. Deeper rethink of our embed layout, rearranging elements to reduce UI chrome.
  4. Float zoom controls out of the toolbar and over the document, hiding or revealing them with some kind of heuristic.

Combining narrow-screen affordances with the improved zoom behavior should make this a winner.

@eyeseast

Copy link
Copy Markdown
Collaborator

If it helps, you can preview how embeds will look by adding /preview/ to the embed URL, like this: https://preview-1390.staging.documentcloud.org/documents/20011297-hhs-grants-terminated/preview/?embed=1

@eyeseast

Copy link
Copy Markdown
Collaborator

Setting a max size of 100% for auto means that a letter-sized document is too small to read on my laptop:

Screenshot 2026-08-18 at 5 39 38 PM

I know there's a point where "fit width" was too big, but I don't think this screen is there.

@dnass

dnass commented Aug 18, 2026

Copy link
Copy Markdown
Contributor Author

You're right, but it seems weird that it wouldn't be readable at 100%. Ended up going on a deep dive into PDF sizing. PDFs don't have intrinsic pixel dimensions, they're sized in physical units. It looks like DocumentCloud is treating the values in page_spec as pixels when they're actually points. At 100%, the viewer draws a standard 8.5x11" document at 612x792px, while Preview shows the same dimensions but in points:

image   image

A point is 1/72 of an inch, and CSS pixels are defined as 1/96 inch, so the conversion is points / 72 * 96. Our 612pt doc should be drawn 816px at "actual size." But I compared a bunch of other PDF viewers and none of them are quite doing that:

  • Chrome at 100%: 826px
  • Safari at Actual size: 878px
  • Preview at Actual size: 924px
  • Acrobat at Actual size: 936px

So I think we have three options here:

  1. Keep treating 1pt as 1px and just increase the auto width cap to 150%
  2. Multiply pt widths from the page spec by 1.33 to get the "actual" width. This is the multiplier that PDF.js's viewer uses internally
  3. Multiply pt widths by whatever we want, apparently

I think users would reasonably expect a normal document to be legible at 100%, so I'm in favor of 2 or 3.

@eyeseast

Copy link
Copy Markdown
Collaborator

Either 2 or 3 seem totally reasonable. I think try 2, just to match what pdf.js does by default, and then see if there's a good reason to do 3.

@dnass

dnass commented Aug 19, 2026

Copy link
Copy Markdown
Contributor Author

Updated to use 96 / 72 as the pt to px conversion. I think things look much more legible at this scale.

@eyeseast

Copy link
Copy Markdown
Collaborator

Yes, much better. The horizontal document I have linked above ends up at 78%, which fills the viewport. A letter-sized document is at 100%, and that's readable. I think we're good.

@eyeseast

Copy link
Copy Markdown
Collaborator

I'm getting this warning in the console: https://svelte.dev/docs/svelte/runtime-warnings#Client-warnings-derived_inert

I have this document open in search mode: https://preview-1390.staging.documentcloud.org/documents/20011264-251118397v1/?mode=search&q=emergent

Click on any search result and you should see it. Doesn't seem like it's breaking anything now but can't promise it won't later.

@dnass

dnass commented Aug 19, 2026

Copy link
Copy Markdown
Contributor Author

I'm seeing that on main too, don't think it's related to this PR. Looks like the issue is that this derived's dependencies change when the navigation happens, so searchWithin fires and is still in flight when the component is destroyed. Pretty sure it's harmless, but fixing it could save a useless network request.

@eyeseast

Copy link
Copy Markdown
Collaborator

OK, I wonder if it's related to #1139 (and we can address it there).

@dnass

dnass commented Aug 21, 2026

Copy link
Copy Markdown
Contributor Author

Just pushed a change that fixes a performance regression related to the pin-x animation, and improves zoom performance above baseline by applying content-visibility: auto to offscreen pages. Both the issue and the fix are only really noticeable on very large documents.

@allanlasser
allanlasser merged commit e8b8e13 into main Aug 31, 2026
10 of 12 checks passed
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.

Changing zoom level duplicates textLayer content Clearer zoom option on document embeds, particularly for mobile

3 participants