Reputation: 381
How can I programmatically:
Using the locations in the native PDF coordinate system?
The goal here is to be able to, for example, highlight all occurrences of a phrase or add interactive design elements that are positioned according to the location of text that I have already parsed out of the document on the back end.
As a specific example, if know the phrase 'This is my Text.' is located on page 4 of my pdf document, and the box defining the position of this text on the page in the native pdf coordinate system is
bottom left corner = (0,0)
top right corner = (14, 5)
Is it possible to 1) scroll down to that line of the document so it is visible, and 2) overlay a div over this location?
I see that this is essentially what the built in 'text search', 'find next', and 'find prev' functionality it doing, but having some trouble interpreting the code.
Upvotes: 9
Views: 8743
Reputation: 2691
PDF.js defines so called PageViewport which allows to convert between PDF coordinates and presentation on the screen. To create a viewport see PDF page's getViewport. Convert coordinates to on-screen presentation: var screenRect = viewport.convertToViewportRectangle([0, 0, 14, 5]);
Normalize coordinates and overlay div on the canvas.
API for the generic viewer is not defined yet. However you can get a page view using viewer component: var pageView = PDFViewerApplication.pdfViewer.getPageView(3); // get page 4 view
. The pageView will have viewport
and div
-container. (Since API is not defined yet, names and arguments might change) If you are using viewers containers, please notice that they are periodically cleaned up during zooming/scroll -- draw your stuff after pagerendered
event.
Scrolling is just showing pageView.div
at the region screenRect
in the current view.
var pageNumber = 4;
var pdfRect = [0,0,140,150];
var pageView = PDFViewerApplication.pdfViewer.getPageView(pageNumber - 1);
var screenRect = pageView.viewport.convertToViewportRectangle(pdfRect);
var x = Math.min(screenRect[0], screenRect[2]), width = Math.abs(screenRect[0] - screenRect[2]);
var y = Math.min(screenRect[1], screenRect[3]), height = Math.abs(screenRect[1] - screenRect[3]);
// note: needs to be done in the 'pagerendered' event
var overlayDiv = document.createElement('div');
overlayDiv.setAttribute('style', 'background-color: rgba(255,255,0,0.5);position:absolute;' +
'left:' + x + 'px;top:' + y + 'px;width:' + width + 'px;height:' + height + 'px;');
pageView.div.appendChild(overlayDiv);
// scroll
scrollIntoView(pageView.div, {top: y});
Upvotes: 10