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.42k stars 886 forks source link

Text layer misaligned after scrollIntoView() #1637

Closed pk-bt closed 8 months ago

pk-bt commented 1 year ago

Before you start - checklist

Description

After using the recipe for text highlight, I want to scroll to the found <mark>tags with scroll into view, after that the text layer is misaligned.

pdf0 pdf1 pdf3

Steps to reproduce

I am using this code to find and navigate through the <mark> elements.

const [objectsFound, setObjectsFound] = useState<HTMLCollection>()
const pdfRef = useRef<HTMLDivElement>(null) //pdf document ref

...
/*
  createMutatiuonObserver to detect when the textRenderer has updated the DOM 
  maybe there is another way to detect it, but I could not find it at the moment,
  onRenderTextLayerSuccess freezes the app
*/

useEffect(() => {
        if (pdfRef.current) {
            const observer = new MutationObserver(incrementMutaion);
            observer.observe(pdfRef.current, {
                attributes: true,
                characterData: true,
                childList: true,
                subtree: true
            });
            return () => observer.disconnect();
        }
    }, []);

//get mark objects and update state
useEffect(() => {
        const objects = pdfRef.current?.getElementsByTagName("mark")
        if (objects?.length !== objectsFound?.length) {
            setObjectsFound(objects)
        }
    }, [objectsFound, mutationCount]);

//navigate through the found elements and add class focused to change the background color
const focusMark = useCallback((prev: number, next: number) => {
        if(!objectsFound?.length)
            return
        objectsFound[next].className="focused"
        objectsFound[prev].className=""
        objectsFound[next].scrollIntoView()
    }, [objectsFound])

....
return (
  <Document file={props.fileUrl}
                     onLoadSuccess={onDocumentLoadSuccess}
                     className={"pdf-viewer-document"}
                     inputRef={pdfRef}
                >
                    {pages.map((page, i) => (
                        <div key={i}>
                            <Page  pageNumber={page}
                                        customTextRenderer={textRenderer}
                                        onLoadSuccess={() => setPagesCompleted(current => current + 1)}
                            />
                        </div>))
                    }
  </Document>
)

Expected behavior

Text layer is in place.

Actual behavior

Text layer is misaligned.

Additional information

Not happening with all documents. I think it is only happening on documents with marked content.

Using the same document from #1622

Environment

wojtekmaj commented 12 months ago

Looks like CSS issue. I'd need to see the actual app to see where it went south. Perhaps some global styles caused React-PDF styles to break up?

pk-bt commented 12 months ago

I have examined a little bit after your hint and I started disabling all the styles on the page, including global styles and inherited styles and when I disabled overflow: hidden in the react-pdf__Page__textContent textLayer class of the react-pdf styles, everything got back into place. What is strange, if I use other document without marked content everything is ok. Anyway here is the css for the react-pdf elements and their containers:

.pdf-viewer-cont {
  overflow: auto;
  padding: 5px;
}

.pdf-viewer-document {
  display: inline-block;
}

.react-pdf__Page{
  margin: 2px;
  display: inline-block;
  box-shadow: rgba(60, 64, 67, 0.3) 0 1px 2px 0, rgba(60, 64, 67, 0.15) 0 2px 6px 2px;
}

mark {
  opacity: 0.3;
  background: #ffff00;
  box-shadow: 0 2px 10px #ffff00;
  color: transparent;
  white-space: pre;
}

.focused {
  background: #0050b3;
  box-shadow: 0 2px 10px #0050b3;
}
github-actions[bot] commented 8 months ago

This issue is stale because it has been open 90 days with no activity. Remove stale label or comment or this issue will be closed in 14 days.

github-actions[bot] commented 8 months ago

This issue was closed because it has been stalled for 14 days with no activity.