JSFiddle - React, Tailwind, and code Playground
by acbabis
HTML
<button class="advance">
Advance
</button>
<label>Run <input type="checkbox" class="run"></label>
<label>Delay <input type="text" class="delay" value="1000"></label>
SCSS
$cell-width: 15px;
.row {
height: $cell-width;
}
.cell {
display: inline-block;
width: $cell-width;
height: $cell-width;
background-color: #999;
border: solid 1px #666;
}
.cell.alive {
background-color: yellow;
}
JavaScript
const WIDTH = 20;
let grid = new Array(WIDTH).fill(0).map(() => new Array(WIDTH).fill(false));
const gridDom = buildDom(grid);
const checkbox = document.querySelector('.run');
const delay = document.querySelector('.delay');
function elemHelper(elemName, className) {
const elem = document.createElement(elemName);
elem.classList.add(className);
return elem;
}
function buildDom(grid) {
const gridDom = elemHelper('div', 'grid');
grid.map((row) => {
const rowDom = elemHelper('div', 'row');
row.forEach(() => rowDom.appendChild(elemHelper('div', 'cell')));
return rowDom;
}).forEach((row) => gridDom.appendChild(row));
document.body.appendChild(gridDom);
return gridDom;
}
function refresh(grid) {
Array.from(gridDom.children).forEach(function(row, y) {
Array.from(row.children).forEach(function(cell, x) {
cell.classList.toggle('alive', grid[x][y]);
})
})
}
function getCell(grid, x, y) {
const col = grid[x];
return col && col[y] || false;
}
function getNeighborsCount(grid, x, y) {
return [
getCell(grid, x - 1, y - 1),
getCell(grid, x - 0, y - 1),
getCell(grid, x + 1, y - 1),
getCell(grid, x - 1, y + 0),
getCell(grid, x + 1, y + 0),
getCell(grid, x - 1, y + 1),
getCell(grid, x - 0, y + 1),
getCell(grid, x + 1, y + 1)
].filter(Boolean).length;
}
function nextState(grid) {
return grid.map(function(col, x) {
return col.map(function(cell, y) {
const neighborsCount = getNeighborsCount(grid, x, y);
if (neighborsCount === 2) {
return cell;
} else {
return neighborsCount === 3;
}
})
});
}
function getCoords(cellDom) {
const rowDom = cellDom.parentElement;
const gridDom = rowDom.parentElement;
const x = Array.prototype.indexOf.call(rowDom.children, cellDom);
const y = Array.prototype.indexOf.call(gridDom.children, rowDom);
return { x, y };
}
gridDom.addEventListener('click', function(event) {
const target = event.target;
...