Get Current Viewer Coordinates

Hello,

Is it possible to get the middle point of the current viewer coordinates for a PDF Pages.
For example, when the user clicks something in a custom sidebar, I would like to add an annotation to the middle of their viewport.

Right now I can get the current page they are on but I am adding the annotation to 0,0 and letting them drag it to the proper location.

Thanks

Hey there!

This code should do the trick for you:

  document.getElementById('b1').onclick = () => {
    const rect = instance.docViewer.getExactViewportRegionRect(instance.docViewer.getCurrentPage())

    const centerX = rect.x2 / 2;
    const centerY = rect.y2 / 2;

    const RECT_WIDTH = 100;
    const RECT_HEIGHT = 100;

    const annot = new instance.Annotations.RectangleAnnotation();

    annot.X = centerX + (RECT_WIDTH / 2)
    annot.Y = centerY

    annot.Width = RECT_WIDTH;
    annot.Height = RECT_HEIGHT;

    annot.StrokeColor = new instance.Annotations.Color(255, 0, 0);
    annot.StrokeThickness = 2;

    instance.annotManager.addAnnotation(annot);
    instance.annotManager.redrawAnnotation(annot);
  }

The main part is:

const rect = instance.docViewer.getExactViewportRegionRect(instance.docViewer.getCurrentPage())

Which gets the current coordinates of the viewport. To get the center point, you just need to divide the x2 and y2 values by two.

Let me know if you have any other questions!

Thanks,
Logan

Hello Logan,

Thank you for the response.
When I try and call that method it seems to return a value only sometimes, where most of the times it returns null. I am on the latest version of PDFExpress, and if I call console.log(instance.docViewer) I can see its initialized as I can get the current page.
image
The top is logging the docViewer itself, the middle is the current page number called by docViewer.getCurrentPage() and the buttom is logging the docViewer.getExactViewportRegionRect()
image

I can see this is something that was just added in the new version. Let me know if there is anything I can do to test / get this working.

Thanks,
Eric Greavette

Just to add onto this from my testing. The method works when the zoom is over 250% otherwise it returns null.

Hey!

Yeah that is the expected behaviour for that API actually - it only returns something if there is a viewport - AKA the full page isn’t rendered (I didn’t realize this when I wrote that snippet)

I’m working on a better code snippet for you - hold tight. This is a bit harder problem to solve than I thought.

Sorry about that!

Logan

Hey Eric, This should do the trick!

  const getCenter = function() {
    const viewerElement = docViewer.getScrollViewElement();
  
    const top = viewerElement.scrollTop + viewerElement.offsetTop;
    const bottom = top + viewerElement.offsetHeight;
    const left = viewerElement.scrollLeft + viewerElement.offsetLeft;
    const right = left + viewerElement.offsetWidth;
  
    const windowCoordinateCenter = {
      x: (left + right) / 2,
      y: (top + bottom) / 2
    };
  
    const displayMode = docViewer.getDisplayModeManager().getDisplayMode();
  
    const pageNumber = docViewer.getCurrentPage();
  
    const pageCoordinates = displayMode.windowToPage(windowCoordinateCenter, pageNumber);
  
    return pageCoordinates;
  };
  
  const addAnnotationToCenter = function() {
    const centerPageCoordinates = getCenter();
  
    const annotationWidth = 20;
    const annotationHeight = 20;
  
    const rectangleAnnot = new Annotations.RectangleAnnotation();
    rectangleAnnot.PageNumber = centerPageCoordinates.pageNumber;
    // values are in page coordinates with (0, 0) in the top left
    rectangleAnnot.X = centerPageCoordinates.x - (annotationWidth / 2);
    rectangleAnnot.Y = centerPageCoordinates.y - (annotationHeight / 2);
    rectangleAnnot.Width = annotationWidth;
    rectangleAnnot.Height = annotationHeight;
    rectangleAnnot.Author = annotManager.getCurrentUser();
  
    annotManager.addAnnotation(rectangleAnnot);
    // need to draw the annotation otherwise it won't show up until the page is refreshed
    annotManager.redrawAnnotation(rectangleAnnot);
  }

The main part is getCenter() which returns the center coordinates of the current view.

You can adjust the addAnnotationToCenter function to fit your use case.

Thanks!
Logan

This worked perfectly.
Thanks

1 Like