Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature request: Improve scaling API to simplify zoom implementation in embedders #18076

Open
2 tasks
nicolo-ribaudo opened this issue May 13, 2024 · 0 comments
Open
2 tasks

Comments

@nicolo-ribaudo
Copy link
Contributor

To properly implement zoom gestures (Ctrl+wheel, or pinch-to-zoom), applications that embed the viewer currently have to:

  1. compute the scaling factor/steps based on the input method
  2. call pdfViewer.decreaseScale or pdfViewer.increaseScale, depending on whether it's a zoom in or out
  3. scroll the PDF to restore the center of the gesture, knowing that decreaseScale/increaseScale preserve the position of the top-left visible corner.
As an example, in the PDF.js app, (2) needs to be checked 4 times (one for each zoom input method):

pdf.js/web/app.js

Lines 2641 to 2646 in b676540

if (scaleFactor < 1) {
PDFViewerApplication.zoomOut(null, scaleFactor);
} else if (scaleFactor > 1) {
PDFViewerApplication.zoomIn(null, scaleFactor);
} else {
return;

pdf.js/web/app.js

Lines 2679 to 2685 in b676540

if (ticks < 0) {
PDFViewerApplication.zoomOut(-ticks);
} else if (ticks > 0) {
PDFViewerApplication.zoomIn(ticks);
} else {
return;
}

pdf.js/web/app.js

Lines 2800 to 2806 in b676540

if (newScaleFactor < 1) {
PDFViewerApplication.zoomOut(null, newScaleFactor);
} else if (newScaleFactor > 1) {
PDFViewerApplication.zoomIn(null, newScaleFactor);
} else {
return;
}

pdf.js/web/app.js

Lines 2813 to 2819 in b676540

if (ticks < 0) {
PDFViewerApplication.zoomOut(-ticks);
} else if (ticks > 0) {
PDFViewerApplication.zoomIn(ticks);
} else {
return;
}

And for (3) it has a "post-zoom scroll fixup" implemented at

pdf.js/web/app.js

Lines 2101 to 2109 in b676540

_centerAtPos(previousScale, x, y) {
const { pdfViewer } = this;
const scaleDiff = pdfViewer.currentScale / previousScale - 1;
if (scaleDiff !== 0) {
const [top, left] = pdfViewer.containerTopLeft;
pdfViewer.container.scrollLeft += (x - left) * scaleDiff;
pdfViewer.container.scrollTop += (y - top) * scaleDiff;
}
},

The same logic needs to be re-implemented in other embedders that implement gestures-based zoom, such as in ngx-extended-pdf-viewer for angular (or the internal one I'm helping with, which re-implements similar logic).


What I would like the viewer to provide is:

  • a center: [x, y] parameter in increaseScale/decreaseScale that allows customizing the "zoom center" rather than always scrolling to _location.top, _location.left and then having to manually adjust it separately. Having to compute the "scroll adjustment" can be tricky if you don't know exactly how the various position/zoom data from the viewer fit together.
  • an updateScale function, that zooms in if the scaleFactor > 1 || steps > 0, and zooms out if scaleFactor < 1 || steps < 0

The first one is more important, since it centralizes the "adjust scroll after zoom" logic in a single place (the viewer) rather than it being split across the viewer and the wrapper. The second one is just for convenience.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants