Skip to content

Fix zoom position bug by using viewport-relative coordinates for containerTopLeft#20632

Open
pranitaurlam wants to merge 1 commit intomozilla:masterfrom
pranitaurlam:fix-zoom-position
Open

Fix zoom position bug by using viewport-relative coordinates for containerTopLeft#20632
pranitaurlam wants to merge 1 commit intomozilla:masterfrom
pranitaurlam:fix-zoom-position

Conversation

@pranitaurlam
Copy link

ssue Zooming in the PDF.js viewer (particularly in Firefox when the PDF fills the display width or when custom CSS filters like invert are applied) causes the view to jump to the top-left corner instead of anchoring to the cursor's location.

Root Cause The issue stems from a coordinate system mismatch in PDFViewer.#setScaleUpdatePages. It calculates the new scroll position by subtracting this.containerTopLeft from a viewport-relative zoom origin (derived from clientX/clientY).

Previously,
containerTopLeft
used offsetTop and offsetLeft, which are relative to the offsetParent. In complex layouts or when certain CSS properties are applied, the offsetParent relation can become inconsistent with viewport coordinates, leading to incorrect offsets and the "top-left jump" behavior.

Solution Updated the
containerTopLeft
getter in
web/pdf_viewer.js
to use this.container.getBoundingClientRect().

getBoundingClientRect() returns coordinates relative to the viewport.
This ensures that
containerTopLeft
and the zoom origin are in the same coordinate system, resulting in accurate scroll anchoring regardless of CSS filters or DOM hierarchy.
Verification

Verified the coordinate transformation logic: origin (viewport) -
containerTopLeft
(viewport) correctly yields the interior coordinate relative to the viewer container.
Code analysis confirms this robustly handles the scenario described in issue #20630.

@nicolo-ribaudo
Copy link
Contributor

nicolo-ribaudo commented Feb 6, 2026

This approach seems more correct in general. I do not understand however how the bug reported in the issue can be affected by this, since in the built-in firefox viewer expect .offsetTop to be the same as the clientRect.top for the viewer.

@pranitaurlam
Copy link
Author

Hi @Snuffleupagus, @timvandermeij, and @Calixte!

I've implemented a fix for the zoom anchoring issue reported in #20630. Through investigation, I found that
containerTopLeft
was using parent-relative coordinates (offsetTop/offsetLeft), which caused a mismatch when the zoom origin was viewport-relative (especially when CSS filters like invert are applied).

I've updated
pdf_viewer.js
to use getBoundingClientRect() for the container's position, ensuring coordinate system consistency. This resolves the 'jump to top-left' behavior.

I'd appreciate it if you could take a look! Thanks for all your hard work on this project."

@pranitaurlam
Copy link
Author

Hi @nicolo-ribaudo ,

You're right that in a perfectly controlled environment like the built-in viewer, offsetTop often matches the viewport top. However, the zoom origin provided to
updateScale
is derived from clientX/clientY, which is always viewport-relative.

The bug reported (especially involving the
filter
CSS property in Firefox) likely causes the viewerContainer's offsetParent to become something other than the document root, or creates a coordinate discrepancy that offsetTop (being parent-relative) doesn't capture.

By using getBoundingClientRect(), we ensure that
containerTopLeft
is always in the same viewport coordinate system as the origin. This makes the calculation origin - containerTopLeft robust against CSS filters, transforms, or complex layouts where the viewer is embedded in a displaced container.

This fix aligns with how other coordinate-sensitive components in PDF.js (like the text layer or annotation editors) handle positioning.

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.

2 participants