JSFiddle - React, Tailwind, and code Playground

by gkucmierz

HTML

<canvas width="600" height="400"></canvas>
<button>RESET</button>

JavaScript

var c = document.getElementsByTagName('canvas')[0];
var ctx = c.getContext('2d');

let cells = random(0.5);
let MAX_SIZE = 256;
let FADE_OUT = 0.5; // 1 = immediately, 0 = never

(function loop() {
  draw(ctx, cells);
  cells = nextGen(cells);

  let empty = cells.length === 0 || cells[0].length === 0;
  let big = cells.length > MAX_SIZE || (cells[0] && cells[0].length > MAX_SIZE || 0);
  if (empty || big) {
    reset();
  }
  requestAnimationFrame(loop);
}());

document.getElementsByTagName('button')[0].addEventListener('click', reset);

function reset() {
  cells = random(0.5);
}

function draw(ctx, cells) {
  let [h, w] = [cells.length, cells[0].length];
  let [ch, cw] = [ctx.canvas.height, ctx.canvas.width];
  let sq = Math.min(ch / h, cw / w);
  let [xd, yd] = [(cw / w - sq) * w * 0.5, (ch / h - sq) * h * 0.5];

  ctx.fillStyle = `rgba(0, 0, 0, ${FADE_OUT})`;
  ctx.fillRect(0, 0, cw, ch);

  ctx.fillStyle = 'rgb(63, 255, 0)';
  for (let i = 0; i < h; ++i) {
    for (let j = 0; j < w; ++j) {
      if (cells[i][j]) {
        ctx.fillRect(xd + j * sq, yd + i * sq, sq, sq);
      }
    }
  }
}

function random(fill = 0.5) {
  let [h, w] = [Math.random() * 10 + 5 | 0, Math.random() * 10 + 5 | 0];
  let r = [];
  for (let i = 0; i < h; ++i) {
    r[i] = [];
    for (let j = 0; j < w; ++j) {
      r[i][j] = Math.random() < fill ? 1 : 0;
    }
  }
  return r;
}

function nextGen(cells) {
  let h = cells.length;
  let w = cells[0].length;
  let m = [];
  let ne = [
    [-1, -1],
    [0, -1],
    [1, -1],
    [-1, 0],
    [1, 0],
    [-1, 1],
    [0, 1],
    [1, 1],
  ];
  for (let y = 0; y < h + 2; ++y) {
    m[y] = [];
    for (let x = 0; x < w + 2; ++x) {
      m[y][x] = 0;
      for (let n = 0; n < ne.length; ++n) {
        let row = cells[y - 1 + ne[n][1]];
        if (row) {
          m[y][x] += row[x - 1 + ne[n][0]] || 0;
        }
      }

      if (m[y][x] === 3) {
        m[y][x] = 1;
      } else {
        if (m[y][x] === 2) {
          let c = cells[y - 1]...