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.
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;
}
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With