javascriptpdfhtml5-canvaspdf.jsoff-screen

Using PDF.js to render to an offscreen canvas


The goal is to render pages of a pdf to an offsrceen canvas to that I can copy portions of the page to a visible canvas. As a first step, the code below is intended to render the entire first page of a pdf. It renders to an offscreen canvas, then copies from offscreen to the visible canvas. Or that was my intention. Nothing appears.

<!doctype html>

<html lang="en">
<head>
  <!--The pdf.js stuff, from Mozilla.-->
  <script src="pdf.js"></script>
  <script src="pdf.worker.min.js"></script>
  <style>
    canvas { border: 1px solid black; }
  </style>
</head>

<body onload="main()">

<canvas id="pdf_renderer"></canvas>

<script>

var myState = {
  pdf: null,
  zoom: 1,
  testcvs: null
}

async function main() {

  await openDocument();
  await getpage(1);
  
  var canvas = document.getElementById("pdf_renderer");
  var ctx = canvas.getContext('2d');
  
  canvas.width = myState.testcvs.width;
  canvas.height = myState.testcvs.height;
  
  ctx.drawImage(myState.testcvs,0,0);
}

async function openDocument() {
  await pdfjsLib.getDocument('ex01gear.pdf').then((pdf) => {
    myState.pdf = pdf;
  });
}

async function getpage(pagenum) {

  await myState.pdf.getPage(pagenum).then((page) => {
    
    var offcanvas = document.createElement('canvas');
    var offctx = offcanvas.getContext('2d');
    var viewport = page.getViewport(myState.zoom);
    
    offcanvas.width = viewport.width;
    offcanvas.height = viewport.height;

    page.render({
      canvasContext: offctx,
      viewport: viewport
    });

    myState.testcvs = offcanvas;
  }); 
}

</script>

</body>
</html>

Solution

  • The code below does what was intended. I am still uncertain why the original code fails to work. My best guess is that it's due to something being done asynchronously.There's very little that's different about the two implemenations aside from that.

    <!doctype html>
    
    <html lang="en">
    <head>
      <!--The pdf.js stuff, from Mozilla.-->
      <script src="pdf.js"></script>
      <script src="pdf.worker.min.js"></script>
      <style>
        canvas { border: 1px solid black; }
      </style>
    </head>
    
    
    <body onload="main()">
    
    <canvas id="pdf_renderer"></canvas>
    
    <script>
    
    var myState = {
      pdf: null,
      zoom: 1,
      testcvs: null,
      curpage: null
    }
    
    async function main() {
    
      await openDocument();
      await getpage(1);
      await renderOff();
    
      var canvas = document.getElementById("pdf_renderer");
      var ctx = canvas.getContext('2d');
      
      var viewport = myState.curpage.getViewport(myState.zoom);
    
      canvas.width = viewport.width;
      canvas.height = viewport.height;
    
      ctx.drawImage(myState.testcvs, 0, 0);
    }
    
    async function openDocument() {
      await pdfjsLib.getDocument('ex01gear.pdf').then((pdf) => {
        myState.pdf = pdf;
      });
    }
    
    async function getpage(pagenum) {
      await myState.pdf.getPage(pagenum).then((page) => {
        myState.curpage = page;
      }); 
    }
    
    async function renderOff() {
    
      myState.testcvs = document.createElement('canvas');
      var offctx = myState.testcvs.getContext('2d');
      var viewport = myState.curpage.getViewport(myState.zoom);
    
      myState.testcvs.width = viewport.width;
      myState.testcvs.height = viewport.height;
      
      await myState.curpage.render({
        canvasContext: offctx,
        viewport: viewport
      });
    }
    
    </script>
    
    </body>
    </html>