Published
Edited
Jul 20, 2020
Fork of Doom Fire
1 fork
1 star
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
colors = [
"rgba( 38, 37, 35, 1)",
"rgba(150, 140, 121, 1)",
"rgba(199, 82, 48, 1)",
"rgba(238, 197, 106, 1)",
"rgba(200, 184, 164, 1)",
]
Insert cell
// c = d3.scaleSequential(d3[scheme]).domain([steps, 0]) // create a color scale for the selected scheme and number of steps
// found interpolateRbgBasis in
c = function(n) {
return d3.interpolateRgbBasis(colors)(n/steps)
}
Insert cell
context = {
// initialize the canvas
let ctx = DOM.context2d(width, height);
ctx.canvas.width = width;
ctx.canvas.height = height;
ctx.canvas.id = "canvas";
ctx.canvas.style.width = "100%";
ctx.canvas.style.imageRendering = "pixelated";
if (!ctx.canvas.style.imageRendering) {
ctx.canvas.style.imageRendering = "crisp-edges";
}

// animation loop
function animate() {
// BURN
pixels.forEach(spreadFire);

// get canvas image data
let color = ctx.getImageData(0, 0, width, height);

pixels.slice(width).forEach((p, i) => {
let pixel = palette[p];
let offset = i * 4;
color.data[offset + 0] = pixel.r;
color.data[offset + 1] = pixel.g;
color.data[offset + 2] = pixel.b;
color.data[offset + 3] = 255;
});
// replace canvas with updated pixel data
ctx.putImageData(color, 0, 0);
}

// TODO: keep track of this interval so we can clear it if this cell is rerun
// using an interval here instead of
// requestanimationframe because the
// animation speed is tied directly to
// the frame rate
const i = setInterval(animate, 62);
invalidation.then(() => i.stop())

return ctx;
}
Insert cell
spreadFire = (pixel, src) => {
// this is the core algorithm behind
// the doom fire technique
if (pixel === 0) {
pixels[src - width] = 0;
} else {
// generate a random number between 0-3
// not sure what this bitwise 3 is accomplishing?
let randIdx = Math.round(Math.random() * 3) & 3;
// use the random number to offset the value
// of the current pixel
let dst = src - randIdx + 1;
// grab the value of the index in the row
// beneath the current row?
pixels[dst - width] = pixel - (randIdx & 1);
}
}
Insert cell
Insert cell
Insert cell
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more