wojtekmaj / react-pdf

Display PDFs in your React app as easily as if they were images.
https://projects.wojtekmaj.pl/react-pdf
MIT License
9.11k stars 867 forks source link

Flashing on resize #1705

Closed jonahallibone closed 6 months ago

jonahallibone commented 6 months ago

Before you start - checklist

Description

I am trying to make my PDF responsive, however, I continually run into the same issue where the PDF pages disappear and reappear during the render phase. This causes my container to lose height and thus resets the scroll, which is a 2nd order problem caused by this behavior. In the other threads I've seen about responsive width, I haven't seen anyone document this issue.. Is there any solution? I have already implemented the suggested fix for scaling (having two pages render depending on if the scale has changed or not). I was wondering if there was some similar work around for sizing, as I have not been able to figure it out.

https://github.com/wojtekmaj/react-pdf/assets/8886318/d6f3e5d9-0abd-4c73-a69c-a6a08ac70f4f

Steps to reproduce

This is roughly what my code looks like:

<PdfViewerContainer>
  <ChakraReactPdfDocument
    file={pdfUrl}
    onLoadSuccess={onDocumentLoadSuccess}
    loading={<Spinner />}
    height="min-content"
    minH="100%"
    margin="auto"
  >
    {display === "scroll" ? (
      pageArray.map((page) => (
        <Box
          boxShadow="xl"
          w="min-content"
          key={page}
          _notLast={{ mb: 3 }}
          marginLeft="auto"
          width={`${containerWidth - 32}px`}
        >
          {isPageRendering(page) ? (
            <Page
              key={`${page}@${getPageScale(page)}`}
              className="prevPage"
              pageNumber={page}
              scale={renderedPageScale[page]}
              width={containerWidth - 32}
            />
          ) : null}
          <Page
            key={`${page}@${scaleAsNumber}`}
            pageNumber={page}
            scale={scaleAsNumber}
            inputRef={(node) => setPageRef(node, page)}
            width={containerWidth - 32}
            onRenderSuccess={onRenderSuccess}
          />
        </Box>
      ))
    ) : (
      <Page pageNumber={Number(pageNumber)} />
    )}
  </ChakraReactPdfDocument>
</PdfViewerContainer>

Expected behavior

I expect the PDF to not flash when resizing it's parent container.

Actual behavior

The PDF disappears and reappears.

Additional information

No response

Environment

wojtekmaj commented 6 months ago

Duplicate of #418

trilliumsmith commented 4 months ago

Hey there,

Thanks for putting this project together, I'm using it to display a resume pdf on my portfolio site.

I'm having this problem as well where the container loses height on resize. It's a behaviour that exists in the next-app example as well. It's not a huge deal for me, but if the user changes their window width I'd like that to be as seamless as possible.

https://github.com/wojtekmaj/react-pdf/assets/5898009/5e345955-c09e-4e71-ae60-089cd0e7c092

In my usecase all the pages are rendered in sequence just like in the next-app example, so when the canvas loses height I get a series of flickering boxes for each page before rerender.

I tried to implement the solution from #418 but couldn't get it figured out.

Steps to reproduce

kauly commented 1 month ago

doing something like this fixed the problem here

  const onResize = useCallback<ResizeObserverCallback>((entries) => {
    const [entry] = entries

    if (entry) {
      setContainerWidth((p = 1) => {
        const newWidth = entry.contentRect.width
        return Math.abs(p - newWidth) > 50 ? newWidth : p
      })
    }
  }, [])