Html 如何知道 PDF.JS 是否已完成渲染?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12693207/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-29 03:08:56  来源:igfitidea点击:

How to know if PDF.JS has finished rendering?

htmlcanvaspdf.js

提问by Malik Ahmed Khan Awan

I am using PDF.JS to render pdf pages into different canvas elements. my requirement is to capture the output of the canvas and to display it as an image. Is there some event to know if the rendering of the pdf page in canvas has been finished or not. because when I try to capture the output of canvas it is blank. but the pdf page is rendered properly. it looks like my capture event is being called before the pdf.js finishes the rendering process.

我正在使用 PDF.JS 将 pdf 页面呈现为不同的画布元素。我的要求是捕获画布的输出并将其显示为图像。是否有一些事件可以知道画布中 pdf 页面的渲染是否已完成。因为当我尝试捕获画布的输出时它是空白的。但 pdf 页面已正确呈现。看起来我的捕获事件在 pdf.js 完成渲染过程之前被调用。

here is my code:

这是我的代码:

page.render(renderContext);
var myImage = new Image();
myImage.src = document.getElementById('my-canvas-id').toDataURL();
$('body').append(myImage);

If I execute the same code in my FireFox's console this works fine. so nothing is wrong with this code.

如果我在我的 FireFox 的控制台中执行相同的代码,这工作正常。所以这段代码没有问题。

Just to let you people know that I already have tried document.ready and window.load events.

只是为了让大家知道我已经尝试过 document.ready 和 window.load 事件。

采纳答案by Lyon

I was also struggling with this problem.. the solution that i used is:

我也在努力解决这个问题..我使用的解决方案是:

//Step 1: store a refer to the renderer
var pageRendering = page.render(renderContext);
//Step : hook into the pdf render complete event
var completeCallback = pageRendering.internalRenderTask.callback;
pageRendering.internalRenderTask.callback = function (error) {
  //Step 2: what you want to do before calling the complete method                  
  completeCallback.call(this, error);
  //Step 3: do some more stuff
};

回答by myuce

<script type="text/javascript">
  document.addEventListener("pagesloaded", function(e) {
   //do sth..
  });
</script>

worked for me

为我工作

回答by sluijs

At the time of writing, this did work. I'm not sure if it still does.

在撰写本文时,这确实有效。我不确定它是否仍然存在。

PDFJS makes use of Promises. The easiest thing to do is the following:

PDFJS 使用Promises. 最简单的方法如下:

page.render(renderContext).promise.then(function(){
  document.body.appendChild(canvas);
});

回答by Luc

Using the textlayerrenderedevent worked for me:

使用该textlayerrendered事件对我有用:

document.addEventListener('textlayerrendered', function (event) {
  // was this the last page?
  if (event.detail.pageNumber === PDFViewerApplication.page) {
    console.log('Finished rendering!');
  }
}, true);

回答by Chris D'Aoust

Lyon's solution of more robust. But this is the simplest solution I could find.

里昂的解决方案更加稳健。但这是我能找到的最简单的解决方案。

var renderTask = pdfPage.render(renderContext);
renderTask.promise.then(
  function pdfPageRenderCallback() {
    pageViewDrawCallback(null);
  },
  function pdfPageRenderError(error) {
    pageViewDrawCallback(error);
  }
);

回答by barbossusus

While examining these solutions, I was having issues getting the renderContext, so I ended up using this approach listening to pagerendered:

在这些解决方案,我有得到的问题renderContext,所以我结束了使用这种方法听pagerendered

document.addEventListener("pagerendered", function(e){

});

In my case, I just wanted to call some external function after the page was rendered, with minimal effort.

就我而言,我只是想在页面呈现后调用一些外部函数,而只需最少的努力。

Hope this helps. Cheers!

希望这可以帮助。干杯!

回答by Malik Ahmed Khan Awan

I have changed my code in this way and it helped me what I wanted to do:

