Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

halting pdf.js page rendering

Tags:

pdf

pdf.js

I have used pdf.js to create a simple pdf viewer that has 2 pages side by side with next,previous buttons and some other features. I used the helloworld example available with the pdf.js repo as the viewer.js file was too complicated for a noob like me. However when I click the previous/next button several times pdf.js renders all the pages instead of the expected last page. It creates a mess. The following example by pdf.js have the same problem. http://jsbin.com/pdfjs-prevnext-v2/1/edit (link seems to work in firefox only.)

I want to know what are the ways to make pdf.js render only the last page reached by next/previous buttons. pdf.js api did not help me much. Hope I will get some guidance here. Thanks in advance.

like image 786
sss Avatar asked Aug 05 '13 23:08

sss


2 Answers

I have the same problem and solve it easier. The render() method returns a renderTask object which look like this:

renderTask: {
    internarRenedrTask: {...},
    promise: {...}
}

The prototype of renderTask.internalRenderTask has cancel() method which can halt rendering. So just remember renderTask.internalRenderTask object and call cancel() if needed:

render: function() {
    if (this.renderTask) {
        this.renderTask.cancel();
    }

    // some code here

    this.renderTask = page.render(...).internalRenderTask;
}
like image 98
Genovich Avatar answered Sep 20 '22 12:09

Genovich


If I understand well your problem, I might have a solution. When I clicked too fast on the buttons previous or next, the canvas had not the time to refresh, and two (or more) pages where drawn, it was unreadable.

To solve the problem, I use the following code :

var stop = false;
function goPrevious() {
    if (pageNum > 1 && !stop)
    {
        stop = true;
        pageNum--;
        renderPage(pageNum);
    }
}

function goNext() {
    if (pageNum < pdfDoc.numPages && !stop)
    {
        stop = true;
        pageNum++;
        renderPage(pageNum);
    }
}

I have also modified the render function in the pdf.js file :

 render: function PDFPageProxy_render(params) {
      this.renderInProgress = true;

      var promise = new Promise();
      var stats = this.stats;
      stats.time('Overall');
      // If there is no displayReadyPromise yet, then the operatorList was never
      // requested before. Make the request and create the promise.
      if (!this.displayReadyPromise) {
        this.displayReadyPromise = new Promise();
        this.destroyed = false;

        this.stats.time('Page Request');
        this.transport.messageHandler.send('RenderPageRequest', {
          pageIndex: this.pageNumber - 1
        });
      }

      var self = this;
      function complete(error) {
        self.renderInProgress = false;
        stop = false;
        if (self.destroyed || self.cleanupAfterRender) {
          delete self.displayReadyPromise;
          delete self.operatorList;
          self.objs.clear();
        }

        if (error)
          promise.reject(error);
        else
          promise.resolve();
      }
      var continueCallback = params.continueCallback;
//etc.

(in my pdf.js file, this is between lines 2563 and 2596).

As a result, no new page will be drawn until the previous page was entirely drawn, even if you click very very fast on the previous/next buttons !

An other solution could be to cancel the previous drawing :

function renderPage(num) {


pdfDoc.getPage(num).then(function(page) {

        // canvas resize
        viewport = page.getViewport(ratio);
        canvas.height = viewport.height;
        canvas.width = viewport.width;


        // draw the page into the canvas
        var pageTimestamp = new Date().getTime();
        timestamp = pageTimestamp;
        var renderContext = {
                canvasContext: ctx,
                viewport: viewport,
                continueCallback: function(cont) {
                    if(timestamp != pageTimestamp) {
                        return;
                    }
                    cont();
                }
        };
        page.render(renderContext);


        // update page numbers
        document.getElementById('page_num').textContent = pageNum;
        document.getElementById('page_count').textContent = pdfDoc.numPages;
    });
}

I hope it will help you, and sorry for my english ;) Have a nice day

like image 25
Elodie Avatar answered Sep 20 '22 12:09

Elodie