Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Callback for when PDF is finished rendering? #5601

Closed
evisiion opened this issue Dec 30, 2014 · 18 comments
Closed

Callback for when PDF is finished rendering? #5601

evisiion opened this issue Dec 30, 2014 · 18 comments

Comments

@evisiion
Copy link

I need to render a gradient to cover the bottom half of the rendered PDF. I'm working for a newspaper and we're doing an app that shows the paper with a teaser before subscribing.

The problem is, the gradient needs to be painted on top of the PDF, so it has to wait until the PDF is finished rendering. In fact, on mobile browsers attempting the gradient rendering before the PDF is finished results in extremely wild behavior (the canvas re-renders and blinks every time the page scrolls even a bit) resulting in constant re-paints and the content will render upside down sometimes.

So quite simply, I need to run a callback when the PDF has finished rendering.

Can you guys support callbacks? Or send out an event when the rendering is done?

@yurydelendik
Copy link
Contributor

We have 'pagerendered' event or render() returns promise. The generic viewer never renders all pages, so this will not be fixable for the viewer, unless we introduce a mode for the PDFViewer object when it renders all pages.

@yurydelendik yurydelendik removed the core label Dec 30, 2014
@evisiion
Copy link
Author

Ok, so a 'pagerendered' event is fired from which object? @yurydelendik

@yurydelendik
Copy link
Contributor

See https://github.com/mozilla/pdf.js/blob/master/web/pdf_viewer.js#L225 and example of usage at https://github.com/mozilla/pdf.js/blob/master/web/viewer.js#L1733

Please notice that we don't have API for viewer. Only API we released is for core and canvas rendering (see src/display/api.js).

@evisiion
Copy link
Author

@yurydelendik I am using this with canvas, in-browser. I'm kind of confused about where else PDF JS is even relevant. That confused me right away, but anyway, it looks like you have what I'm looking for. Thanks so much!

@timvandermeij
Copy link
Contributor

Closing as resolved.

@evisiion
Copy link
Author

I'm having trouble catching this event.

I listen (Jquery) for the pagerendered event as shown in the documents above:

$(document).bind('pagerendered', function (e) {
    console.log('Page rendering complete.');
    //do stuff
});

and render the PDF on canvas:

PDFJS.getDocument('my_file.pdf').then(function(pdf) {
    pdf.getPage(1).then(function(page) {
        /* .. snip .. */
        var scaledViewport = page.getViewport(scale);
        var canvas = document.getElementById('the-canvas');
        var context = canvas.getContext('2d');
        canvas.height = scaledViewport.height;
        canvas.width = scaledViewport.width;
        var renderContext = {
            canvasContext : context,
            viewport : scaledViewport
        };
        page.render(renderContext);
});

Triggering the event myself works successfully, so my listener is set up properly, and is attached long before page.render(renderContext) is called.

Perhaps I misunderstood the event's trigger. When exactly should the pagerendered event be fired from the document?

@yurydelendik

@yurydelendik
Copy link
Contributor

If you are not using the generic viewer, the event will not be triggered. Sorry, I don't understood what you are asking.

See https://github.com/mozilla/pdf.js/blob/master/examples/learning/prevnext.html#L76 to see how to wait for rendering to finish. jQuery will be less useful here, try to learn how to use Promises.

@evisiion
Copy link
Author

@yurydelendik I understand now, thank you so much for your time!

@lucdetellis
Copy link

Using the textlayerrendered event works for me:

document.addEventListener('textlayerrendered', function (e) {
  if (e.detail.pageNumber === PDFViewerApplication.page) {
    // finished rendering
  }
}, true);

@brendandahl
Copy link
Contributor

Using your snippet above you'd simply do:

page.render(renderContext).then(function() {
  console.log("FINISHED RENDERING!");
}, function() {
  console.log("ERROR");
});

@mibamur
Copy link

mibamur commented Feb 18, 2016

@brendandahl thanks )

@NinjaKC
Copy link

NinjaKC commented Nov 16, 2016

Thank you @lucdetellis ! I have been trying to have a button external to the viewer trigger the print functionality, but it would never work due to the error given. Using your solution inside of a function allowed me to trigger that function from the parent frame and then window.focus() and window.print() when finished rendering, and BAM, issue resolved.. Was looking all over for a solution on this :)

@JimVanG
Copy link

JimVanG commented Apr 2, 2017

document.addEventListener('textlayerrendered', function (e) {
  if (e.detail.pageNumber === PDFViewerApplication.page) {
    // finished rendering
  }
}, true);

Is never called for me...

I'm calling it like so (at the end viewer.js):

document.addEventListener('textlayerrendered', function (e) {
      console.log("textlayerrendered event called!");
    if (e.detail.pageNumber === PDFViewerApplication.page) {
    // finished rendering
      console.log("FINISHED RENDERING!");
      Android.makeWebViewVisible();
     } else {
     console.log("NOT DONE RENDERING!");
     }
}, true);

document.addEventListener('DOMContentLoaded', webViewerLoad, true);

Please forgive my javascript ignorance, I'm an Android developer trying to get js callbacks for when the PDF has finished rendering because I'm running into some Android specific issues... Any help would be greatly appreciated.

Updated:
The issue was that my Android WebView's visibility was not set to VISIBLE, so none of the JS events were being triggered.

@turquoise-turtle
Copy link

Using the viewer provided with pdf.js, pagesloaded event worked for me (I open the print dialog as soon as it is finished loading):

document.addEventListener('pagesloaded', function (e) {
	window.print();
}, true);

@diwakar1911
Copy link

diwakar1911 commented Feb 22, 2019

@turquoise-turtle did you attached to event Listener to the main document or to the iframe where you have the viewer?

var iframe = document.getElementById('iframe').contentDocument;

                            iframe.addEventListener('pagesloaded', function (e) {
                                alert("loaded");
                            }, true);

i'm doing this and it doesn't seem to work

@diwakar1911
Copy link

set "eventBusDispatchToDOM": true in viewer.js why isn't anyone telling this!

@turquoise-turtle
Copy link

It seems the default was changed to not dispatch events to DOM in around August to September, looking at #10019

@garaboncias
Copy link

please see: #10718 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests