pdfblobpdf.jsturnjsbloburls

Turnjs display tcpdf output as flipbook using pdfjs in same file


I want to display tcpdf output as flipbook using pdfjs in same file.

Method 1: Using Turnjs only (tried as we do for blob image)-not successful

First, I get base64 from $pdf->Output('', 'E');. Then, I convert to blob and create url. The pdf file I created contain two pages. I could not preview in turnjs. After that, I passed url to div inside div with id(flipbook). But , There are no content shown in flipbook.

<?php
ob_start();
    require_once('plugin/tcpdf/tcpdf.php');
    $pdf    =new TCPDF();
    $pdf->setPrintHeader(false);
    $pdf->setPrintFooter(false);
    $pdf->AddPage();
    $html_p1='Text messaging, or texting, is the act of composing and sending electronic messages, typically consisting of alphabetic and numeric characters, between two or more users of mobile devices, desktops/laptops, or other type of compatible computer. Text messages may be sent over a cellular network, or may also be sent via an Internet connection.';
        //echo $html;
    $pdf->writeHTML($html_p1, true, 0, true, 0);
    $pdf->AddPage();
    $html_p2='A telephone call is a connection over a telephone network between the called party and the calling party.';
    $pdf->writeHTML($html_p2, true, 0, true, 0);

    $base64PdfString = $pdf->Output('', 'E');
    $base64PdfArray = explode("\r\n", $base64PdfString);
    $base64 = '';
    for($i = 5; $i < count($base64PdfArray); $i++) 
    {
      $base64 .= $base64PdfArray[$i];
    }
?>

<!doctype html>
<!--[if lt IE 7 ]> <html lang="en" class="ie6"> <![endif]-->
<!--[if IE 7 ]>    <html lang="en" class="ie7"> <![endif]-->
<!--[if IE 8 ]>    <html lang="en" class="ie8"> <![endif]-->
<!--[if IE 9 ]>    <html lang="en" class="ie9"> <![endif]-->
<!--[if !IE]><!--> <html lang="en"> <!--<![endif]-->
<head>
<meta name="viewport" content="width = 1050, user-scalable = no" />
<script type="text/javascript" src="plugin/turnjs4/extras/jquery.min.1.7.js"></script>
<script type="text/javascript" src="plugin/turnjs4/extras/modernizr.2.5.3.min.js"></script>
<script>
    const b64toBlob = (b64Data, contentType='', sliceSize=512) =>
    {
        const byteCharacters = atob(b64Data);
        const byteArrays = [];

        for (let offset = 0; offset < byteCharacters.length; offset += sliceSize)
        {
            const slice = byteCharacters.slice(offset, offset + sliceSize);
            const byteNumbers = new Array(slice.length);
            for (let i = 0; i < slice.length; i++)
            {
                byteNumbers[i] = slice.charCodeAt(i);
            }
            const byteArray = new Uint8Array(byteNumbers);
            byteArrays.push(byteArray);
        }

        const blob = new Blob(byteArrays, {type: contentType});
        return blob;
    }
    $( document ).ready(function() {


        const contentType   ='application/pdf';
        const b64Data       ='<?php echo $base64;?>';
        const blob          =b64toBlob(b64Data, contentType);           
        const blobUrl       =URL.createObjectURL(blob); 

        var div_container = document.querySelector('#flipbook');                


        var element                     = document.createElement("div");
        element.style.backgroundImage   = "url(" + blobUrl + ")";
        div_container.appendChild(element);
    })
</script>   
</head>    
<body>    
<div class="flipbook-viewport">
    <div class="container">
        <div class="flipbook" id="flipbook">

        </div>
    </div>
</div>


<script type="text/javascript">

function loadApp() {

    // Create the flipbook

    $('.flipbook').turn({
            // Width

            width:922,

            // Height

            height:600,

            // Elevation

            elevation: 50,

            // Enable gradients

            gradients: true,

            // Auto center this flipbook

            autoCenter: true

    });
}

// Load the HTML4 version if there's not CSS transform

yepnope({
    test : Modernizr.csstransforms,
    yep: ['plugin/turnjs4/lib/turn.js'],
    nope: ['plugin/turnjs4/lib/turn.html4.min.js'],
    both: ['plugin/turnjs4/samples/basic/css/basic.css'],
    complete: loadApp
});

</script>

</body>
</html>

Method 2: Using Pdf flipbook converter with turnjs and pdfjs libraries.-successful

