pdfrx icon indicating copy to clipboard operation
pdfrx copied to clipboard

Supporting ScrollPhysics

Open enhancient opened this issue 7 months ago • 8 comments

Thanks for your great pdf reader!

I know InteractiveViewer doesn't support ScrollPhysics, so I had a go at implementing this by constructing 'synthetic' ScrollMetrics for the InteractiveViewer and applying the physics from the specified ScrollPhysics to offsets outside of the bounds. I've also tried to leverage the ScrollPhysics in the case of zooming beyond maxScale and below minScale. Obviously ScrollPhysics doesn't currently consider zooming, so I took the approach of calculating the extent the content bounds would be exceeded when zooming beyond the maxScale and applying the ScrollPhysics to that offset to provide friction (in the case of BouncingScrollPhysics).

InteractiveViewerScrollPhysics

video

I've added this info to the relevant flutter ticket in relation to InteractiveViewer, but I know you're using a forked version of InteractiveViewer for pdfrx. I have also integrated this ScrollPhysics support into the pdfrx forked version for my project. There are some issues around zooming below minScale that I'm still working on, but not sure how open you'd be to integrating this work to pdfrx? For iOS in particular it provides a much better experience of PDF reading.

enhancient avatar May 06 '25 04:05 enhancient

@enhancient It seems to be great addition to InteractiveViewer!

So should I manually merge your interactive_viewer_scroll_physics.dart code to pdfrx or will you send me a PR? Either way is acceptable to me :)

espresso3389 avatar May 06 '25 04:05 espresso3389

Great! I'll try merging my changes into the latest pdfrx and see how that goes - the _normalizeMatrix function conflicts with enabling boundaries to be exceeded (which is required for BouncingScrollPhysics), and I need to check how it works with the new _updateLayout approach you've added. I'll be in touch after that.

enhancient avatar May 06 '25 06:05 enhancient

Yes, normalizeMatrix may interfere with ScrollPhysics. Anyway, at the first implementation, we should work it around by setting empty implementation, (m,_,_,_) => m or such.

espresso3389 avatar May 06 '25 08:05 espresso3389

I'm testing your InteractiveViewer fork on ScrollPhysics_#356 branch.

And, realized that beside settings scrollPhysics: BouncingScrollPhysics,

  1. Add normalizeMatrix: (matrix, viewSize, layout, controller) => matrix
  2. Add boundaryMargin to some solid value like EdgeInsets.zero

The second one is important for pdfrx to center the actual document inside the view. So I need some extra work to deal with it anyway.

espresso3389 avatar May 15 '25 05:05 espresso3389

I'm also taking a look at this at the moment, and yes, boundaryMargin is important to set for the scroll physics to work as it calculates the boundaries using this. This does present some challenges for using in pdfrx because of the reliance on normalizeMatrix to align pages, and lots of the logic for page fitting doesn't currently accommodate a boundaryMargin. Also when there are boundaryMargins set for InteractiveViewer there can be some conflicts between the boundary clamping logic in InteractiveViewer and in pdfrx, and when we want to zoom out beyond the fit scale, how exactly to handle alignment. I'm trying to figure out what the best path forward is - things like the zoom snapback are presenting some challenges. I'll share some ideas and code hopefully in the next few days.

enhancient avatar May 15 '25 06:05 enhancient

Another issue, because pdfrx provides several PdfViewerController.goTo and of course PdfViewerController.value to directly set the transformation matrix, but I cannot figure out how to initiate bouncing back in such situation.

espresso3389 avatar May 15 '25 06:05 espresso3389

Another issue, because pdfrx provides several PdfViewerController.goTo and of course PdfViewerController.value to directly set the transformation matrix, but I cannot figure out how to initiate bouncing back in such situation.

The bounce back simulations are initiated by gestures detectors within InteractiveViewer, and there is no way to trigger a 'bounce back' if the matrix is directly set as far as I can see. For programatic updates of the matrix in functions like calcFitZoomMatrices, _calcCoverFitScale, _normalizeMatrix, calcMatrixFitWidthForPage, etc, ensuring that boundaryMargins are included as part of the translations, will ensure that no bouncing back into bounds is required. I'm looking into this further.

enhancient avatar May 15 '25 06:05 enhancient

After a fair bit of effort I've found what I think is a really good solution - more details in this PR https://github.com/espresso3389/pdfrx/pull/366.

enhancient avatar May 20 '25 04:05 enhancient