switchon@lavalamp.biz
+27(0) 83 419 4851 / +27(0) 21 036 1165
Application & software development
Get A Quote

    • Home
    • Services
      • Application & software development
      • Outsourced software development
      • Project based resourcing
      • Digital marketing & consulting
      • Graphic design & consulting
      • UI / UX design & consulting
      • Recruitment services
      • Lease an expert
    • About
      • How we work
      • NBConsult Group
      • Partners
      • Lightbox Digital
    • Blog
    • Join us
    • Contact

    • Home
    • Services
      • Application & software development
      • Outsourced software development
      • Project based resourcing
      • Digital marketing & consulting
      • Graphic design & consulting
      • UI / UX design & consulting
      • Recruitment services
      • Lease an expert
    • About
      • How we work
      • NBConsult Group
      • Partners
      • Lightbox Digital
    • Blog
    • Join us
    • Contact

    • Home
    • Services
      • Application & software development
      • Outsourced software development
      • Project based resourcing
      • Digital marketing & consulting
      • Graphic design & consulting
      • UI / UX design & consulting
      • Recruitment services
      • Lease an expert
    • About
      • How we work
      • NBConsult Group
      • Partners
      • Lightbox Digital
    • Blog
    • Join us
    • Contact

    • Home
    • Services
      • Application & software development
      • Outsourced software development
      • Project based resourcing
      • Digital marketing & consulting
      • Graphic design & consulting
      • UI / UX design & consulting
      • Recruitment services
      • Lease an expert
    • About
      • How we work
      • NBConsult Group
      • Partners
      • Lightbox Digital
    • Blog
    • Join us
    • Contact
    angular array
    How To Create An Angular Form Array
    Dec 5, 2022
    design patterns in software development
    Design Patterns In Software Development
    Jan 9, 2023

    Creating A Basic Customisable PDF Viewer Using PDF.js

    Categories
    • Languages / Tech areas
    • Software Development
    • Web Design
    • Web Development
    Tags
    • framework
    • html
    • javascript
    • pdf
    • PDF.js
    customisable pdf viewer using
    customisable pdf viewer using

     

    In this blog, I’ll be going over creating a basic custom PDF viewer by using PDF.js. I came across this package while working on a project that required learning material to be displayed but also to prevent the user from downloading the document itself. Please note that this is not a 100% guaranteed way of protecting your PDF content, however it does make it slightly harder for your users to download the document itself.

    Now lets get setup:

    Step 1)

    If you are wanting more information on the PDF.js library you can checkout their documentation.

    You can set this up by using your node package manager, however for my example for this blog I’m going to make use of one of the CDN(s) that are being hosted currently which can be found in the documentation of the PDF.js package.

    Here is the CDN I used within my head tag.

    <script src="//mozilla.github.io/pdf.js/build/pdf.js"></script>

    Step 2)

    Then in your body we will need a canvas tag to view our PDF file from. This is the canvas tag I created along with some buttons to help us control which page we will be looking at.

    <body>
      <div>
        <button id="prev">Previous</button>
        <button id="next">Next</button>
        &nbsp; &nbsp;
        <span>Page: <span id="page_num"></span> / <span id="page_count"></span></span>
      </div>
      
      <canvas id="the-canvas"></canvas>
    </body>

    Step 3)

    Now that we have the HTML part down we can start adding the scripts to initialize the content to be shown inside the canvas tag.

    <script id="script">
        // Here you can define what PDF you will be using to be displayed in the canvas
        var url = 'https://raw.githubusercontent.com/mozilla/pdf.js/ba2edeae/web/compressed.tracemonkey-pldi-09.pdf';
        
        // Loaded via <script> tag, create shortcut to access PDF.js exports.
        var pdfjsLib = window['pdfjs-dist/build/pdf'];
        
        // The workerSrc property shall be specified.
        pdfjsLib.GlobalWorkerOptions.workerSrc = '//mozilla.github.io/pdf.js/build/pdf.worker.js';
        
        var pdfDoc = null,
            pageNum = 1,
            pageRendering = false,
            pageNumPending = null,
            scale = 1.2,
            canvas = document.getElementById('the-canvas'),
            ctx = canvas.getContext('2d');
        
        /**
         * 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: 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 = num;
        }
        
        /**
         * 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.
         */
        pdfjsLib.getDocument(url).promise.then(function(pdfDoc_) {
          pdfDoc = pdfDoc_;
          document.getElementById('page_count').textContent = pdfDoc.numPages;
        
          // Initial/first page rendering
          renderPage(pageNum);
        });
    </script>
    

    Output

    In the above code snippets I used exactly the same setup as what was provided on the documentation. Its that easy to get yourself all setup.
    Now you should have a page that looks like this.

    Example of what the PDF viewer should look like

     

    Lets prevent the user from downloading your content

    You might have already noticed the issue here… If you right click you can still save as image. Do not worry my paranoid friend, there is a very simple one liner that we can use to prevent this from happening.  If you add the following to your script you will no longer have this issue.

     

    document.getElementById('the-canvas').addEventListener('contextmenu', event => event.preventDefault());

    The rest is up to you on how you want it all to look.

     

    Upcoming blog information

    In my next upcoming blog I’ll cover the default PDF viewer that PDF.js provides.
    In case you want an idea of what I’m talking about go here.

     

    Conclusion

    I am by no means good at PDF.js, I have only started looking into this recently for one of my current projects and I thought it would make a great blog post. I hope this helped you understand things a bit better on how you can make use of the PDF.js.

    Contact us


      Related posts:

      how to create and digitally sign a pdf using laravel and tcpdfHow To Create And Digitally Sign A PDF Using Laravel And TCPDF dynamic doughnut graph using laravel vue componentDynamic Doughnut Graph Using Laravel Vue Component sending files with auxiliary dataSimple Way To Send A File With Auxiliary Data Via Axios In VueJS laravel livewireLaravel Livewire
      Share
      0
      Collin Yarrington
      Collin Yarrington
      Collin is a software developer for Lava Lamp Lab. For him there is no obstacle too big. Learning to improve and overcome those obstacles is what drives him forward.

      Leave a Reply Cancel reply

      Your email address will not be published. Required fields are marked *

      Lava Lamp Lab


      Like technology, a lava lamp constantly changes form, producing new conditions with every passing moment



      lava lamp lab facebook   lava lamp lab twitter   lava lamp lab linkedin   lava lamp lab instgram

      Services


      Application & software development

      Outsourced software development

      Project based resourcing

      Digital marketing & consulting

      Graphic design & consulting

      UI / UX design & consulting

      Contact Us


      +27(0) 83 419 4851

      +27(0) 21 036 1165


      switchon@lavalamp.biz


      Unit 4 Monaco Square,
      14 Church Street,
      Durbanville,
      Cape Town, 7550

      NBConsult Group


      nbconsult
      nbconnect msp
      nbclearning
      river broadband
      designer needed
      © 2023 Lava Lamp Lab (Pty) Ltd | All Rights Reserved | Privacy Policy
      Contact us now

        Application & software development

          Outsourced software development

            Project based resourcing

              Digital marketing & consulting

                Graphic design & consulting

                  UI/UX design & consulting

                    Lease an expert

                      Recruitment services

                        We are using cookies to give you the best experience on our website.

                        You can find out more about which cookies we are using or switch them off in settings.

                        Lava Lamp Lab
                        Powered by  GDPR Cookie Compliance
                        Privacy Overview

                        This website uses cookies so that we can provide you with the best user experience possible. Cookie information is stored in your browser and performs functions such as recognising you when you return to our website and helping our team to understand which sections of the website you find most interesting and useful.

                        Strictly Necessary Cookies

                        Strictly Necessary Cookie should be enabled at all times so that we can save your preferences for cookie settings.

                        If you disable this cookie, we will not be able to save your preferences. This means that every time you visit this website you will need to enable or disable cookies again.

                        3rd Party Cookies

                        This website uses Google Analytics to collect anonymous information such as the number of visitors to the site, and the most popular pages.

                        Keeping this cookie enabled helps us to improve our website.

                        Please enable Strictly Necessary Cookies first so that we can save your preferences!

                        Cookie Policy

                        More information about our Cookie Policy