【问题标题】:halting pdf.js page rendering停止 pdf.js 页面渲染
【发布时间】:2013-08-06 19:49:53
【问题描述】:

我使用 pdf.js 创建了一个简单的 pdf 查看器,它有 2 页并排,带有下一个、上一个按钮和一些其他功能。我使用了 pdf.js 存储库中提供的 helloworld 示例,因为 viewer.js 文件对于像我这样的菜鸟来说太复杂了。但是,当我多次单击上一个/下一个按钮时,pdf.js 会呈现所有页面而不是预期的最后一页。它会造成混乱。 pdf.js 的以下示例有同样的问题。 http://jsbin.com/pdfjs-prevnext-v2/1/edit(链接似乎只在 Firefox 中有效。)

我想知道有什么方法可以让 pdf.js 只呈现下一个/上一个按钮到达的最后一页。 pdf.js api 对我帮助不大。希望我能在这里得到一些指导。提前致谢。

【问题讨论】:

    标签: pdf pdf.js


    【解决方案1】:

    我有同样的问题,解决起来更容易。 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;
    }
    

    【讨论】:

    • 2015: page.render(...) 现在返回具有cancel 方法的renderTask。 --> this.renderTask = page.render(...);.
    • @NinhPham 您能否提供更多有关如何访问此方法的信息,好吗?还是在 2019 年仍然有意义?
    • @Jansindl3r,它仍然可用。 mozilla.github.io/pdf.js/api/draft/RenderTask.html.
    • @Jansindl3r,看看examples,你会看到page.render(..)以及如何访问renderTask
    【解决方案2】:

    如果我能很好地理解您的问题,我可能会有一个解决方案。 当我在上一个或下一个按钮上单击得太快时,画布没有时间刷新,并且绘制了两个(或更多)页面,无法读取。

    为了解决这个问题,我使用以下代码:

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

    我希望它会帮助你,对不起我的英语;) 祝你有美好的一天

    【讨论】:

    • 我试过这个,它似乎比以前工作得更好,但是我在点击太快时仍然遇到这个问题。我不知道你是否也面临这个问题。我希望我可以禁用按钮,直到画布完全加载,我尝试使用 window.onload(),没有工作,因为画布需要更长的时间来加载。 pdf.js 的完整 viewer.html 具有停止功能,但无法弄清楚他们是如何做到的。
    • 我只试过你的第一个解决方案,让我看看第二个。非常感谢你的努力,你的英语很棒。 :)
    • 我尝试取消之前的绘图,但是 timestamp = pageTimestamp;给出了一个未定义的错误时间戳,所以我将代码更改为 var timestamp = pageTimestamp;现在它永远不会进入 if(timestamp != pageTimestamp) 条件,因为它们总是相等的。我究竟做错了什么 ?再次提前感谢。 :)
    • 第一种方案,即使我点击非常非常快,也可以,只绘制一页。
    【解决方案3】:

    关于第二种解决方案,您必须在函数外部创建变量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;
        });
    }
    

    告诉我现在还好吗

    【讨论】:

    • 非常感谢,这很有魅力。你是救生员。欣赏它。 :)
    猜你喜欢
    • 2017-03-20
    • 2015-02-19
    • 1970-01-01
    • 2020-11-27
    • 2015-08-02
    • 2010-10-31
    • 1970-01-01
    • 2010-12-28
    • 2013-08-24
    相关资源
    最近更新 更多