Pdf.js: Retorno de chamada para quando o PDF terminar de renderizar?

Criado em 30 dez. 2014  ·  17Comentários  ·  Fonte: mozilla/pdf.js

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?

Comentários muito úteis

Usar o evento textlayerrendered funciona para mim:

document.addEventListener('textlayerrendered', function (e) {
  if (e.detail.pageNumber === PDFViewerApplication.page) {
    // finished rendering
  }
}, true);

Todos 17 comentários

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

Esta página foi útil?
0 / 5 - 0 avaliações

Questões relacionadas

hp011235 picture hp011235  ·  4Comentários

smit-modi picture smit-modi  ·  3Comentários

SehyunPark picture SehyunPark  ·  3Comentários

azetutu picture azetutu  ·  4Comentários

anggikolo11 picture anggikolo11  ·  3Comentários