How to know if PDF.JS has finished rendering?

不问归期 提交于 2019-11-28 18:44:02

I was also struggling with this problem.. the solution that i used is:

//Step 1: store a refer to the renderer
var pageRendering = page.render(renderContext);
//Step : hook into the pdf render complete event
var completeCallback = pageRendering.internalRenderTask.callback;
pageRendering.internalRenderTask.callback = function (error) {
  //Step 2: what you want to do before calling the complete method                  
  completeCallback.call(this, error);
  //Step 3: do some more stuff
};

<script type="text/javascript">
  document.addEventListener("pagesloaded", function(e) {
   //do sth..
  });
</script>

worked for me

At the time of writing, this did work. I'm not sure if it still does.

PDFJS makes use of Promises. The easiest thing to do is the following:

page.render(renderContext).promise.then(function(){
  document.body.appendChild(canvas);
});

Using the textlayerrendered event worked for me:

document.addEventListener('textlayerrendered', function (event) {
  // was this the last page?
  if (event.detail.pageNumber === PDFViewerApplication.page) {
    console.log('Finished rendering!');
  }
}, true);

Lyon's solution of more robust. But this is the simplest solution I could find.

var renderTask = pdfPage.render(renderContext);
renderTask.promise.then(
  function pdfPageRenderCallback() {
    pageViewDrawCallback(null);
  },
  function pdfPageRenderError(error) {
    pageViewDrawCallback(error);
  }
);
barbossusus

While examining these solutions, I was having issues getting the renderContext, so I ended up using this approach listening to pagerendered:

document.addEventListener("pagerendered", function(e){

});

In my case, I just wanted to call some external function after the page was rendered, with minimal effort.

Hope this helps. Cheers!

I have changed my code in this way and it helped me what I wanted to do:

pageRendering = page.render(renderContext);
pageRendering.onData(function(){
    var myImage = new Image();
    myImage.src = document.getElementById('my-canvas-id').toDataURL();
    $('body').append(myImage);
});

This helps only if the specific page has finished rendering. it doesn't tell you about the rendering of all of the pages.

As it turns out, your first line, page.render(renderContext); returns a RenderTask object which has 3 properties:

  • internalRenderTask - an InternalRenderTask, duh
  • cancel - a function, presumably to allow you to cancel the rendering effort
  • promise - a jQuery Promise object

The Promise is the one you want. To make use of it, it goes like this:

page.render(renderContext).promise.then(function() {

//do something after the page is rendered here

});

Hope that helps.

If you want to render all pages of pdf document in different canvases, all one by one synchronously this is kind of solution:

index.html

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>PDF Sample</title>
    <script type="text/javascript" src="jquery.js"></script>
    <script type="text/javascript" src="pdf.js"></script>
    <script type="text/javascript" src="main.js">
    </script>
    <link rel="stylesheet" type="text/css" href="main.css">
</head>
<body id="body">  
</body>
</html>

main.css

canvas {
    display: block;
}

main.js

$(function() {  
    var filePath = "document.pdf";

    function Num(num) {
        var num = num;

        return function () {
            return num;
        }
    };

    function renderPDF(url, canvasContainer, options) {
        var options = options || {
                scale: 1.5
            },          
            func,
            pdfDoc,
            def = $.Deferred(),
            promise = $.Deferred().resolve().promise(),         
            width, 
            height,
            makeRunner = function(func, args) {
                return function() {
                    return func.call(null, args);
                };
            };

        function renderPage(num) {          
            var def = $.Deferred(),
                currPageNum = new Num(num);
            pdfDoc.getPage(currPageNum()).then(function(page) {
                var viewport = page.getViewport(options.scale);
                var canvas = document.createElement('canvas');
                var ctx = canvas.getContext('2d');
                var renderContext = {
                    canvasContext: ctx,
                    viewport: viewport
                };

                if(currPageNum() === 1) {                   
                    height = viewport.height;
                    width = viewport.width;
                }

                canvas.height = height;
                canvas.width = width;

                canvasContainer.appendChild(canvas);

                page.render(renderContext).then(function() {                                        
                    def.resolve();
                });
            })

            return def.promise();
        }

        function renderPages(data) {
            pdfDoc = data;

            var pagesCount = pdfDoc.numPages;
            for (var i = 1; i <= pagesCount; i++) { 
                func = renderPage;
                promise = promise.then(makeRunner(func, i));
            }
        }

        PDFJS.disableWorker = true;
        PDFJS.getDocument(url).then(renderPages);       
    };

    var body = document.getElementById("body");
    renderPDF(filePath, body);
});
Kiran

page.render is a promise so you have to do your stuff inside your success like below:

page.render({
  canvasContext: context,
  viewport: viewport
}).then(function() {
//do your stuff here });
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!