JSFiddle - React, Tailwind, and code Playground

by fxi

HTML

<input id="slider" type="number" step="1" min="0" max="255" value="30">

<canvas id="canvas"></canvas>

CSS

html,
body {
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0;
}

JavaScript

const elSlider = document.getElementById('slider');

elSlider.addEventListener('input', (e) => {
  config.ruleNumber = e.target.value * 1;
 update();
})

// Configuration
const config = {
  cellResolution: 5, // Size of each cell in pixels
  ruleNumber: 73  // Rule number for the automaton
};

elSlider.value = config.ruleNumber ;

// Initialization
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");
canvas.width = document.body.clientWidth;
canvas.height = document.body.clientHeight;


function update() {
  // Convert the rule number to binary
  config.ruleBinary = config.ruleNumber.toString(2).padStart(8, '0').split('').map(Number);


  // Starting state with a single '1' in the middle
  config.rowWidth = Math.floor(canvas.width / config.cellResolution);
  let currentState = Array(config.rowWidth).fill(0);
  currentState[Math.floor(config.rowWidth / 2)] = 1;
  draw(currentState);
}


// Compute next state based on the rule
function computeNextState(current) {
  let newState = [];
  for (let i = 0; i < current.length; i++) {
    let left = current[i - 1] || 0;
    let center = current[i];
    let right = current[i + 1] || 0;
    let ruleIndex = 7 - (left * 4 + center * 2 + right);
    newState[i] = config.ruleBinary[ruleIndex];
  }
  return newState;
}

// Draw function
function draw(currentState) {
  for (let y = 0; y < canvas.height; y += config.cellResolution) {
    for (let x = 0; x < config.rowWidth * config.cellResolution; x += config.cellResolution) {
      let cellState = currentState[Math.floor(x / config.cellResolution)];
      ctx.fillStyle = cellState === 1 ? 'black' : 'white';
      ctx.fillRect(x, y, config.cellResolution, config.cellResolution);
    }
    currentState = computeNextState(currentState);
  }
}
update()