I placed the url (php file output pdf to browser using tcpdf) as default url in viewer.js. This method could run successfully.

If possible , I want to combine turnjs with pdfjs in same file. After create tcpdf output, turnjs and pdfjs use that blob output within same file to display as flipbook.

Thank in advance.


Solution

  • Here is the solution!

    1. Save 64bit format of tcpdf output $pdf->Output('', 'E') to variable $base64PdfString.
    2. Explode $base64PdfString to array and get only base64 parts(value of index 5 onwards from the array).
    3. Convert base64 to blob in javascript by atob(b64Data),new Uint8Array(byteNumbers) and new Blob(byteArrays, {type: contentType}).
    4. Create blobUrl using URL.createObjectURL(blob).
    5. Hardcode cover div as first page.
    6. Create turnjs instance.page: 1 refer to page on load. So, could not define this before add page to turnjs.

              $("#book").turn({
                  page: 1,
                  autoCenter: true,                   
              }); 
      
    7. Create list array and add page start from 2 to last page of pdf files using pdf_doc.numPages.

    8. Add all pages to turnjs inside PDFJS.getDocument({ url: blobUrl }).then(function(pdf_doc){}).

      a) Get page from pdf blob by pdf_doc.getPage((page-1)).then(function(p){}).

      b) Create html element, canvas. Create renderContext(RenderContext encapsulates the information needed to produce a specific rendering from a RenderableImage) and add pag1.getContext('2d') of canvas to key, canvasContext of renderContext. Then, Render the pdf page on this by p.render(renderContext).then(function(){}).

      <?php
      ob_start();
      require_once('plugin/tcpdf/tcpdf.php');
      $pdf = new TCPDF();
      $pdf->setPrintHeader(false);
      $pdf->setPrintFooter(false);
      $pdf->AddPage();
      $html_p1 = 'Text messaging, or texting, is the act of composing and sending electronic messages, typically consisting of alphabetic and numeric characters, between two or more users of mobile devices, desktops/laptops, or other type of compatible computer. Text messages may be sent over a cellular network, or may also be sent via an Internet connection';
      //echo $html;
      $pdf->writeHTML($html_p1, true, 0, true, 0);
      $pdf->AddPage();
      $html_p2 = 'A telephone call is a connection over a telephone network between the called party and the calling party.';
      $pdf->writeHTML($html_p2, true, 0, true, 0);
      $base64PdfString = $pdf->Output('', 'E');
      $base64PdfArray  = explode("\r\n", $base64PdfString);
      $base64          = '';
      for($i = 5; $i < count($base64PdfArray); $i++){
          $base64 .= $base64PdfArray[$i];
      }
      ?>
      
      <!doctype html>
      <html>
          <head>
              <script type="text/javascript" src="http://code.jquery.com/jquery-1.7.1.min.js">
              </script>
              <script type="text/javascript" src="plugin/turnjs4/lib/turn.min.js">
              </script>
              <script type="text/javascript" src="plugin/pdfjs_ex/pdf.js">
              </script>
              <script>
                  const b64toBlob = (b64Data, contentType='', sliceSize=512) =>
                  {
                      const byteCharacters = atob(b64Data);
                      const byteArrays = [];
      
                      for (let offset = 0; offset < byteCharacters.length; offset += sliceSize)
                      {
                          const slice = byteCharacters.slice(offset, offset + sliceSize);
                          const byteNumbers = new Array(slice.length);
                          for (let i = 0; i < slice.length; i++)
                          {
                              byteNumbers[i] = slice.charCodeAt(i);
                          }
                          const byteArray = new Uint8Array(byteNumbers);
                          byteArrays.push(byteArray);
                      }
      
                      const blob = new Blob(byteArrays, {type: contentType});
                      return blob;
                  }
                              function addPage(page, book, pdf_doc)
                  {
                      if (!book.turn('hasPage', page))
                      {
                          var element = $('<div />', {'class': 'page '+((page%2==0) ? 'odd' : 'even'), 'id': 'page-'+page}).html('<i class="loader"></i>');
                          book.turn('addPage', element, page);                                        
                          pdf_doc.getPage((page-1)).then(function(p)
                                          {
                                              var scale = 1;
                                              var viewport = p.getViewport(scale);
      
                                              var pag1        =document.createElement('canvas');
                                              pag1.id         ='Pg_1';
                                              var context1    =pag1.getContext('2d');
                                              pag1.height     =viewport.height;
                                              pag1.width      =viewport.width;
      
                                              var renderContext =
                                              {
                                                  canvasContext: context1,
                                                  viewport: viewport
                                              };
      
                                              p.render(renderContext).then(function()
                                                  {
                                                      pag1.toBlob(function(blob)
                                                      {
                                                          var burl                        =URL.createObjectURL(blob); 
      
                                                      setTimeout(function()
                                                          {
                                                              element.html('<div style="background-image:url('+burl+'); width: 400px; height: 500px; background-size: cover;"></div><div style="top: 0px; left: 0px; overflow: hidden; z-index: 1; width: 461px; height: 600px;"></div>');
      
                                                          }, 1000);
                                                      })
                                                  })
                                          })
      
      
      
                      }
                  }
              </script>
              <style type="text/css">
                  body
                  {
                      background: #ccc;
                  }
                  #book
                  {
                      width: 800px;
                      height: 500px;
                  }
      
                  #book .turn-page
                  {
                      background-color: white;
                  }
      
                  #book .cover
                  {
                      background: #333;
                  }
      
                  #book .cover h1
                  {
                      color: white;
                      text-align: center;
                      font-size: 50px;
                      line-height: 500px;
                      margin: 0px;
                  }
      
                  #book .loader
                  {
                      background-image: url(loader.gif);
                      width: 24px;
                      height: 24px;
                      display: block;
                      position: absolute;
                      top: 238px;
                      left: 188px;
                  }
      
                  #book .data
                  {
                      text-align: center;
                      font-size: 40px;
                      color: #999;
                      line-height: 500px;
                  }
      
                  #controls
                  {
                      width: 800px;
                      text-align: center;
                      margin: 20px 0px;
                      font: 30px arial;
                  }
      
                  #controls input, #controls label
                  {
                      font: 30px arial;
                  }
      
                  #book .odd
                  {
                      background-image: -webkit-linear-gradient(left, #FFF 95%, #ddd 100%);
                      background-image: -moz-linear-gradient(left, #FFF 95%, #ddd 100%);
                      background-image: -o-linear-gradient(left, #FFF 95%, #ddd 100%);
                      background-image: -ms-linear-gradient(left, #FFF 95%, #ddd 100%);
                  }
      
                  #book .even
                  {
                      background-image: -webkit-linear-gradient(right, #FFF 95%, #ddd 100%);
                      background-image: -moz-linear-gradient(right, #FFF 95%, #ddd 100%);
                      background-image: -o-linear-gradient(right, #FFF 95%, #ddd 100%);
                      background-image: -ms-linear-gradient(right, #FFF 95%, #ddd 100%);
                  }
              </style>
          </head>
          <body>
      
              <div id="book">
                      <div class="cover">
                      <h1>
                          Cover
                      </h1>
                  </div>
              </div>
      
              <!--<div id="controls">
                  <label for="page-number">
                      Page:
                  </label> <input type="text" size="3" id="page-number"> of
                  <span id="number-pages">
                  </span>
              </div>-->
      
              <script type="text/javascript">
      
      
      
                  $(window).ready(function()
                      {
      
                          const contentType   ='application/pdf';
                          const b64Data       ='<?php echo $base64;?>';
                          const blob          =b64toBlob(b64Data, contentType);
      
                          const blobUrl       =URL.createObjectURL(blob);
      
                          PDFJS.getDocument({ url: blobUrl }).then(function(pdf_doc)
                          {
                              __PDF_DOC       = pdf_doc;
                              __TOTAL_PAGES   = __PDF_DOC.numPages;
      
                              $("#book").turn({
                                              page: 1,
                                             /* width: 400,
                                              height: 300,*/
                                              autoCenter: true,
      
                                          }); 
                                          //addPage(2, $("#book"),pdf_doc);
                              var list = [];
                              for (var i = 1; i <= __TOTAL_PAGES; i++) 
                              {
                                  list.push(i+1);
                              }
                              for (page = 0; page<list.length; page++)
                              addPage(list[page], $("#book"),pdf_doc);
                          })  
                      });
      
                  $(window).bind('keydown', function(e)
                      {
                          if (e.target && e.target.tagName.toLowerCase()!='input')
                          if (e.keyCode==37)
                          $('#book').turn('previous');
                          else if (e.keyCode==39)
                          $('#book').turn('next');
      
                      });
      
              </script>
      
      
          </body>
      </html>