我正在使用PDF.JS将pdf页面渲染到不同的画布元素中。我的要求是捕获画布的输出并将其显示为图像。是否有一些事件要知道画布中的pdf页面的渲染是否已经完成。因为当我尝试捕获画布的输出时,它是空白的。但pdf页面正确呈现。看起来我的捕获事件是在pdf.js完成渲染过程之前调用的。
这是我的代码:
page.render(renderContext);
var myImage = new Image();
myImage.src = document.getElementById('my-canvas-id').toDataURL();
$('body').append(myImage);
如果我在FireFox的控制台中执行相同的代码,这可以正常工作。所以这段代码没什么问题。
只是为了让你们知道我已经尝试过document.ready和window.load事件。
我也在努力解决这个问题..我使用的解决方案是:
//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
};
page.render是一个承诺,所以你必须在你的成功中做你的事情,如下所示:
page.render({
canvasContext: context,
viewport: viewport
}).then(function() {
//do your stuff here });
<script type="text/javascript">
document.addEventListener("pagesloaded", function(e) {
//do sth..
});
</script>
为我工作
在撰写本文时,这确实有效。我不确定它是否仍然存在。
PDFJS使用Promises
。最简单的方法是:
page.render(renderContext).promise.then(function(){
document.body.appendChild(canvas);
});
使用textlayerrendered
事件为我工作:
document.addEventListener('textlayerrendered', function (event) {
// was this the last page?
if (event.detail.pageNumber === PDFViewerApplication.page) {
console.log('Finished rendering!');
}
}, true);
里昂的解决方案更加强大。但这是我能找到的最简单的解决方案。
var renderTask = pdfPage.render(renderContext);
renderTask.promise.then(
function pdfPageRenderCallback() {
pageViewDrawCallback(null);
},
function pdfPageRenderError(error) {
pageViewDrawCallback(error);
}
);
在检查这些解决方案时,我遇到了renderContext
的问题,所以我最终使用这种方法听pagerendered
:
document.addEventListener("pagerendered", function(e){
});
在我的情况下,我只是想在页面渲染后调用一些外部函数,只需要很少的努力。
希望这可以帮助。干杯!
我已经用这种方式更改了代码,它帮助了我想做的事情:
pageRendering = page.render(renderContext);
pageRendering.onData(function(){
var myImage = new Image();
myImage.src = document.getElementById('my-canvas-id').toDataURL();
$('body').append(myImage);
});
仅当特定页面已完成渲染时,这才有用。它没有告诉你所有页面的渲染。
事实证明,你的第一行,page.render(renderContext);
返回一个RenderTask
对象,它有3个属性:
InternalRenderTask
,duhPromise
对象承诺是你想要的。要使用它,它是这样的:
page.render(renderContext).promise.then(function(){
//do something after the page is rendered here
});
希望有所帮助。
如果你想在不同的画布中渲染pdf文档的所有页面,所有这些都是同步的,这是一种解决方案:
的index.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);
});