2013-08-05 137 views
5

我已經使用pdf.js來創建一個簡單的PDF查看器,其中有兩頁並排顯示下一個,上一個按鈕和一些其他功能。我使用了pdf.js回購的helloworld示例,因爲viewer.js文件對於像我這樣的noob來說太複雜了。但是,當我點擊上一個/下一個按鈕幾次時,pdf.js將呈現所有頁面而不是預期的最後一頁。它造成一團糟。下面的pdf.js例子有同樣的問題。 http://jsbin.com/pdfjs-prevnext-v2/1/edit(鏈接似乎只在Firefox中工作。)暫停pdf.js頁面呈現

我想知道什麼方式使pdf.js只呈現下一個/上一個按鈕到達的最後一頁。 pdf.js api對我沒有多大幫助。希望我會在這裏得到一些指導。提前致謝。

回答

3

如果我理解你的問題,我可能會有一個解決方案。 當我點擊上一個或下一個按鈕的速度太快時,畫布沒有時間刷新,並且繪製了兩個(或更多)頁面,這是不可讀的。

爲了解決這個問題,我使用下面的代碼:

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

我也曾在pdf.js文件修改的渲染功能:

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. 

(在我pdf.js文件這是在第2563和2596行之間)。

因此,即使您在上一個/下一個按鈕上點擊得非常快,在上一頁完全繪製之前,不會繪製新頁面!

的其他解決方案是取消前繪圖:

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

我希望它會幫助你,爲我的英語很抱歉;) 有一個愉快的一天

+0

我已經嘗試這樣做,它似乎工作比以前好多了,但我仍然面對的問題,同時也點擊fast.I如果你正面臨着不知道它也。我希望我可以禁用按鈕,直到畫布完全加載,我嘗試使用window.onload(),沒有工作,因爲畫布需要更長的時間加載。 pdf.js的完整viewer.html具有暫停功能,但無法弄清楚他們是如何做到的。 – sss

+0

我只試過你的第一個解決方案,讓我看看第二個解決方案。非常感謝你的努力,你的英語很棒。 :) – sss

+0

我試着取消先前的繪圖,但是timestamp = pageTimestamp;錯誤時間戳是未定義的,所以我將代碼更改爲var timestamp = pageTimestamp;現在它永遠不會進入if(timestamp!= pageTimestamp)條件,因爲它們總是相等的。我究竟做錯了什麼 ?再次提前感謝。 :) – sss

0

關於第二個解決方案,您必須在函數外部創建變量timestamp,例如在文件的開頭。如果在函數內部聲明timestamp,則該變量僅在執行該函數期間存在,並且不能工作。是你能做到以下幾點:

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

告訴我,如果這是確定現在

+0

非常感謝,這很有魅力。你是救生員。欣賞它。 :) – sss

4

我有同樣的問題,解決它更容易。 的render()方法返回一個renderTask對象,它看起來像這樣:

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

renderTask.internalRenderTask原型具有cancel()方法可以停止渲染。 所以只記得renderTask.internalRenderTask對象,並在需要時調用cancel()

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

    // some code here 

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

2015:'page.render(...)'現在返回具有'cancel'方法的'renderTask'。 - >'this.renderTask = page.render(...);'。 –