Darragh McCarthy
Darragh McCarthy

Reputation: 270

for embedded PDFs, can PDFJS support both scrolling and jump to a page number at the same time?

This seems like it should be very standard behavior.

I can display a scrollable PDF with:

var container = document.getElementById('viewerContainer');
var pdfViewer = new PDFJS.PDFViewer({
    container: container,
});
PDFJS.getDocument(DEFAULT_URL).then(function (pdfDocument) {
    pdfViewer.setDocument(pdfDocument);
});

and I can display the PDF page by page with something like:

PDFJS.getDocument(URL_ANNOTATED_PDF_EXAMPLE).then(function getPdfHelloWorld(pdf) {
    pdf.getPage(pageNumber).then(function getPageHelloWorld(page) {
        var scale = 1.5;
        var viewport = page.getViewport(scale);

        var canvas = document.getElementById('the-canvas');
        var context = canvas.getContext('2d');
        canvas.height = viewport.height;
        canvas.width = viewport.width;
        var renderContext = {
            canvasContext: context,
            viewport: viewport
        };
        page.render(renderContext);
    });

But can't seem to find any reference in the API to both allow scrolling and jumping to a particular page, besides:

pdfViewer.currentPageNumber = 3;

which doesn't work...

Upvotes: 3

Views: 1995

Answers (1)

Darragh McCarthy
Darragh McCarthy

Reputation: 270

So I found a way to make this work (mixed with a little Angular code, "$scope.$watch...") I now have other problems with font decoding. But here is a solution that might help someone else.

var me = this;
PDFJS.externalLinkTarget = PDFJS.LinkTarget.BLANK;
var container = document.getElementById('capso-court-document__container');


function renderPDF(url, container) {

    function renderPage(page) {
        var SCALE = 1;
        var pdfPageView = new PDFJS.PDFPageView({
            container: container,
            id: page.pageIndex + 1,
            scale: SCALE,
            defaultViewport: page.getViewport(SCALE),
            textLayerFactory: new PDFJS.DefaultTextLayerFactory(),
            annotationLayerFactory: new PDFJS.DefaultAnnotationLayerFactory()
        });
        pdfPageView.setPdfPage(page);
        return pdfPageView.draw();
    }
    function renderPages(pdfDoc) {
        var pageLoadPromises = [];
        for (var num = 1; num <= pdfDoc.numPages; num++) {
            pageLoadPromises.push(pdfDoc.getPage(num).then(renderPage));
        }
        return $q.all(pageLoadPromises);
    }

    PDFJS.disableWorker = true;

    return PDFJS.getDocument(url)
        .then(renderPages);
}

$scope.$watch(function() {
    return {
        filingUrl: me.filingUrl,
        whenPageSelected: me.whenPageSelected,
    };
}, function(newVal, oldVal) {
    if (newVal.filingUrl) {
        //newVal.filingUrl = URL_EXAMPLE_PDF_ANNOTATED;
        //newVal.filingUrl = URL_EXAMPLE_PDF_ANNOTATED_2;
        //newVal.filingUrl = URL_EXAMPLE_PDF_MULTI_PAGE;

        if (newVal.filingUrl !== oldVal.filingUrl &&
            newVal.whenPageSelected &&
            newVal.whenPageSelected.page) {
            scrollToPage(newVal.whenPageSelected.page);
        }
        //HACK - create new container for each newly displayed PDF
        container.innerHTML = '';
        var newContainerForNewPdfSelection = document.createElement('div');
        container.appendChild(newContainerForNewPdfSelection);
        renderPDF(newVal.filingUrl, newContainerForNewPdfSelection).then(function() {
            if (newVal.whenPageSelected && 
                newVal.whenPageSelected.page) {
                scrollToPage(newVal.whenPageSelected.page);
            }
        });
    }
}, true);

function scrollToPage(pageNumber) {
    var pageContainer = document.getElementById('pageContainer' + pageNumber);
    if (pageContainer) {
        container.scrollTop = pageContainer.offsetTop;
    } else {
        console.warn('pdf pageContainer doesn\'t exist for index', pageNumber);
    }
}

Upvotes: 1

Related Questions