Skip to main content
Photography of Alvaro Montoro being a doofus
Alvaro Montoro

Command Line Lover

Joshua-Paul Meme Generator

After the boxing match between Joshua and Blake, I put together a small meme generator demo inspired by one of the match's most iconic images. In this article I explain how it's done.

html javascript webdev showdev

Ever wanted to build a meme generator from scratch? It's a fun and straightforward project that's ideal for practicing JavaScript and the Canvas API. With just a few standard building blocks, we can have a basic, functional demo up and running in no time. No big frameworks, libraries, or any external dependencies needed.

All we need is an image and one or more text input fields, depending on the type of meme we want to create. The HTML structure itself is fairly simple:

<textarea></textarea>
<!-- As many textareas as needed -->
<canvas></canvas>

Next, we'll initialize the canvas and load the background image in JavaScript. It's important to explicitly set the canvas width and height to match the image dimensions (or at least with the same aspect ratio) to avoid unwanted scaling or distortion.

const WIDTH  = 500; // set the size you want
const HEIGHT = 600; //
const textarea = document.querySelector("textarea");
const canvas = document.querySelector("canvas");
const ctx = canvas.getContext("2d");

// set up the canvas
canvas.width = WIDTH;
canvas.height = HEIGHT;

// load the image in the background
const background = new Image();
background.src = "https://path-to-meme-image";
background.onload = function(){
  ctx.drawImage(background, 0, 0, WIDTH, HEIGHT);   
}

Finally, we'll add an event listener to the textarea so that the meme updates every time the text changes. For the typography, we'll use Impact as the default font, since it's the most commonly used typeface in classic memes.

Note: There are many ways to handle multiline text on a canvas. For simplicity, this article assumes that users control line breaks manually by pressing Enter.

// function to be called when text changes
const updateMeme = () => {
  // reset the background picture
  ctx.drawImage(background, 0, 0, WIDTH, HEIGHT); 

  // set the specs for text and outline
  ctx.textAlign = "center";
  ctx.font = "50px Impact,sans-serif";
  ctx.fillStyle = "white";
  ctx.strokeStyle = "black";
  ctx.lineWidth = "2";
  
  const LEFT = 250;
  const TOP  = 300;

  // break the text in lines and display them one by one
  const lines = textarea.value.split("\n");
  for (let x = 0; x < lines.length; x++) {
    ctx.fillText(lines[x], LEFT, TOP + x * 50);
    ctx.strokeText(lines[x], LEFT, TOP + x * 50);
  }
}

// add the event listener when text changes
textarea.addEventListener("input", updateMeme);

And that's all we need! With just a canvas, an image, and a text input, we've built a functional meme generator from scratch. From here, you can easily extend it by adding more features:

  • Image selection
  • Multiple text fields
  • Font controls
  • Positioning options
  • Automatic text resize/wrapping
  • Export button
  • Anything that you can imagine!

However, for a single-image meme generator, this minimal setup already gets the job done. I'll let you add some of the other features (and please share! I'll love to see them)

Demos

The smiling demo...

And using a different picture/angle:

Article originally published on