transition = {
const cellWidth = 10;
const cellHeight = 10;
const rows = 30;
const cols = 40;
const generations = 60;
const genTime = 1;
d3.select('#glfield2')
.attr('width', cellWidth * cols)
.attr('height', cellHeight * rows);
function update(selection, data) {
const cells = selection
.selectAll("rect").data(data, d => `${d[0]}_${d[1]}`);
cells.exit()
.style('fill', 'blue')
.style('opacity', 1)
.transition()
.duration(genTime * 500)
.style('opacity', 0)
.on('end', function () {
d3.select(this).remove();
});
cells.enter().append("rect")
.attr('x', d => d[0] * cellWidth)
.attr('y', d => d[1] * cellHeight)
.attr('width', cellWidth)
.attr('height', cellHeight)
.style('fill', 'red')
.transition()
.duration(genTime * 500)
.style("fill", "black");
}
let gen = pattern
const end = generations * genTime * 1000;
const interval = genTime * 1000;
d3.select('#glfield2').call(update, gen);
const t = d3.interval(elapsed => {
if (elapsed > end || !gen.length) t.stop();
gen = tick(gen);
d3.select('#glfield2').call(update, gen);
}, interval);
}