Generating Matrix-Rain Avatars with Canvas and gif.js

Upload a static profile picture and walk away with an animated Matrix-style avatar that drips green glyphs. A live demo is here.

Quick start

  1. Pick a square photo—round crops look better.
  2. If the falling characters look off, tweak the tint until they match the vibe.
  3. Happy with the preview? Right-click → "Save image as…" or hit the download button.

gif.js in a nutshell

gif.js is a zero-dependency browser library that builds animated GIFs from canvas frames. It off-loads heavy pixel work to Web Workers so the UI stays snappy.

// bare-bones setup
const encoder = new GIF({
  workers: 4,
  quality: 20,
  workerScript: './gif.worker.js' // mandatory for worker mode
});

// grab a frame
encoder.addFrame(canvas, { delay: 100 });

// repeat for every frame
for (let i = 0; i < totalFrames; i++) {
  drawFrame(i);
  encoder.addFrame(canvas, { delay: 100 });
}

encoder.on('finished', blob => {
  const url = URL.createObjectURL(blob);
  const a = document.createElement('a');
  a.href = url;
  a.download = 'matrix-avatar.gif';
  a.click();
});

encoder.render();

Matrix-rain logic

The glyph shower is a classic column drop. Each column has:

  • a head that moves downward,
  • a tailLength that fades behind it,
  • a random chance too spawn a new head at the top.
const COLS = 32;
const ROWS = 32;
const FONT_SIZE = 12;

const glyphs = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split('');
const columns = Array.from({ length: COLS }, () => ({
  y: Math.random() * -ROWS,
  speed: 1 + Math.random() * 3,
  tail: 8 + Math.floor(Math.random() * 10)
}));

function drawFrame() {
  ctx.fillStyle = 'rgba(0, 0, 0, 0.05)';
  ctx.fillRect(0, 0, canvas.width, canvas.height);

  ctx.font = `${FONT_SIZE}px monospace`;
  ctx.fillStyle = '#00ff41';

  for (let x = 0; x < COLS; x++) {
    const col = columns[x];
    for (let i = 0; i < col.tail; i++) {
      const y = col.y - i;
      if (y >= 0 && y < ROWS) {
        const char = glyphs[Math.floor(Math.random() * glyphs.length)];
        ctx.fillText(char, x * FONT_SIZE, y * FONT_SIZE);
      }
    }
    col.y += col.speed;
    if (col.y - col.tail > ROWS) {
      col.y = Math.random() * -col.tail;
      col.speed = 1 + Math.random() * 3;
    }
  }
}

Overlaying the avatar

After each rain pass, compostie the user’s image on top with a soft-light blend so the face remains recognizable.

ctx.globalCompositeOperation = 'soft-light';
ctx.drawImage(userImage, 0, 0, canvas.width, canvas.height);
ctx.globalCompositeOperation = 'source-over';

Full source is on GitHub; open DevTools on the demo page for instant tinkering.

Tags: gif.js Canvas web-workers matrix-effect avatar-generator

Posted on Sat, 03 Oct 2026 16:29:59 +0000 by gunslinger008