Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Zoom on simple pdf.js viewer

I started to build a pdf viewer with the pdf.js library. I really liked how simple some of the examples were so I used the PREV/NExt example to start off my viewer:

https://github.com/mozilla/pdf.js/blob/master/examples/learning/prevnext.html

I wanted to add zoom in and out and found this simple viewer which I wanted to model my zoom and scroll off of:

https://github.com/zedr/simple-pdf-reader.js/blob/master/viewer.js

Here is my html for my index.html:

         <div class="row">
              <div class="col-md-4">
              <button class="btn btn-primary" id="prev"><i class="fa fa-level-up fa-lg"></i></button>
                <button class="btn btn-primary" id="next"><i class="fa fa-level-down fa-lg"></i></button>
              </div><div class="col-md-4">
                <span>Page: <span id="page_num"></span> / <span id="page_count"></span></span>
                <div id="pdf-controls">
                    <button id="zoom_minus" onclick="url.zoomMinus()"
                      oncontextmenu="return false;" class="btn btn-primary">-</button>
                    <button id="zoom_plus" onclick="url.zoomPlus()"
                      oncontextmenu="return false;" class="btn btn-primary">+</button>
                    <div id="pdf-stats">
                      <p>
                        <span id="pdf-page-zoom">n/a</span> <span>%</span>
                      </p>
                    </div>
                  </div>
              </div><div class="col-md-4 pull-right">
                <a href="sample.pdf" class="btn btn-primary"><i class="fa fa-arrows-alt fa-lg"></i></a>
                <a href="sample.pdf" class="btn btn-primary" download><i class="fa fa-cloud-download fa-lg"></i></a>
              </div>
            </div>
            <br><br>
            <center>
            <div style="overflow: scroll" id="pdfviewer">
              <canvas id="pdfcanvas" style="border:1px solid black; width: 100%"></canvas>
            </div>
            </center>

and this is my javascript for my viewer.js:

            <script id="pdfviewer">
            //
            // If absolute URL from the remote server is provided, configure the CORS
            // header on that server.
            //
            var url = 'sample.pdf';

            //
            // Disable workers to avoid yet another cross-origin issue (workers need
            // the URL of the script to be loaded, and dynamically loading a cross-origin
            // script does not work).
            //
            // PDFJS.disableWorker = true;

            //
            // In cases when the pdf.worker.js is located at the different folder than the
            // pdf.js's one, or the pdf.js is executed via eval(), the workerSrc property
            // shall be specified.
            //

            PDFJS.workerSrc = 'pdf.worker.js';

            var pdfDoc = null,
                pageNum = 1,
                pageRendering = false,
                pageNumPending = null,
                scale = 1.5,
                canvas = document.getElementById('pdfcanvas'),
                ctx = canvas.getContext('2d');
            var camera = {
              x: 0,
              y: 0,
              scale: 1,
            };

            /**
             * Get page info from document, resize canvas accordingly, and render page.
             * @param num Page number.
             */
            function renderPage(num) {
              pageRendering = true;
              // Using promise to fetch the page
              pdfDoc.getPage(num).then(function(page) {
                var viewport = page.getViewport(scale);
                canvas.height = viewport.height;
                canvas.width = viewport.width;
                // Render PDF page into canvas context
                var renderContext = {
                  canvasContext: ctx,
                  viewport: viewport
                };
                var renderTask = page.render(renderContext);
                // Wait for rendering to finish
                renderTask.promise.then(function () {
                  pageRendering = false;
                  if (pageNumPending !== null) {
                    // New page rendering is pending
                    renderPage(pageNumPending);
                    pageNumPending = null;
                  }
                });
              });
              // Update page counters
              document.getElementById('page_num').textContent = pageNum;
            }
            /**
             * If another page rendering in progress, waits until the rendering is
             * finised. Otherwise, executes rendering immediately.
             */
            function queueRenderPage(num) {
              if (pageRendering) {
                pageNumPending = num;
              } else {
                renderPage(num);
              }
            }
            /**
             * Displays previous page.
             */
            function onPrevPage() {
              if (pageNum <= 1) {
                return;
              }
              pageNum--;
              queueRenderPage(pageNum);
            }
            document.getElementById('prev').addEventListener('click', onPrevPage);
            /**
             * Displays next page.
             */
            function onNextPage() {
              if (pageNum >= pdfDoc.numPages) {
                return;
              }
              pageNum++;
              queueRenderPage(pageNum);
            }
            document.getElementById('next').addEventListener('click', onNextPage);
            /**
             * Asynchronously downloads PDF.
             */
            PDFJS.getDocument(url).then(function (pdfDoc_) {
              pdfDoc = pdfDoc_;
              document.getElementById('page_count').textContent = pdfDoc.numPages;
              // Initial/first page rendering
              renderPage(pageNum);
            });

            //The PdfRead object is a browser-aware reading device that the User will
            //manipulate to read the page. Basically, a wrapper around the PdfView object.


            var frame = document.getElementById('pdfcanvas');

            var zoom_widget = document.getElementById('pdf-page-zoom');

            // Keep track of certain values inside the most interesting nodes of the DOM
            var state = {

                    get ctop () { return frame.lastChild.offsetTop },

                    get ftop () { return frame.scrollTop },

                    get fsh () { return frame.scrollHeight },

                    get fh () { return frame.offsetHeight },
            };

            // Decrease the Zoom, acting on the scale
            this.zoomMinus = function (val) {
                doc.page.scale -= (val) ? val : 0.25;
                zoom_widget.innerText = doc.page.scale * 100;
            };

            // Increase the Zoom, acting on the scale
            this.zoomPlus = function (val) {
                doc.page.scale += (val) ? val : 0.25;
                zoom_widget.innerText = doc.page.scale * 100;
            };

            // Controller: monitor for frame scroll events and advance page rendering
            frame.onscroll = function () {
                var test = (state.fsh - (state.fh + state.ftop));
                if (test < 0 && doc.page.head < doc.page.last) {
                    doc.page.number++; 
                }
            };

            // Init the widgets
            zoom_widget.innerText = doc.page.scale * 100;

          </script>

