Eu preciso renderizar um gradiente para cobrir a metade inferior do PDF renderizado. Estou trabalhando para um jornal e estamos fazendo um aplicativo que mostra o jornal com um teaser antes de assinar.
O problema é que o gradiente precisa ser pintado em cima do PDF, então ele precisa esperar até que o PDF termine de renderizar. Na verdade, em navegadores móveis, tentar a renderização de gradiente antes que o PDF seja concluído resulta em um comportamento extremamente selvagem (a tela é renderizada novamente e pisca toda vez que a página rola um pouco), resultando em constantes repinturas e o conteúdo será renderizado de cabeça para baixo às vezes.
Então, simplesmente, preciso executar um retorno de chamada quando o PDF terminar de renderizar.
Vocês podem suportar retornos de chamada? Ou enviar um evento quando a renderização estiver concluída?
Nós temos o evento 'pagerendered' ou render() retorna a promessa. O visualizador genérico nunca renderiza todas as páginas, portanto, isso não será corrigível para o visualizador, a menos que introduzamos um modo para o objeto PDFViewer quando ele renderiza todas as páginas.
Ok, então um evento 'pagerendered' é disparado de qual objeto? @yurydelendik
Veja https://github.com/mozilla/pdf.js/blob/master/web/pdf_viewer.js#L225 e exemplo de uso em https://github.com/mozilla/pdf.js/blob/master/web /viewer.js#L1733
Observe que não temos API para visualizador. A única API que lançamos é para renderização de núcleo e tela (consulte src/display/api.js).
@yurydelendik Estou usando isso com canvas, no navegador. Estou meio confuso sobre onde mais o PDF JS é relevante. Isso me confundiu imediatamente, mas de qualquer forma, parece que você tem o que estou procurando. Muito obrigado!
Fechando conforme resolvido.
Estou tendo problemas para capturar este evento.
Eu escuto (Jquery) para o evento pagerendered
conforme mostrado nos documentos acima:
$(document).bind('pagerendered', function (e) {
console.log('Page rendering complete.');
//do stuff
});
e renderize o PDF na tela:
PDFJS.getDocument('my_file.pdf').then(function(pdf) {
pdf.getPage(1).then(function(page) {
/* .. snip .. */
var scaledViewport = page.getViewport(scale);
var canvas = document.getElementById('the-canvas');
var context = canvas.getContext('2d');
canvas.height = scaledViewport.height;
canvas.width = scaledViewport.width;
var renderContext = {
canvasContext : context,
viewport : scaledViewport
};
page.render(renderContext);
});
Acionar o evento sozinho funciona com sucesso, então meu ouvinte está configurado corretamente e é anexado muito antes page.render(renderContext)
ser chamado.
Talvez eu tenha entendido mal o gatilho do evento. Quando exatamente o evento pagerendered
deve ser disparado do documento?
@yurydelendik
Se você não estiver usando o visualizador genérico, o evento não será acionado. Desculpe, não entendi o que você está perguntando.
Consulte https://github.com/mozilla/pdf.js/blob/master/examples/learning/prevnext.html#L76 para ver como aguardar a conclusão da renderização. jQuery será menos útil aqui, tente aprender a usar Promises.
@yurydelendik eu entendo agora, muito obrigado pelo seu tempo!
Usar o evento textlayerrendered
funciona para mim:
document.addEventListener('textlayerrendered', function (e) {
if (e.detail.pageNumber === PDFViewerApplication.page) {
// finished rendering
}
}, true);
Usando seu snippet acima, você simplesmente faria:
page.render(renderContext).then(function() {
console.log("FINISHED RENDERING!");
}, function() {
console.log("ERROR");
});
@brendadahl obrigado)
Obrigado @lucdetellis ! Eu tenho tentado fazer com que um botão externo ao visualizador acione a funcionalidade de impressão, mas nunca funcionaria devido ao erro dado. Usar sua solução dentro de uma função me permitiu acionar essa função a partir do quadro pai e, em seguida, window.focus() e window.print() quando terminar de renderizar, e BAM, problema resolvido. :)
document.addEventListener('textlayerrendered', function (e) {
if (e.detail.pageNumber === PDFViewerApplication.page) {
// finished rendering
}
}, true);
Nunca é chamado por mim...
Estou chamando assim (no final viewer.js
):
document.addEventListener('textlayerrendered', function (e) {
console.log("textlayerrendered event called!");
if (e.detail.pageNumber === PDFViewerApplication.page) {
// finished rendering
console.log("FINISHED RENDERING!");
Android.makeWebViewVisible();
} else {
console.log("NOT DONE RENDERING!");
}
}, true);
document.addEventListener('DOMContentLoaded', webViewerLoad, true);
Por favor, perdoe minha ignorância de javascript, sou um desenvolvedor Android tentando obter retornos de chamada js para quando o PDF terminar de renderizar porque estou enfrentando alguns problemas específicos do Android... Qualquer ajuda seria muito apreciada.
Atualizada:
O problema era que a visibilidade do meu Android WebView
não estava definida como VISIBLE
, então nenhum dos eventos JS estava sendo acionado.
Usando o visualizador fornecido com o pdf.js, o evento pagesloaded
funcionou para mim (eu abro a caixa de diálogo de impressão assim que terminar de carregar):
document.addEventListener('pagesloaded', function (e) {
window.print();
}, true);
@turquoise-turtle você anexou o evento Listener ao documento principal ou ao iframe onde você tem o visualizador?
var iframe = document.getElementById('iframe').contentDocument;
iframe.addEventListener('pagesloaded', function (e) {
alert("loaded");
}, true);
eu estou fazendo isso e não parece funcionar
set "eventBusDispatchToDOM": true em viewer.js por que ninguém está dizendo isso!
Parece que o padrão foi alterado para não enviar eventos para DOM por volta de agosto a setembro, olhando para #10019
Comentários muito úteis
Usar o evento
textlayerrendered
funciona para mim: