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

Black flash occurs when we zoom in using scale and rotate #1340

Closed
3 of 4 tasks
bhanusingh431 opened this issue Feb 17, 2023 · 14 comments
Closed
3 of 4 tasks

Black flash occurs when we zoom in using scale and rotate #1340

bhanusingh431 opened this issue Feb 17, 2023 · 14 comments
Labels
bug Something isn't working

Comments

@bhanusingh431
Copy link

Before you start - checklist

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

Description

Hi Team,

We can see Black flash when we zoom a document using scale or rotate.
We started getting this issue when we updated to latest version of react-pdf 6.2.2.
This was working fine with react-pdf 5.7.2

Steps to reproduce

Open the document using react-pdf
Zoom the document by using scale option of Page
Document flickers and black flash appears between zoom change

Expected behavior

Document should zoom smoothly

Actual behavior

Flickering occurs with black flashing between zoom change

Additional information

No response

Environment

  • Browser (if applicable):
  • React-PDF version: 6.2.2
  • React version:16.14.2
  • Webpack version (if applicable):4
@bhanusingh431 bhanusingh431 added the bug Something isn't working label Feb 17, 2023
@HANYUNSEONG
Copy link

I'm experiencing the same error.
Below is a link that reproduces the error.
https://codesandbox.io/s/patient-grass-wsf85l?file=/package.json

@jb-thery
Copy link

jb-thery commented Mar 2, 2023

Same issue

@ezalorsara
Copy link

same issue is there an update to this. Thank you

@fiqrisr
Copy link

fiqrisr commented Mar 8, 2023

same issue here

@ezalorsara
Copy link

ezalorsara commented Mar 8, 2023

using renderMode="svg"
props in Document fixed the issue

but the issue is if you use that renderMode="svg" for pdf that was scanned no text. the canvas become only white

@MattL75
Copy link
Contributor

MattL75 commented Mar 16, 2023

Fix is here though not sure if it will be merged #1279.

@victorbojica
Copy link

Until @MattL75 pr is merged, this fixed it for me (basically what @MattL75 did):

Add this to your component that renders the Page

const containerRef = useRef<HTMLDivElement>();
 
 const hidePageCanvas = useCallback(() => {
   const canvas = containerRef.current.querySelector('canvas');
   if (canvas) canvas.style.visibility = 'hidden';
 }, [containerRef]);
 const showPageCanvas = useCallback(() => {
   const canvas = containerRef.current.querySelector('canvas');
   if (canvas) canvas.style.visibility = 'visible';
 }, [containerRef]);

 const onPageLoadSuccess = useCallback(() => {
   hidePageCanvas();
 }, [containerRef]);
 const onPageRenderSuccess = useCallback(() => {
   showPageCanvas();
 }, [containerRef]);
 const onPageRenderError = useCallback(() => {
   showPageCanvas();
 }, [containerRef]);

and attach to Page

<Page
   onLoadSuccess={onPageLoadSuccess}
   onRenderSuccess={onPageRenderSuccess}
   onRenderError={onPageRenderError}
/>

and make sure to add the ref to the container that holds the Document

@aseidma
Copy link

aseidma commented Mar 25, 2023

Until @MattL75 pr is merged, this fixed it for me (basically what @MattL75 did):

Add this to your component that renders the Page

const containerRef = useRef<HTMLDivElement>();
 
 const hidePageCanvas = useCallback(() => {
   const canvas = containerRef.current.querySelector('canvas');
   if (canvas) canvas.style.visibility = 'hidden';
 }, [containerRef]);
 const showPageCanvas = useCallback(() => {
   const canvas = containerRef.current.querySelector('canvas');
   if (canvas) canvas.style.visibility = 'visible';
 }, [containerRef]);

 const onPageLoadSuccess = useCallback(() => {
   hidePageCanvas();
 }, [containerRef]);
 const onPageRenderSuccess = useCallback(() => {
   showPageCanvas();
 }, [containerRef]);
 const onPageRenderError = useCallback(() => {
   showPageCanvas();
 }, [containerRef]);

and attach to Page

<Page
   onLoadSuccess={onPageLoadSuccess}
   onRenderSuccess={onPageRenderSuccess}
   onRenderError={onPageRenderError}
