Canvas interaction
The setup function returns several utilities for interacting with the grid at runtime. Beyond update and draw, you can read the current state, overwrite the entire grid, or update individual cells — all while the simulation is running.
const { update, draw, readGrid, writeGrid, writeCell, writeCellAt } = setup({ canvas, automaton,});Reading the grid
Section titled “Reading the grid”readGrid returns a Promise that resolves to a flat array of element indices, in row-major order (left to right, top to bottom). Each value corresponds to an element’s .index.
const snapshot = await readGrid();// snapshot is a number[] of length width * heightThis is useful for inspecting the current state, running analytics, or saving a snapshot that can be restored later.
Writing the entire grid
Section titled “Writing the entire grid”writeGrid replaces every cell at once. Pass a flat array of element indices whose length must equal width * height:
writeGrid(snapshot); // restore a previously saved snapshotThe function validates every index in the array and throws if any value is out of range.
Writing a single cell
Section titled “Writing a single cell”writeCell updates one cell without touching the rest of the grid. Pass the flat index of the cell and the element index to assign:
writeCell(index, alien.index);The flat index for a cell at column x and row y in a grid of width width is y * width + x.
If you prefer working with grid coordinates instead of flat indices, use writeCellAt:
writeCellAt(x, y, alien.index);Practical examples
Section titled “Practical examples”Click to paint
Section titled “Click to paint”Let users draw on the canvas by converting mouse coordinates to cell coordinates and calling writeCellAt:
const { update, draw, writeCellAt } = setup({ canvas, automaton });
canvas.addEventListener("click", (e) => { const rect = canvas.getBoundingClientRect();
// Scale from CSS pixels to grid cells const x = Math.floor((e.clientX - rect.left) * (canvas.width / rect.width)); const y = Math.floor((e.clientY - rect.top) * (canvas.height / rect.height));
writeCellAt(x, y, alien.index);});Pause, snapshot, resume
Section titled “Pause, snapshot, resume”Save the grid state so you can rewind:
const { update, draw, readGrid, writeGrid } = setup({ canvas, automaton });
let saved: number[] | null = null;
document.getElementById("save")!.addEventListener("click", async () => { saved = await readGrid();});
document.getElementById("restore")!.addEventListener("click", () => { if (saved) writeGrid(saved);});