React-pdf: Getting current page number

Created on 7 Apr 2018  ·  7Comments  ·  Source: wojtekmaj/react-pdf

My app requires multiple pages to be rendered along with a table of content on the side. I got the multiple pages figured out, but wondering if if there's a way for me to get the current page the user is, in multiple page rendering option. Thanks in advance.

question

Most helpful comment

That should be doable :) Actually, it's a general web development question, and we won't be using anything React-PDF specific to achieve it.

Option 1

Add a listener on scroll and resize which would fire a function checking, which page is in the view. You can use the following function to check if a given element is in the view:

function isElementInViewport (el) {
    var rect = el.getBoundingClientRect();

    return (
      rect.bottom >= 0 && 
      rect.right >= 0 && 
      rect.top <= (window.innerHeight || document.documentElement.clientHeight) && 
      rect.left <= (window.innerWidth || document.documentElement.clientWidth)
    );
}

Then, iterate through all pages (eg. document.querySelectorAll('.react-pdf__Page').find(inElementInViewport)) and now you have the page which is in the viewport. Page number is attached to each <div> in data-page-number attribute.

Option 2

A little trickier option, but much better performance wise.

  • Add a listener on scroll and resize which measures two things:

    • The starting Y position of your first page. For example, if it's 200 pixels from the top of the screen, that should be 200.

    • The distance between top borders of two pages which are next to each other.

Say your results are:

firstPageY = 200;
pagesDeltaY = 600;

Now:

  • Create a function which on scroll would check, how far you have scrolled from the top. If you have a simple webpage with default scrolling, you'd be looking for window.scrollY.
  • Now that you have it, calculate which page is currently in view. For example, for scrollY between 200-800 it should return 1. For 800-1400 it should return 2, and so on.

General hint

Doing any action on scroll/resize is super costly. Try to use lodash.throttle or lodash.debounce.

All 7 comments

That should be doable :) Actually, it's a general web development question, and we won't be using anything React-PDF specific to achieve it.

Option 1

Add a listener on scroll and resize which would fire a function checking, which page is in the view. You can use the following function to check if a given element is in the view:

function isElementInViewport (el) {
    var rect = el.getBoundingClientRect();

    return (
      rect.bottom >= 0 && 
      rect.right >= 0 && 
      rect.top <= (window.innerHeight || document.documentElement.clientHeight) && 
      rect.left <= (window.innerWidth || document.documentElement.clientWidth)
    );
}

Then, iterate through all pages (eg. document.querySelectorAll('.react-pdf__Page').find(inElementInViewport)) and now you have the page which is in the viewport. Page number is attached to each <div> in data-page-number attribute.

Option 2

A little trickier option, but much better performance wise.

  • Add a listener on scroll and resize which measures two things:

    • The starting Y position of your first page. For example, if it's 200 pixels from the top of the screen, that should be 200.

    • The distance between top borders of two pages which are next to each other.

Say your results are:

firstPageY = 200;
pagesDeltaY = 600;

Now:

  • Create a function which on scroll would check, how far you have scrolled from the top. If you have a simple webpage with default scrolling, you'd be looking for window.scrollY.
  • Now that you have it, calculate which page is currently in view. For example, for scrollY between 200-800 it should return 1. For 800-1400 it should return 2, and so on.

General hint

Doing any action on scroll/resize is super costly. Try to use lodash.throttle or lodash.debounce.

I did take an approach similar to your option 1 and it was quite laggy with a large pdf. Will try option 2 and thanks for the tip on lodash.throttle or lodash.debounce. :) 👍

Another option, much more modern one and probably the best, but haven't tried this one yet - happy experimenting :)

https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API

Hey, I have a react app that creates a PDF and generates a link for the user to download the document. I want every page in the downloaded document to contain the page number. How do I achieve this using react-pdf?

I have read the doc countless times but I dont seem to find a solution that works

React-PDF only reads the PDFs. It does not allow writing to PDFs. You will not be able to add page numbers to PDFs using this package.

Hello, thanks for the reply.

Basically, I am not trying to write to an existing PDF document. I created
the document using @react-pdf/renderer. with , and
I added texts and an image to the document. Now all I want is for the
document to bear the page numbers in the process of creating the
document. Liike the first page bears 1, the second bears 2, etc.
Do you mean this is not also possible?

On Mon, Jul 20, 2020 at 10:23 AM Wojciech Maj notifications@github.com
wrote:

React-PDF only reads the PDFs. It does not allow writing to PDFs. You will
not be able to add page numbers to PDFs using this package.


You are receiving this because you commented.
Reply to this email directly, view it on GitHub
https://github.com/wojtekmaj/react-pdf/issues/184#issuecomment-660911843,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/AHF7IN75VIRXYBMXWJG5JATR4QEJFANCNFSM4EZLYNWQ
.

Wrong repository.

Was this page helpful?
0 / 5 - 0 ratings