我以这种方式更改了我的代码,它帮助了我想要做的事情:

pageRendering = page.render(renderContext);
pageRendering.onData(function(){
    var myImage = new Image();
    myImage.src = document.getElementById('my-canvas-id').toDataURL();
    $('body').append(myImage);
});

This helps only if the specific page has finished rendering. it doesn't tell you about the rendering of all of the pages.

仅当特定页面已完成呈现时,这才有帮助。它不会告诉您所有页面的渲染。

回答by Vladimir Trifonov

If you want to render all pages of pdf document in different canvases, all one by one synchronously this is kind of solution:

如果你想在不同的画布中渲染pdf文档的所有页面,所有页面都同步同步,这是一种解决方案:

index.html

索引.html

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>PDF Sample</title>
    <script type="text/javascript" src="jquery.js"></script>
    <script type="text/javascript" src="pdf.js"></script>
    <script type="text/javascript" src="main.js">
    </script>
    <link rel="stylesheet" type="text/css" href="main.css">
</head>
<body id="body">  
</body>
</html>

main.css

主文件

canvas {
    display: block;
}

main.js

主文件

$(function() {  
    var filePath = "document.pdf";

    function Num(num) {
        var num = num;

        return function () {
            return num;
        }
    };

    function renderPDF(url, canvasContainer, options) {
        var options = options || {
                scale: 1.5
            },          
            func,
            pdfDoc,
            def = $.Deferred(),
            promise = $.Deferred().resolve().promise(),         
            width, 
            height,
            makeRunner = function(func, args) {
                return function() {
                    return func.call(null, args);
                };
            };

        function renderPage(num) {          
            var def = $.Deferred(),
                currPageNum = new Num(num);
            pdfDoc.getPage(currPageNum()).then(function(page) {
                var viewport = page.getViewport(options.scale);
                var canvas = document.createElement('canvas');
                var ctx = canvas.getContext('2d');
                var renderContext = {
                    canvasContext: ctx,
                    viewport: viewport
                };

                if(currPageNum() === 1) {                   
                    height = viewport.height;
                    width = viewport.width;
                }

                canvas.height = height;
                canvas.width = width;

                canvasContainer.appendChild(canvas);

                page.render(renderContext).then(function() {                                        
                    def.resolve();
                });
            })

            return def.promise();
        }

        function renderPages(data) {
            pdfDoc = data;

            var pagesCount = pdfDoc.numPages;
            for (var i = 1; i <= pagesCount; i++) { 
                func = renderPage;
                promise = promise.then(makeRunner(func, i));
            }
        }

        PDFJS.disableWorker = true;
        PDFJS.getDocument(url).then(renderPages);       
    };

    var body = document.getElementById("body");
    renderPDF(filePath, body);
});

回答by witttness

As it turns out, your first line, page.render(renderContext);returns a RenderTaskobject which has 3 properties:

事实证明,您的第一行page.render(renderContext);返回一个RenderTask具有 3 个属性的对象:

  • internalRenderTask- an InternalRenderTask, duh
  • cancel- a function, presumably to allow you to cancel the rendering effort
  • promise- a jQuery Promiseobject
  • internalRenderTask- 一个InternalRenderTask,呃
  • 取消- 一个函数,大概是为了让你取消渲染工作
  • promise- 一个 jQueryPromise对象

The Promise is the one you want. To make use of it, it goes like this:

承诺是你想要的。要使用它,它是这样的:

page.render(renderContext).promise.then(function() {

//do something after the page is rendered here

});

page.render(renderContext) .promise .then(function() {

//do something after the page is rendered here

});

Hope that helps.

希望有帮助。

回答by Kiran

page.render is a promise so you have to do your stuff inside your success like below:

page.render 是一个承诺,所以你必须在你的成功中做你的事情,如下所示:

page.render({
  canvasContext: context,
  viewport: viewport
}).then(function() {
//do your stuff here });