JSFiddle - React, Tailwind, and code Playground
HTML
<div id=sim class=no>Simulate?</div><!--div id=options><input name="scale" type="text" value="50,50" size="8"></div>-->
<canvas id=c width="500" height="500"></canvas>
CSS
html, body {
margin: 0;
background-color: hsla(0,0%,10%,1.00);
overflow: hidden;
color: white;
} * {-webkit-touch-callout: none;-webkit-user-select: none;-khtml-user-select: none;-moz-user-select: none;-ms-user-select: none;user-select: none;}
#c {
background-color: hsla(0,0%,0%,1.00); position: absolute;
top: calc(50% - 500px/2);
left: calc(50% - 500px/2);
}
#sim {
position: absolute;
top: calc(50% - 540px/2 - 6px);
left: calc(50% - 500px/2);
border: 1px solid;
border-left-width: 10px;
border-right-width: 10px;
padding: 2px;
cursor: pointer;
}
#sim.no {
border-color: hsla(359,91%,52%,1.00);
}
#sim.yes {
border-color: hsla(118,91%,52%,1.00);
}
#options {
position: absolute;
top: calc(50% - 540px/2 - 6px);
left: calc(50% - 500px/2 + 82px);
}
JavaScript
var ce = document.getElementById('c'), // Canvas element
c = ce.getContext('2d'), // Context
sim = document.getElementById('sim'), // "Simulate?" button
highlighted = [-1,-1], // Mouse position
clicking = false, // Use for disabled and hidden click and drag functionality
simulating = false, // Is it happening?
cells = [], // The data
size = [50, 50], // Default size
vsize = [ce.width/size[0], ce.height/size[1]], // Pre-set size
bg = null; // Grid background placeholder
function draw() {
//ce.width = ce.width; // Basic clear
if(!simulating) c.fillStyle = bg; // Grid background
else c.fillStyle = 'hsla(180,100%,25%,.15)'; // Fancy graphics
c.fillRect(0,0,ce.width, ce.height);
if(simulating) c.drawImage(ce, 1, -1, ce.width, ce.height); // Fancy graphics
tC = cells; // Temporary cells (for checking against previous frame)
for(var y = 0; y < size[1]; y++) {
for(var x = 0; x < size[0]; x++) {
var cell = tC[x][y], ne = 0; // The relevant cell; alive cell count
if(simulating) { // If simulating, otherwise just save processing time/power
// top topright right bottomright bottom bottomleft left topleft
var x2 = x+1, x3 = x-1, y2 = y+1, y3 = y-1; // Math
if(tC[x][y3] !== undefined && tC[x][y3]) ne++; // T
if(tC[x][y2] !== undefined && tC[x][y2]) ne++; // TR
if(tC[x2] !== undefined) {
if(tC[x2][y]) ne++; // R
if(tC[x2][y3] !== undefined && tC[x2][y3]) ne++; // BR
if(tC[x2][y2] !== undefined && tC[x2][y2]) ne++; // B
}
if(tC[x3] !== undefined) {
if(tC[x3][y]) ne++; // BL
if(tC[x3][y3] !== undefined && tC[x3][y3]) ne++; // L
if(tC[x3][y2] !== undefined && tC[x3][y2]) ne++; // TL
}
/*
1. Any live cell with fewer than two live neighbours dies, as if caused by under-population.
2. Any live cell with two or three live neighbours lives on to the next...