2013-08-05 9 views
5

Ich habe pdf.js verwendet, um einen einfachen PDF-Viewer zu erstellen, der 2 Seiten nebeneinander mit den nächsten, vorherigen Schaltflächen und einigen anderen Funktionen hat. Ich habe das Helloworld-Beispiel verwendet, das mit dem Reposeditor pdf.js verfügbar ist, da die Datei viewer.js für einen Neuling wie mich zu kompliziert war. Wenn ich jedoch mehrmals auf den vorherigen/nächsten Knopf klicke, rendert pdf.js alle Seiten statt der erwarteten letzten Seite. Es schafft ein Durcheinander. Das folgende Beispiel von pdf.js hat das gleiche Problem. http://jsbin.com/pdfjs-prevnext-v2/1/edit (Link scheint nur in Firefox zu funktionieren.)stockend pdf.js page rendering

Ich möchte wissen, was die Möglichkeiten sind, pdf.js render nur die letzte Seite von nächsten/vorherigen Schaltflächen zu machen. pdf.js api hat mir nicht viel geholfen. Ich hoffe, ich werde hier Anleitung bekommen. Danke im Voraus.

Antwort

3

Wenn ich Ihr Problem gut verstehe, könnte ich eine Lösung haben. Wenn ich zu schnell auf die Schaltflächen vorherigen oder nächsten geklickt hatte, hatte die Leinwand nicht die Zeit zum Aktualisieren, und zwei (oder mehr) Seiten wurden gezeichnet, es war nicht lesbar.

das Problem zu lösen, verwende ich den folgenden 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); 
    } 
} 

ich auch die Render-Funktion in der Pdf.js Datei geändert haben:

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 meiner Pdf.js Datei , dies ist zwischen den Zeilen 2563 und 2596).

Als Ergebnis wird keine neue Seite gezeichnet, bis die vorherige Seite vollständig gezeichnet wurde, selbst wenn Sie sehr schnell auf die vorherigen/nächsten Schaltflächen klicken!

Eine andere Lösung, die die vorherige Zeichnung könnte abbrechen:

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; 
    }); 
} 

ich es Ihnen helfen, hoffen, und sorry für mein Englisch;) einen schönen Tag

+0

Ich habe dies versucht, und es schien, besser zu arbeiten als zuvor, aber immer noch ich die Frage stellen, während ein zu fast.I klicken weiß nicht, ob Sie konfrontiert sind es auch. Ich wünschte, ich könnte die Tasten deaktivieren, bis die Zeichenfläche vollständig geladen wurde, habe ich versucht mit window.onload(), hat nicht funktioniert, wie Leinwand dauert länger zum Laden. Die komplette viewer.html von pdf.js hat die Haltefunktion, kann aber nicht herausfinden, wie sie es gemacht hat. – sss

+0

Ich habe nur Ihre erste Lösung ausprobiert, lassen Sie mich die zweite auschecken. Vielen Dank für Ihre Mühe und Ihr Englisch ist großartig. :) – sss

+0

Ich habe versucht, die vorherige Zeichnung abzubrechen, jedoch timestamp = pageTimestamp; gab einen Fehler Timestamp, der undefiniert ist, so änderte ich Code zu var timestamp = pageTimestamp; und jetzt kommt es nie in die Bedingung if (timestamp! = pageTimestamp), da sie immer gleich sind. Was mache ich falsch ? Nochmals vielen Dank im Voraus. :) – sss

0

Bezüglich der zweiten Lösung, Sie müssen die Variable timestamp außerhalb der Funktion erstellen, zum Beispiel am Anfang der Datei. Wenn Sie innerhalb der Funktion timestamp deklarieren, existiert die Variable nur während der Ausführung der Funktion und kann nicht funktionieren. S Sie folgendes tun:

var timestamp; 
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; 
    }); 
} 

Sag mir, wenn es in Ordnung ist jetzt

+0

Vielen Dank, das funktioniert wie ein Zauber. Du bist ein Lebensretter. Bin dankbar. :) – sss

4

ich das gleiche Problem und lösen es einfacher. Die render() Methode gibt ein renderTask Objekt, das wie folgt aussehen:

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

Der Prototyp renderTask.internalRenderTask hat cancel() Methode, die Rendering anhalten kann. Also denken Sie daran nur renderTask.internalRenderTask Objekt und cancel() rufen, wenn nötig:

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

    // some code here 

    this.renderTask = page.render(...).internalRenderTask; 
} 
+0

2015: 'page.render (...)' gibt jetzt eine 'renderTask' zurück, die' cancel' Methode hat. -> 'this.renderTask = page.render (...);'. –