javascripthtmlnode.jscanvasnode-canvas

Node-Canvas Library: Text not visible and coming below Image


I'm trying to use node-canvas npm package to generate an image from canvas. But the texts(TITLE 1 and TITLE 2) are appearing below the image. I want the image to be a background spanning across the canvas size and then put the texts over the image.

Here is my code:

const { createCanvas, loadImage } = require("canvas");
const fs = require("fs");

// Dimensions for the image/canvas
const width = 848;
const height = 600;

// Instantiate the canvas object
const canvas = createCanvas(width, height);
const context = canvas.getContext("2d");

context.font = "bold 70pt 'PT Sans'";
context.textAlign = "center";
context.fillStyle = "#764abc";

context.fillText("TITLE 1", 600, 170);

context.font = "bold 100pt 'PT Sans'";
context.textAlign = "center";
context.fillStyle = "#764abc";

context.fillText("TITLE 2", 600, 270);

// Write the image to file
loadImage("./assets/jimp-cert-template.jpg").then((image) => {
  const pattern = context.createPattern(image, "no-repeat");
  context.fillStyle = pattern;
  context.fillRect(0, 0, width, height);
  const buffer = canvas.toBuffer("image/jpeg");
  fs.writeFileSync("./image.jpeg", buffer);
});

I've tried putting the loadImage function before drawing the texts in the canvas, but that also didn't work. I want the image to be a background spanning across the canvas size and then put the texts over the image.


Solution

  • I tried adding some logs and saw the issue was that the image was getting set in the context after the texts were drawn in the context. Hence, since image was set in the context at the end, the image was coming over the text.

    Here is the working code:

    const { createCanvas, loadImage } = require("canvas");
    const fs = require("fs");
    
    // Dimensions for the image
    const width = 848;
    const height = 600;
    
    // Instantiate the canvas object
    const canvas = createCanvas(width, height);
    const context = canvas.getContext("2d");
    
    loadImage("./assets/jimp-cert-template.jpg").then((image) => {
      console.log("Drawing background Image");
      const pattern = context.createPattern(image, "no-repeat");
      context.fillStyle = pattern;
      context.fillRect(0, 0, width, height);
      context.font = "bold 70pt 'PT Sans'";
      context.textAlign = "center";
      context.fillStyle = "#764abc";
    
      console.log("Writing title1");
      context.fillText("TITLE 1", 600, 170);
    
      context.font = "bold 100pt 'PT Sans'";
      context.textAlign = "center";
      context.fillStyle = "#764abc";
      console.log("Writing title2");
      context.fillText("TITLE 2", 600, 270);
      const buffer = canvas.toBuffer("image/jpeg");
      fs.writeFileSync("./image.jpeg", buffer);
      console.log("Generated Certificate!!");
    });
    
    // Write the image to file