user25090379
user25090379

Reputation: 23

Download p5.js sketch canvas as PDF using jsPDF addImage JPEG

Trying to get a minimal script running to download a p5.js sketch canvas element as a PDF using jsPDF -- specifically the jsPDF addImage method, after converting the canvas to a JPEG using the JS toDataURL method.

I can get p5.js to draw on the canvas and jsPDF to download a PDF after launching the page, but the PDF is blank (black with JPEG, white with PNG, presumably b/c alpha channel). I'm guessing this is because of where I have the jsPDF code in the script, but anywhere else I put it, the download doesn't work.

Any advice?

(FWIW, I tried the solution to this: JsPDF addImage jpeg background is black, but I just end up with an all-white PDF, like when I go with PNG instead of JPEG)

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <title>Page 0</title>

    <link rel="stylesheet" type="text/css" href="style.css">

    <script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.5.3/jspdf.debug.js" integrity="sha384-NaWTHo/8YCBYJ59830LTz/P4aQZK1sS0SneOgAvhsIl3zBu8r9RevNg5lHCHAuQ/" crossorigin="anonymous"></script>
    <script src="libraries/p5.min.js"></script>
    <script src="libraries/p5.sound.min.js"></script>
  </head>

  <body>
    <script src="page0.js"></script>
  </body>
</html>
function  setup() {

  let     the_canvas  =     createCanvas(792, 612, P2D);

                            noLoop();

  let     doc         = new jsPDF("l", "pt", [792, 612]);

  let     the_img     =     the_canvas.elt.toDataURL("image/JPEG", 1.0);
                            doc.addImage(the_img, "JPEG", 0, 0, 792, 612);

                            doc.save("page0.pdf");
                          
}

function  draw() {

                            background(43);

                            stroke(200);
                            fill(200);
                            textSize(100);
                            text("Test", 500, 500);

}
html, body {
  margin: 0;
  padding: 0;
}

canvas {
  display: block;
}

Upvotes: 2

Views: 146

Answers (1)

ggorlen
ggorlen

Reputation: 57195

Since setup runs first, then draw, you save the PDF before writing text to it.

Try drawing and writing, then saving the PDF as the final step:

<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Page 0</title>
<style>
html,
body {
  margin: 0;
  padding: 0;
}

canvas {
  display: block;
}
</style>
<script
  src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.5.3/jspdf.debug.js"
  integrity="sha384-NaWTHo/8YCBYJ59830LTz/P4aQZK1sS0SneOgAvhsIl3zBu8r9RevNg5lHCHAuQ/"
  crossorigin="anonymous"
></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.9.0/p5.js"></script>
</head>
<body>
<script>
let canvas;

function setup() {
  canvas = createCanvas(792, 612, P2D);
  noLoop();
}

function draw() {
  background(43);
  stroke(200);
  fill(200);
  textSize(100);
  text("Test", 500, 500);
  const doc = new jsPDF("l", "pt", [792, 612]);
  const img = canvas.elt.toDataURL("image/JPEG", 1.0);
  doc.addImage(img, "JPEG", 0, 0, 792, 612);
  doc.save("page0.pdf");
}
</script>
</body>
</html>

Note that separating setup and draw functions as shown above isn't strictly necessary since you're doing a one-shot operation. You could put all of the code in setup, or all of the code in draw (with noLoop() so it only runs once).

Upvotes: 2

Related Questions