"https://coolors.co/bb1e21-1a638a-efeae0-edc46b-89847a",
"https://coolors.co/fffcf2-ccc5b9-403d39-252422-D8683C",
"https://coolors.co/c9cba3-ffe1a8-e26d5c-723d46-472d30",
const shape_size_pct = 0.8;
const min_animation_duration = fps * 2;
const max_animation_duration = fps * 5;
const animation_start_interval = 3;
const animation_start_probability = 0.8;
const noise_strength = 15;
let enqueue_save = false;
const palette = new CoolorPalette(random(coolors));
for (let x = 0; x < width; x += cell_size) {
for (let y = 0; y < height; y += cell_size) {
cells.push(new Cell(x, y, cell_size, shape_size_pct, palette));
noise_layer = createGraphics(width, height);
noise_layer.loadPixels();
for (let i = 0; i < noise_layer.pixels.length; i += 4) {
noise_layer.pixels[i] = random(255);
noise_layer.pixels[i + 1] = random(255);
noise_layer.pixels[i + 2] = random(255);
noise_layer.pixels[i + 3] = noise_strength;
noise_layer.updatePixels();
save("circles-idle-####.png");
if (frameCount % animation_start_interval == 0) {
if (random() < animation_start_probability) {
const available_cells = cells.filter((cell) => !cell.animating);
const animation_duration = random(
if (available_cells.length > 0) {
random(available_cells).animate(animation_duration);
image(noise_layer, 0, 0);
save("circles-####.png");