我正在使用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活动。
答案 0 :(得分:21)
我也在努力解决这个问题..我使用的解决方案是:
//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
};
答案 1 :(得分:17)
<script type="text/javascript">
document.addEventListener("pagesloaded", function(e) {
//do sth..
});
</script>
为我工作
答案 2 :(得分:12)
在撰写本文时,这确实有效。我不确定它是否仍然存在。
PDFJS使用Promises
。最简单的方法是:
page.render(renderContext).promise.then(function(){
document.body.appendChild(canvas);
});
答案 3 :(得分:5)
使用textlayerrendered
事件为我工作:
document.addEventListener('textlayerrendered', function (event) {
// was this the last page?
if (event.detail.pageNumber === PDFViewerApplication.page) {
console.log('Finished rendering!');
}
}, true);
答案 4 :(得分:4)
里昂的解决方案更加强大。但这是我能找到的最简单的解决方案。
var renderTask = pdfPage.render(renderContext);
renderTask.promise.then(
function pdfPageRenderCallback() {
pageViewDrawCallback(null);
},
function pdfPageRenderError(error) {
pageViewDrawCallback(error);
}
);
答案 5 :(得分:3)
在检查这些解决方案时,我遇到问题renderContext
,所以我最终使用这种方法听取pagerendered
:
document.addEventListener("pagerendered", function(e){
});
在我的情况下,我只是想在页面渲染后调用一些外部函数,只需要很少的努力。
希望这会有所帮助。干杯!
答案 6 :(得分:2)
根据来自 PDF.js 的文档。
对于 2.2 之前的版本使用:
page.render(renderContext).then(function(){
var myImage = new Image();
myImage.src = document.getElementById('my-canvas-id').toDataURL();
$('body').append(myImage);
});
对于 2.2 之后的版本,请使用:
page.render(renderContext).promise.then(function(){
var myImage = new Image();
myImage.src = document.getElementById('my-canvas-id').toDataURL();
$('body').append(myImage);
});
答案 7 :(得分:1)
我已经用这种方式改变了我的代码,它帮助了我想做的事情:
pageRendering = page.render(renderContext);
pageRendering.onData(function(){
var myImage = new Image();
myImage.src = document.getElementById('my-canvas-id').toDataURL();
$('body').append(myImage);
});
仅当特定页面已完成渲染时才有用。它没有告诉你所有页面的渲染。
答案 8 :(得分:1)
事实证明,您的第一行page.render(renderContext);
会返回一个RenderTask
对象,该对象有3个属性:
InternalRenderTask
,duh Promise
对象承诺是你想要的。为了使用它,它是这样的:
page.render(renderContext) .promise .then(function(){
//do something after the page is rendered here
});
希望有所帮助。
答案 9 :(得分:1)
根据使用的PDF.js组件(和版本),还可以使用EventBus。
如果使用的是最简单的PDF.js实现,则可能无法使用,但是如果使用的是SimpleViewer or PageViewer examples,请尝试以下操作:
eventBus.on("pagesloaded", function() {
console.log('pagesloaded');
// your code here
});
eventBus应该已经定义好了,否则,您可以使用以下命令进行设置:
var eventBus = new pdfjsViewer.EventBus();
同样,这取决于PDF Viewer的复杂程度。事实证明,PDF.js中有许多不同的层。
要监听每个页面加载,请使用eventBus事件'pagerendered
'
答案 10 :(得分:1)
如果您在查看器应用程序中使用 pdf.js,这是我发现等待它初始化的最佳方法:
// Wait for the PDFViewerApplication to initialize
PDFViewerApplication.initializedPromise.then(function() {
// Do whatever startup code you need to here, now that the EventBus
// is read. For example:
PDFViewerApplication.eventBus.on('pagerendered', function (e) {
annotationInterface.onPageRendered(e);
});
});
答案 11 :(得分:0)
如果你想在不同的画布中渲染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);
});
答案 12 :(得分:0)
page.render是一个承诺,所以你必须在你的成功中做你喜欢的事情,如下所示:
page.render({
canvasContext: context,
viewport: viewport
}).then(function() {
//do your stuff here });
答案 13 :(得分:0)
window.addEventListener('load', function () {
PDFViewerApplication.eventBus.on('textlayerrendered', function () {
console.log('textlayerrendered', arguments, PDFViewerApplication)
})
事件名称textlayerrendered
包括PDFViewerApplication.eventBus._listeners