Skip to content

Instantly share code, notes, and snippets.

@yurydelendik
Last active June 18, 2024 11:46
Show Gist options
  • Save yurydelendik/f2b846dae7cb29c86d23 to your computer and use it in GitHub Desktop.
Save yurydelendik/f2b846dae7cb29c86d23 to your computer and use it in GitHub Desktop.
PDF.js get/show hightlight
function getHightlightCoords() {
var pageIndex = PDFViewerApplication.pdfViewer.currentPageNumber - 1;
var page = PDFViewerApplication.pdfViewer.getPageView(pageIndex);
var pageRect = page.canvas.getClientRects()[0];
var selectionRects = window.getSelection().getRangeAt(0).getClientRects();
var viewport = page.viewport;
var selected = selectionRects.map(function (r) {
return viewport.convertToPdfPoint(r.left - pageRect.x, r.top - pageRect.y).concat(
viewport.convertToPdfPoint(r.right - pageRect.x, r.bottom - pageRect.y));
});
return {page: pageIndex, coords: selected};
}
function showHighlight(selected) {
var pageIndex = selected.page;
var page = PDFViewerApplication.pdfViewer.getPageView(pageIndex);
var pageElement = page.canvas.parentElement;
var viewport = page.viewport;
selected.coords.forEach(function (rect) {
var bounds = viewport.convertToViewportRectangle(rect);
var el = document.createElement('div');
el.setAttribute('style', 'position: absolute; background-color: pink;' +
'left:' + Math.min(bounds[0], bounds[2]) + 'px; top:' + Math.min(bounds[1], bounds[3]) + 'px;' +
'width:' + Math.abs(bounds[0] - bounds[2]) + 'px; height:' + Math.abs(bounds[1] - bounds[3]) + 'px;');
pageElement.appendChild(el);
});
}
@vquilon
Copy link

vquilon commented Dec 30, 2021

@abhilashsajeev If you want to make annotations in the PDF file you need to modify the binary data of the file. To do that you need another library like https://pdf-lib.js.org/.

@achapman009
Copy link

achapman009 commented Jun 29, 2022

I am getting this weird overflow with this approach any idea why this might be the case?

the pdf viewer I am using is ngx-extended-pdf-viewer

image

@shessafridi I am having this same issue. Did you ever resolve this?

@vquilon
Copy link

vquilon commented Jun 29, 2022

I am getting this weird overflow with this approach any idea why this might be the case?
the pdf viewer I am using is ngx-extended-pdf-viewer
image

@shessafridi I am having this same issue. Did you ever resolve this?

This seems to be a problem in the style of hidden text layer. I mean, maybe you have other CSS that modify the text layers, for example the font-size, I recommend you, to use my solution from zero, no extra CSS or code.

I have a minimal solution in a Codepen. Only highgliht the texts, but in the javascript you can copy the text or other operations.

Minimalistic PDF selector

@nurullah
Copy link

nurullah commented Jul 8, 2022

I am getting this weird overflow with this approach any idea why this might be the case?
the pdf viewer I am using is ngx-extended-pdf-viewer
image

@shessafridi I am having this same issue. Did you ever resolve this?

As far as i remember this problem is caused by the textLayerMode property. You can try this property by giving 2 value.

const pdfViewer = new pdfjsViewer.PDFViewer({
  container,  
  eventBus,  
  linkService,  
  textLayerMode: 2  
})

@falxen
Copy link

falxen commented Jul 16, 2022

@vquilon Thanks for your codepen. https://codepen.io/vquilon/pen/zYdgjVV
Unfortunately, it doesn't seem to highlight anything for me - what paragraph or words is it meant to highlight? I was hoping to start off with your code: I'm trying to highlight a part of the PDF, when given the start index and end index (of how the text appears in the PDF).

@achapman009
Copy link

I am getting this weird overflow with this approach any idea why this might be the case?
the pdf viewer I am using is ngx-extended-pdf-viewer
image

@shessafridi I am having this same issue. Did you ever resolve this?

As far as i remember this problem is caused by the textLayerMode property. You can try this property by giving 2 value.

const pdfViewer = new pdfjsViewer.PDFViewer({
  container,  
  eventBus,  
  linkService,  
  textLayerMode: 2  
})

This is the correct answer. Fixed all issues.

@arty-ms
Copy link

arty-ms commented Nov 2, 2023

This solution is not useful for several reasons:

  1. It is an overlay on the top of the text, so it changes the view(color) of the text.
  2. On the tablets it will work with problems.
  3. The pdf.js TextLayer is rendered with incorrect fonts. That's why your highlight may be in incorrect place.
    The smooth way would be to make highlight using canvas. You need to construct charsMap of all characters rendered on the canvas by pdf.js. Then on mouse move you will need to find the char in charsMap and re-draw text with background on the top of pdf.js canvas. This drawing should be done in separate custom canvas.

@Mowmowj
Copy link

Mowmowj commented Jan 12, 2024

This solution is not useful for several reasons:

  1. It is an overlay on the top of the text, so it changes the view(color) of the text.
  2. On the tablets it will work with problems.
  3. The pdf.js TextLayer is rendered with incorrect fonts. That's why your highlight may be in incorrect place.
    The smooth way would be to make highlight using canvas. You need to construct charsMap of all characters rendered on the canvas by pdf.js. Then on mouse move you will need to find the char in charsMap and re-draw text with background on the top of pdf.js canvas. This drawing should be done in separate custom canvas.

Hi, I am working on this recently, I would like to discuss this with you.
About your problem :
No.1 you could add a svg layer under text layer to use rect to render the highlighted element then the text layer will not be changed.
No.2 curious to know why can't it work on tablet? cuz touch or something? (as i know ios selection have problem.)
No.3 you are right the text layer position is not 100% same with canvas text position. the canvas solution is great as i find the "apryse"(but it not open source and need pay) seems to use this solution. But I am not sure how much work need to do of this by self.

@dieggop
Copy link

dieggop commented Apr 26, 2024

Is possible to get only position of click on document? in points?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment