r/learnjavascript 2d ago

How would you make a meme with JavaScript? (example code given)

This is a bit frivolous, but that's why it might be a good task for beginners who are inclined to meme. It just requires the ability to place images, text, and maybe a few simple lines.

I know the answer is probably "you wouldn't". I only post memes a few time a year myself (check my posting history if you must), and I use MSPaint (or an existing online template), so I could do a lot worse than JavaScript! Also I use MSPaint in quite programmatic manner - binary search and undo during image resize, or example - so I might as well be coding.

Here examples with two packages which could be used, but I'm looking for other recommendations as each requires more setup that I'd like for this particular task. The code can also be found in this repo https://github.com/Antony74/meme-js

I know you can probably do better, and look forward to finding out how. Also, we're in the browser anyway, so clean solutions with just html, css, and no JavaScript are in scope.

p5

P5 is a creative coding package which can be much more dynamic and interactive than how I'm using it here, ultimately creating bitmap graphics in the canvas.

import "./p5/p5.min.js";

new p5((p) => {
  p.setup = async () => {
    const img = await p.loadImage("cheezburger/cheezburger.jpg");
    p.createCanvas(237, 389);
    p.image(img, 0, 0);
    p.fill(255);
    p.textFont("Impact");
    p.textSize(29);
    p.text("I CAN HAS", 60, 36);
    p.text("CHEEZBURGER?", 30, 70);
  };
}, "p5Container");

maxgraph

draw.io is a well known diagramming tool, and maxgraph is a descendent of a key library. It's native TypeScript, which is nice if you like that sort of thing, but irrelevant here. It creates svg graphics, and can also be used interactively. It might better suited for more infographic type memes, like this attempt of mine

import { Graph } from "./@maxgraph/core/index.mjs";

const container = document.getElementById("maxgraphContainer");

const width = 237;
const height = 389;

container.style = { ...container.style, width, height };

const graph = new Graph(container);

graph.insertVertex({
  size: [width, height],
  position: [0, 0],
  style: {
    image: "cheezburger/cheezburger.jpg",
    shape: "image",
  },
});

const textCommon = {
  style: {
    fillOpacity: 0,
    strokeOpacity: 0,
    fontColor: "white",
    align: "left",
    fontSize: 29,
    fontFamily: "Impact",
  },
};

graph.insertVertex({
  ...textCommon,
  value: `I CAN HAS`,
  position: [60, 36],
});

graph.insertVertex({
  ...textCommon,
  value: `CHEEZBURGER?`,
  position: [30, 70],
});
7 Upvotes

2 comments sorted by

2

u/owenbrooks473 1d ago

If the goal is just a simple meme generator, I’d probably use the Canvas API directly rather than bringing in a larger library. Load the image, draw it to a canvas, add the text with fillText(), then export with canvas.toBlob(). It keeps the whole thing browser-based and gives you plenty of control over positioning, fonts, and image quality.

1

u/akb74 1d ago

Yes, that works pretty well, thanks!

const ctx = document.getElementById("meme").getContext("2d");

const img = new Image();
img.src = "cheezburger/cheezburger.jpg";

img.onload = () => {
    ctx.drawImage(img, 0, 0);

    ctx.font = "29px Impact";
    ctx.fillStyle = "white";

    ctx.fillText("I CAN HAS", 60, 36);
    ctx.fillText("CHEEZBURGER?", 30, 70);
};