/>

and make sure to add the ref to the container that holds the Document

Great workaround for now!
Just make sure to replace containerRef in the useCallback hooks for onPageLoadSuccess, onPageRenderSuccess and onPageRenderError with showPageCanvas and hidePageCanvas, each being the one called in the respective function. This stops ESLint complaining about exhaustive deps, but shouldn't have an influence on functionality.

e.g.

 const onPageLoadSuccess = useCallback(() => {
   hidePageCanvas();
 }, [hidePageCanvas]); // hidePageCanvas instead of containerRef

This provides a workaround for every kind of rerender by the way, it's not just relevant for scale/rotate operations. The black flicker affects simply switching pages as well, therefore is probably present in the majority of use-cases.

@bhanusingh431
Copy link
Author

@victorbojica @aseidma
Thank you for the workaround.
I have implemented the above workaround, it is working only with page change. Black flicker still exists for scale and rotate change.

@SebiBasti
Copy link

On my page I'm still using the svg version for that reason. On resize I get heavy flickering with canvas.

@Meess
Copy link

Meess commented Jul 2, 2023

If it helps someone, using commonJs import made the flickering go away for me, waiting for patch in the mean time:

replace:

import { pdfjs } from 'react-pdf';
pdfjs.GlobalWorkerOptions.workerSrc = new URL('pdfjs-dist/legacy/build/pdf.worker.min.js', import.meta.url).toString();

With:

require('pdfjs-dist/build/pdf.worker.entry.js');

@wojtekmaj
Copy link
Owner

wojtekmaj commented Jul 13, 2023

This has already been addressed. Canvas was hidden during rendering in fc2ac76 and it shipped in v7.0.0-beta.3

@Bogdan2904
Copy link

Bogdan2904 commented Oct 12, 2023

I found a solution. I downloaded the script that we received using pdfjs.GlobalWorkerOptions.workerSrc = //cdnjs.cloudflare.com/ajax/libs/pdf.js/${pdfjs.version}/pdf.worker.min.js;
Here is the URL to the script - https://cdnjs.cloudflare.com/ajax/libs/pdf.js/3.11.174/pdf.worker.min.js. And imported locally with the following method pdfjs.GlobalWorkerOptions.workerSrc = require("./pdf.worker.main.js");

Now react-pdf works very fast and does not flicker.

Screenshot 2023-10-12 at 13 51 37

@huypham1411
Copy link

I found a solution. I downloaded the script that we received using pdfjs.GlobalWorkerOptions.workerSrc = //cdnjs.cloudflare.com/ajax/libs/pdf.js/${pdfjs.version}/pdf.worker.min.js; Here is the URL to the script - https://cdnjs.cloudflare.com/ajax/libs/pdf.js/3.11.174/pdf.worker.min.js. And imported locally with the following method pdfjs.GlobalWorkerOptions.workerSrc = require("./pdf.worker.main.js");

Now react-pdf works very fast and does not flicker.

Screenshot 2023-10-12 at 13 51 37

Hi, I'm using the latest version now but still got flickering issue, I've also tried your solution but the issue is still occurs, I received pdf file from BE side and then convert the response to base64 pdf file so I wonder if anyone here did the same flow as mine, here is some part of the code

  const options = {
    cMapUrl: '/cmaps/',
    standardFontDataUrl: '/standard_fonts/',
  };

  function onDocumentLoadSuccess({
    numPages: nextNumPages,
  }: PDFDocumentProxy): void {
    if (nextNumPages > 0) {
      setNumPages(nextNumPages);
    }
  }
..........
      <div ref={wrapperDiv} className="flex justify-center">
        {file ? (
          <Document
            file={file}
            onLoadSuccess={onDocumentLoadSuccess}
            options={options}
            loading={null}
          >
            {numPages &&
              Array.from(new Array(numPages), (el, index) => (
                <Page
                  key={`page_${index + 1}`}
                  pageNumber={index + 1}
                  width={width || 375}
                  renderTextLayer={false}
                  renderAnnotationLayer={false}
                  loading={null}
                />
              ))}
          </Document>
        ) : (
          <Spin className="h-screen" size="large" />
        )}
      </div>

hope someone can help

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests