flutter_pdf_render icon indicating copy to clipboard operation
flutter_pdf_render copied to clipboard

PdfViewer pinch-zoom error when only single page is provided

Open mbojec opened this issue 2 years ago • 4 comments

Hi there,

I've noticed a problem when using PdfViewer with only single page and trying to use pinch-zoom. When I zoom the page it instalty looses it's initial padding set in PdfViewerParams and when I try to go back to initial scale the padding is still missing and the scale is way bigger than the initial one.

mbojec avatar Oct 05 '22 14:10 mbojec

Currently, it's a restriction of InteractiveViewer and I don't know any workaround.

espresso3389 avatar Oct 06 '22 05:10 espresso3389

Hey, I am also facing this issue. Most of the PDFs in our app have only a single page so the issue is quite noticable. Has there been any development on this front lately?

ntoljic avatar Feb 27 '23 15:02 ntoljic

I think I found a workaround, at least for my use case. Let me try to explain.

Current behavior

My observation was that initially the single page PDF was fully visible. But since the aspect ratio of the PdfViewer and the aspect ratio of the PDF do not match I got some blank space at the bottom of the PdfViewer. Kind of like BoxFit.contain for an image let's say. Upon zooming in on the PDF there is a noticable jump as the PDF immediately fills its parent. Kind of like BoxFit.cover. Since the aspect ratios do not match we are now in a situation where the PDF is bigger than its parent, thus we can pan (in my case) left and right. Zooming in also works. Zooming out however only works up to the point where the PDF still covers the entire PdfViewer but not further. I am not sure where this behavior exactly comes from, whether it's from PdfViewer or from InteractiveViewer.

Digging deeper

Inspecting the code in pdfviewer.dart I noticed that the child of InteractiveViewer is a Stack. That stack has a SizedBox matching the dimensions of the PDF to be displayed. Overlayed on top is the result of ...iterateLaidOutPages. Now, I haven't looked into the specifics of the functions but instead focues on the Stack widget. The Stack size also increases on the jump on first zoom as described above.

Workaround

My naive idea at this point was "What if the SizedBox matches or exceeds the size of its parent?". Since PdfViewer is already using a LayoutBuilder and even stored the max constraints is the Size object viewSize, I simply sized the SizedBox with the max of the values docSize and viewSize for each axis.

So instead of

SizedBox(width: docSize.width, height: docSize.height)

I now got

SizedBox(width: max(docSize.width, viewSize.width), height: max(docSize.height, viewSize.height))

And lo and behold it actually works! The jump on first zoom is gone 🎉 Now, I am not sure about the reason for the current setup of the PdfViewer but I'd kindly ask you to think through my workaround. If you think this is a viable approach feel free to incorporate the change. I can also provide a PR but since it is literally just one line you're pry faster just doing it yourself.

Let me know what you think. In the meantime I will just use my local changes.

ntoljic avatar Feb 28 '23 10:02 ntoljic

This will help https://www.youtube.com/watch?v=gAUVz0U7eyA

myselfuser1 avatar Mar 17 '23 12:03 myselfuser1

using a single page pdf document shown on screen higher than document (so empty space under the page is shown):

i can confirm your patch fixes the zoom-in bump and even also fixes the fully zoom-out bug (currently, you can't make the page fully fit the screen using zoom out gesture, you could only do that using double tap zoom out).

However, as a side effect of your change, the empty space under the first (and only) page, remains there, even when zooming in. Although you could argue that's less of a problem than not being able to fully zoom out ;)

mx1up avatar Oct 20 '23 16:10 mx1up