Published
Edited
Feb 16, 2021
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
viewof density = {
const form = html`<form>
<input name=i type=range min=0 max=100 step=1 style="width:180px;">
<output style="font-size:smaller;font-style:oblique;" name=o></output>
</form>`;
form.i.oninput = () => {
form.o.value = `${form.i.valueAsNumber}% fill`;
form.value = form.i.valueAsNumber / 100;
};
form.i.oninput();
return form;
}
Insert cell
// originally taken from https://observablehq.com/@formsandlines/4-valued-1d-cellular-automaton

canvas1 = {
const height = 600;
const context = DOM.context2d(width, height, 1);
context.canvas.style.imageRendering = "pixelated";
context.globalCompositeOperation = "copy";

// Initialize the first row.
let row1 = context.getImageData(0, 0, width, 1);

for (let i = 0; i < width; ++i) {
const rgba = [(i << 2) + 0, (i << 2) + 1, (i << 2) + 2, (i << 2) + 3];

const dice = Math.floor(Math.random()*3);
row1.data[rgba[3]] = 255;
row1.data[rgba[dice]] = (Math.random() < density) ? 255 : 0;

}

context.putImageData(row1, 0, 0);

// let row2 = context.createImageData(width, 1);
// for (let j = 1; true; ++j) {

// // Read from the first row to write to the second.
// for (let i = 0; i < width; ++i) {
// const rgba = [(i << 2) + 0, // bitshifts indices to handle rgba image data
// (i << 2) + 1,
// (i << 2) + 2,
// (i << 2) + 3];
// row2.data[rgba[0]] = row2.data[rgba[1]] = row2.data[rgba[2]] = 0; // resets all pixels to black
// row2.data[rgba[3]] = 255; // makes sure pixels are opaque

// // For each cell, check its r, g and b values and get the corresponding 6 bit integers.
// const L = BigInt(row1.data[((i > 0 ? i - 1 : width - 1) << 2) + 2]) ? 0b010000n // b (1 0 0)
// : BigInt(row1.data[((i > 0 ? i - 1 : width - 1) << 2) + 0]) ? 0b100000n // r (2 0 0)
// : BigInt(row1.data[((i > 0 ? i - 1 : width - 1) << 2) + 1]) ? 0b110000n : 0n; // g (3 0 0)
// const E = BigInt(row1.data[(i << 2) + 2]) ? 0b000100n // b (0 1 0)
// : BigInt(row1.data[(i << 2) + 0]) ? 0b001000n // r (0 2 0)
// : BigInt(row1.data[(i << 2) + 1]) ? 0b001100n : 0n; // g (0 3 0)
// const R = BigInt(row1.data[((i < width - 1 ? i + 1 : 0) << 2) + 2]) ? 0b000001n // b (0 0 1)
// : BigInt(row1.data[((i < width - 1 ? i + 1 : 0) << 2) + 0]) ? 0b000010n // r (0 0 2)
// : BigInt(row1.data[((i < width - 1 ? i + 1 : 0) << 2) + 1]) ? 0b000011n : 0n; // g (0 0 3)

// // Match the combined input values with the ruleset
// const v = matchRule(rules, (L | E | R));
// // leave 0 as is and apply matched color value
// if (v >= 0) row2.data[rgba[valToRGBindex(v)]] = 255;
// }
// // Swap the rows.
// [row1, row2] = [row2, row1];

// // Append until the canvas is full.
// if (j < height) {
// context.putImageData(row2, 0, j);
// continue;
// }

// // Otherwise, shift the canvas up before appending the new row.
// context.drawImage(context.canvas, 0, -1);
// context.putImageData(row2, 0, height - 1);
yield context.canvas;
// }
}
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