web-dev-qa-db-fra.com

Zoom sur l'afficheur pdf.js simple

J'ai commencé à construire un lecteur de pdf avec la bibliothèque pdf.js. J'ai vraiment aimé la simplicité de certains exemples. J'ai donc utilisé l'exemple PREV/NExt pour lancer mon lecteur:

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

Je voulais ajouter un zoom avant et arrière et ai trouvé cette visionneuse simple que je voulais modéliser mon zoom et faire défiler de:

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

Voici mon code HTML pour mon 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>

et voici mon javascript pour mon 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>

J'ai tenté d'intégrer les deux et d'ajouter un zoom à mon visionneur, mais je n'ai aucun succès. Mes connaissances en javascript sont assez limitées comparées à la complexité de pdf.js, mais je me demandais si quelqu'un pourrait m'aider à résoudre mon problème. tout conseil, direction, code serait apprécié.

11
Rizzo

Désolé, je sais que c'est une vieille question et vous avez probablement déjà trouvé une solution. Cependant, vous trouverez ci-dessous le code d’une page PDF.js très simple (créée en bricolant avec le sample sur la page Web de Mozilla) avec des boutons de zoom avant et arrière qui fonctionnent.

<!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>

Désolé, je n'ai pas examiné votre code ci-dessus pour voir en quoi il diffère du mien ou déterminer ce qui ne fonctionne pas, mais peut-être que cela vous donnera ce dont vous avez besoin.

14
frabjous

Je voulais ajouter un zoom avant et arrière ...

La réponse @frabjous est bonne, elle offre exactement ce que vous avez décrit. Je bricolais aussi, démonstration en direct: http://next.plnkr.co/edit/XQBGOhdzkX3zQ86Y


Pour quelque chose de plus avancé, consultez celui-ci: mozilla pdf.js sans la vue complète

Utiliser un iframe et transmettre une URL en tant que paramètre semble facile!

1
Michal Stefanow