web-dev-qa-db-fra.com

Comment savoir si PDF.JS a terminé le rendu?

J'utilise PDF.JS pour rendre des pages PDF en différents éléments de toile. Mon exigence est de capturer la sortie du canevas et de l’afficher sous forme d’image. Existe-t-il un événement pour savoir si le rendu de la page pdf dans la zone de dessin est terminé ou non. parce que quand j'essaie de capturer la sortie de la toile, elle est vide. mais la page pdf est rendue correctement. il semble que mon événement de capture soit appelé avant que le fichier pdf.js ne termine le processus de rendu.

voici mon code:

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

Si j'exécute le même code dans la console de FireFox, cela fonctionne correctement. donc rien ne va pas avec ce code. 

Juste pour que vous sachiez que j'ai déjà essayé les événements document.ready et window.load.

23

Je me battais aussi avec ce problème .. la solution que j'ai utilisée est:

//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
};
21
Lyon

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

a travaillé pour moi

17
myuce

Au moment de l'écriture, cela a fonctionné. Je ne sais pas si c'est toujours le cas.

PDFJS utilise Promises. La chose la plus facile à faire est la suivante:

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

Utiliser l'événement textlayerrendered a fonctionné pour moi:

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

La solution lyonnaise de plus robuste. Mais c'est la solution la plus simple que j'ai pu trouver.

var renderTask = pdfPage.render(renderContext);
renderTask.promise.then(
  function pdfPageRenderCallback() {
    pageViewDrawCallback(null);
  },
  function pdfPageRenderError(error) {
    pageViewDrawCallback(error);
  }
);
4
Chris D'Aoust

Lors de l’examen de ces solutions, j’avais des problèmes pour obtenir le "renderContext";

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

            });

Dans mon cas, je voulais juste appeler une fonction externe après le rendu de la page, avec un minimum d’effort.

J'espère que cela t'aides. À votre santé!

3
barbossusus

J'ai changé mon code de cette manière et cela m'a aidé à faire ce que je voulais faire:

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

Cela aide uniquement si le rendu de la page spécifique est terminé. il ne vous parle pas du rendu de toutes les pages.

1

Il s'avère que votre première ligne, page.render(renderContext);, renvoie un objet RenderTask qui possède 3 propriétés:

  • internalRenderTask - une InternalRenderTask, duh
  • cancel - une fonction, probablement pour vous permettre d'annuler le rendu
  • promesse - un jQuery Promise object

La promesse est celle que vous voulez. Pour s'en servir, ça se passe comme ça:

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

//do something after the page is rendered here

});

J'espère que cela pourra aider.

1
witttness

page.render est une promesse donc vous devez faire votre travail dans votre succès comme ci-dessous:

page.render({
  canvasContext: context,
  viewport: viewport
}).then(function() {
//do your stuff here });
0
Kiran

Si vous voulez rendre toutes les pages d'un document pdf dans différentes toiles, une par une, c'est une 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);
});
0