Как узнать, закончил ли PDF.JS рендеринг?
Я использую 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.
Ответы
Ответ 1
Я также боролся с этой проблемой.. решение, которое я использовал:
//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
};
Ответ 2
<script type="text/javascript">
document.addEventListener("pagesloaded", function(e) {
//do sth..
});
</script>
Ответ 3
На момент написания, это действительно сработало. Я не уверен, что он все еще делает.
PDFJS использует Promises
. Проще всего сделать следующее:
page.render(renderContext).promise.then(function(){
document.body.appendChild(canvas);
});
Ответ 4
Лионное решение более надежное. Но это самое простое решение, которое я мог найти.
var renderTask = pdfPage.render(renderContext);
renderTask.promise.then(
function pdfPageRenderCallback() {
pageViewDrawCallback(null);
},
function pdfPageRenderError(error) {
pageViewDrawCallback(error);
}
);
Ответ 5
Использование события textlayerrendered
работало для меня:
document.addEventListener('textlayerrendered', function (event) {
// was this the last page?
if (event.detail.pageNumber === PDFViewerApplication.page) {
console.log('Finished rendering!');
}
}, true);
Ответ 6
При изучении этих решений у меня возникли проблемы с получением renderContext
, поэтому я в итоге использовал этот подход, слушая pagerendered
:
document.addEventListener("pagerendered", function(e){
});
В моем случае я просто хотел вызвать некоторую внешнюю функцию после рендеринга страницы с минимальными усилиями.
Надеюсь это поможет. Ура!
Ответ 7
Я изменил свой код таким образом, и это помогло мне, что я хотел сделать:
pageRendering = page.render(renderContext);
pageRendering.onData(function(){
var myImage = new Image();
myImage.src = document.getElementById('my-canvas-id').toDataURL();
$('body').append(myImage);
});
Это помогает, только если конкретная страница закончила рендеринг. он не сообщает вам об рендеринге всех страниц.
Ответ 8
Как оказалось, ваша первая строка page.render(renderContext);
возвращает объект RenderTask
, который имеет 3 свойства:
- internalRenderTask - a
InternalRenderTask
, duh
- cancel - функция, по-видимому, позволяющая отменить рендеринг.
- обещание - объект jQuery
Promise
Обещание - это тот, который вы хотите. Чтобы использовать его, он выглядит следующим образом:
page.render(renderContext) .promise.then(function() {
//do something after the page is rendered here
});
Надеюсь, что это поможет.
Ответ 9
Если вы хотите отображать все страницы 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);
});
Ответ 10
page.render - это обещание, поэтому вам нужно сделать свой материал в своем успехе, как показано ниже:
page.render({
canvasContext: context,
viewport: viewport
}).then(function() {
//do your stuff here });