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

Flickering while zooming #875

Closed
phal0r opened this issue Oct 20, 2021 · 8 comments
Closed

Flickering while zooming #875

phal0r opened this issue Oct 20, 2021 · 8 comments
Assignees
Labels
question Further information is requested

Comments

@phal0r
Copy link

phal0r commented Oct 20, 2021

Before you start - checklist

  • [x ] I followed instructions in documentation written for my React-PDF version
  • [x ] I have checked if this bug is not already reported
  • [x ] I have checked if an issue is not listed in Known issues
  • [x ] If I have a problem with PDF rendering, I checked if my PDF renders properly in Mozilla Firefox

Description

I want to implement zoom functionality with canvas renderer, but when changing the dimensions of the page component (width/height or scale), the currently rendered page disappears (height is zero or canvas is removed, not sure) until the page with the new dimensions is rendered. This leads to flickering while zooming.

Steps to reproduce

  • take simple example
  • change scale, width or height of the page
  • flickering occurs

Expected behavior
The currently rendered page should stay until the new one is rendered like it's down with the pdf.js viewer (https://mozilla.github.io/pdf.js/web/viewer.html). When zooming, you can see, that the old rendered page stays and will be replaced with the newly rendered page.

Environment

  • Browser (if applicable) [e.g. Chrome 57, Firefox 59]:
  • React-PDF version [e.g. 3.0.4]:
  • React version [e.g. 16.3.0]:
  • Webpack version (if applicable) [e.g. 4.16.2]:
@wojtekmaj wojtekmaj added the question Further information is requested label Oct 21, 2021
@AstroProjection
Copy link

Hey,
What is the status on this? Is this issue being taken up or is a there a way/starting point that we could look into to resolve this?
We're also facing a similar issue when zooming in/out on the viewer and hoping to fix it.

Thanks!

@phal0r
Copy link
Author

phal0r commented Nov 12, 2021

The questions is, what @wojtekmaj thinks about this topic. In general I think, that it should be part of the library, because it cannot be added from "outside". All issues in this repo regarding zooming only suggest solutions with css transforms, which only works for the svg backend. With canvas rendering it is not possible to accomplish a solution without modifying the library, because it must be a mix of expanding the old canvas, rerender in the background and replace the old with the new canvas.

Apart from that, for me it is also possible to use pdf.js directly in my project, if zooming will not become a first class citizen.

@zarv1k
Copy link

zarv1k commented Nov 12, 2021

@phal0r Hi! Just FYI, you are completely right that it can't be added from outside. I found some workaround that might be helpful for you, it's a bit tricky and not a perfect solution :) but at least it works pretty well:

  • hide canvas element completely (display: none);
  • in onRenderSuccess handler you can create create png image blob (canvas.toBlob()) from canvas element (using canvasRef prop of Page component) and then you can create imgUrl from blob (URL.createObjectUrl) and then store it in local state;
  • when imgUrl is defined, your can render <img src={imgUrl}> as a Page children component;
  • apply appropriate styles to img for your needs;
  • on zoom change, canvas'll be redrawn and then onRenderSuccess is called again, where you can recreate png from canvas with the new dimensions.

So, such an approach allows you to avoid seeing some short moment with an empty canvas element during it's re-drawing, because the png image, you are rendering by yourself as Page children, will be always shown.

Hope this can help you.

@wojtekmaj
Copy link
Owner

wojtekmaj commented Nov 24, 2021

The trick here is to use keys to delay unmounting old version of the Page while the new one is still being rendered.

A simplified version of this issue was discussed in #418, where I proposed https://codesandbox.io/s/react-pdf-prevent-flash-nbikj.

To stop page from flickering, we need to modify this example to keep the old version of the page not only when page number changes, but scale as well:

https://codesandbox.io/s/react-pdf-prevent-flash-with-scale-nse51l

Hope this helps.

@wojtekmaj wojtekmaj self-assigned this Nov 24, 2021
@yunsii

This comment was marked as resolved.

@wojtekmaj
Copy link
Owner

Updated link, sorry about that

@AstroProjection
Copy link

@wojtekmaj

Hey, I was just wondering if there would be a way to add in this flickering fix which also allows the PDF to say zoom into a certain click position, without shifting around due to the old page being a little smaller than the new updated position of the whole PDF container document.

In this situation, the PDF is not bound to top-left but is floating freely in a view space

@wojtekmaj
Copy link
Owner

@AstroProjection Nothing comes to my mind that I could do on my side. You can manipulate scale with CSS somehow to prevent page jumps, or put pages in your own containers you manage size yourself to avoid any problems with swapping <Page /> components.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

5 participants