Closed ShashanKV98 closed 1 month ago
Has a solution been posted for this? Would love to see a working fix for rendering the whole pdf without flashes. @wojtekmaj
Having a similar issue, I've tried all of the provided solutions regarding hiding the canvas while the PDF is rendering e.g. #1340 & #1279 however these do not have any impact on the canvas disappearing when "zooming" the document.
The demo PDFJS does not have this issue and unfortunately this flicker is creating a horrible UIX when zooming/panning around a single page PDF.
From what I can tell, this wasn't an issue when using renderMode="svg"
however that has been deprecated in the newer versions 😕 any guidance from others would be greatly appreciated!
This solution worked for me, albeit I have no idea why since this was quite long ago on a project I've since stopped working on. I'm quite new to React in general, but perhaps this may be of use.
export const PDFView = ({ pdfURL }) => {
const [numPages, setNumPages] = useState(null)
// Config variables
const initialWidth = 405
const stepSize = 0.5
const magnifierMax = 4
const { scale, newScale, pageVisible, scaleUp, scaleDown, scaleReset, togglePageVisibility } =
usePDFScaling(initialWidth, stepSize, magnifierMax)
useElectronAPI(scaleUp, scaleDown, scaleReset)
return (
<Document file={pdfURL} onLoadSuccess={({ numPages }) => setNumPages(numPages)}>
{numPages &&
Array.from(new Array(numPages), (_el, index) => (
<React.Fragment key={`container_${index + 1}`}>
<Page
className={`mb-2 ${pageVisible ? 'visible' : 'hidden'}`}
key={`front_page_${index + 1}`}
pageNumber={index + 1}
scale={pageVisible ? scale : newScale}
width={initialWidth}
onRenderSuccess={pageVisible ? null : togglePageVisibility}
/>
<Page
className={`mb-2 ${pageVisible ? 'hidden' : 'visible'}`}
key={`back_page_${index + 1}`}
pageNumber={index + 1}
scale={pageVisible ? newScale : scale}
width={initialWidth}
onRenderSuccess={pageVisible ? togglePageVisibility : null}
/>
</React.Fragment>
))}
</Document>
)
}
export const useElectronAPI = (scaleUp, scaleDown, scaleReset) => {
useEffect(() => {
const handleZoom = (_event, action) => {
switch (action) {
case 'zoom-in':
scaleUp()
break
case 'zoom-out':
scaleDown()
break
case 'zoom-reset':
scaleReset()
break
}
}
window.electronAPI.onMenuAction(handleZoom)
return () => {
window.electronAPI.removeMenuActionListener(handleZoom)
}
}, [scaleUp, scaleDown, scaleReset])
}
export const usePDFScaling = (initialWidth, stepSize, magnifierMax) => {
const [scale, setScale] = useState(1.0)
const [newScale, setNewScale] = useState(1.0)
const [pageVisible, setPageVisible] = useState(true)
const minWidth = initialWidth / magnifierMax
const maxWidth = initialWidth * magnifierMax
const scaleUp = () => {
setNewScale((prevScale) => Math.min(prevScale + stepSize, maxWidth / initialWidth))
}
const scaleDown = () => {
setNewScale((prevScale) => Math.max(prevScale - stepSize, minWidth / initialWidth))
}
const scaleReset = () => {
const windowWidth = window.innerWidth
const resetScale = (windowWidth * 0.45) / initialWidth
setNewScale(resetScale)
setScale(resetScale)
}
useEffect(() => {
scaleReset()
}, [])
const togglePageVisibility = () => {
if (newScale !== scale) {
setPageVisible(!pageVisible)
setScale(newScale)
}
}
return { scale, newScale, pageVisible, scaleUp, scaleDown, scaleReset, togglePageVisibility }
}
Thanks. But it seems to have the same issue. I switched the electron API part with buttons in react for scaling. I am beginning to think that since page.render
re creates from scratch, pages with heavy graphics tend to flicker or take time to render. I wonder if it's possible to just render the portion of the pdf in the viewport and not all the pages with every scale change or maybe utilizing an offscreencanvas, but I'm not sure how to go about it.
Duplicate of #1705 Duplicate of #875 Duplicate of #418
Hi @wojtekmaj I've seen those issues but I just can't get the performance to be even close to how pdfjs does it (seems like it only renders the text part) . The conditional rendering does a decent job but it is not robust for bigger files. Can you please maybe point me in the direction of how to handle this or if you have any ideas I might try?
Before you start - checklist
Description
Hi. I had some issues when dealing with zooming a document with all pages in a column (not just a single page). I browsed the issues in this repo, and found a sandbox link from @wojtekmaj https://github.com/wojtekmaj/react-pdf/issues/875#issuecomment-977975073.
This was for a single page in the viewport, so I extended it to include all the pages. The first page seems to render just fine as I use the slider, but the rest of the pages tend to flicker a lot. I've been on this for days but couldn't figure out if this is because of React or
page.render
refreshing the entire page from scratch at every new scale value or something else that I'm missing.I'm also curious about the recommended approach for handling zooming with this library. Is it possible to get it close to how pdf.js viewer handles zooming?
Thanks and appreciate the work put into this library.
Steps to reproduce
Attached a codesandbox link showing this behavior.
https://codesandbox.io/p/sandbox/react-pdf-prevent-flash-with-scale-forked-pwcw8z
Expected behavior
Flickering for all pages is supposed to be minimal to none
Actual behavior
The first page doesn't flicker but the subsequent pages do.
Additional information
No response
Environment