I attempted to integrate the two and add zoom to my viewer, but am not having any success. My javascript knowledge is pretty limited compared to the complexity of pdf.js, but I was wondering if someone could help me with my problem. any advice, direction, code would be appreciated.

like image 912
Rizzo Avatar asked Dec 22 '14 17:12

Rizzo


People also ask

How do I preview a PDF in JavaScript?

JS library is initialized taking the object url as the source url of the PDF. PDF. JS' APIs getDocument and getPage are used to render the PDF. The first page of the PDF is rendered as an image, and that is shown as the preview of the PDF.

Does PDF JS work in Chrome?

What Browsers does PDF. js Support. PDF. js is used within Mozilla Firefox today as the built-in PDF viewer, and it works well within a website when viewed using the latest versions of Chrome and Firefox, whether through the pre-built PDF.

Is PDF JS free to use?

PDF. js is a good free option if you're willing to invest time into implementing a UI for it. The project comes with some examples and API docs.


1 Answers

Sorry I know this is an old question, and you've probably come up with a solution by now. Below, however, you'll code for a very simple PDF.js page (which I made by tinkering with the sample on Mozilla's webpage) with zoom in and zoom out buttons that work.

<!DOCTYPE html>
<html>
   <head>
      <meta charset="UTF-8">
      <title>Simple PDF.js with zoom</title>
      <script src="pdfjs/build/pdf.js"></script>
   </head>
   <body>

      <h1>Simple PDF.js with zoom</h1>

      <button id="nextbutton" type="button">next page</button>
      <button id="prevbutton" type="button">prev page</button>
      <button id="zoominbutton" type="button">zoom in</button>
      <button id="zoomoutbutton" type="button">zoom out</button>
      <br>


      <canvas id="the-canvas" style="border:1px  solid black"></canvas>

      <script id="script">
         var pageNum = 1;
         var pdfScale = 1; // make pdfScale a global variable
         var shownPdf; // another global we'll use for the buttons
         var url = './helloworld.pdf' // PDF to load: change this to a file that exists;

         function renderPage(page) {
            var scale = pdfScale; // render with global pdfScale variable
            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);
         }

         function displayPage(pdf, num) {
            pdf.getPage(num).then(function getPage(page) { renderPage(page); });
         }

         var pdfDoc = PDFJS.getDocument(url).then(function getPdfHelloWorld(pdf) {
            displayPage(pdf, 1);
            shownPdf = pdf;
         });

         var nextbutton = document.getElementById("nextbutton");
         nextbutton.onclick = function() {
            if (pageNum >= shownPdf.numPages) {
               return;
            }
            pageNum++;
            displayPage(shownPdf, pageNum);
         }

         var prevbutton = document.getElementById("prevbutton");
         prevbutton.onclick = function() {
            if (pageNum <= 1) {
               return;
            }
            pageNum--;
            displayPage(shownPdf, pageNum);
         }

         var zoominbutton = document.getElementById("zoominbutton");
         zoominbutton.onclick = function() {
            pdfScale = pdfScale + 0.25;
            displayPage(shownPdf, pageNum);
         }

         var zoomoutbutton = document.getElementById("zoomoutbutton");
         zoomoutbutton.onclick = function() {
            if (pdfScale <= 0.25) {
               return;
            }
            pdfScale = pdfScale - 0.25;
            displayPage(shownPdf, pageNum);
         }


      </script>


   </body>
</html>

Sorry I haven't examined your code above to see how it differs from mine, or determine what about it doesn't work, but perhaps this will give you what you need.

like image 168
frabjous Avatar answered Sep 18 '22 15:09

frabjous