Time: Calenders // ICM W5

Oct 6, 2024

The Assignment

This weeks assignment was to create a visual representation of time using p5.js. The brief emphasized the theme of "organization" and asked us to consider various aspects of time, such as:

  • The passing of time through change, motion, or accumulation of elements

  • The relativity of time

  • Time twisted or captured

  • The stillness of time

I interpreted this as an opportunity to explore how we perceive and organize time visually. I wanted to create something that would show both the gradual accumulation of moments and the ever-changing nature of our perception of time

Inspiration

My main inspiration came from Ellsworth Kelly's "Spectrum Colors Arranged by Chance III" (1951). This artwork resonated with me because:

  • Its grid structure reminded me of how we often organize time (calendars, schedules)

  • The seemingly random arrangement of colors felt like a perfect metaphor for the unpredictability of events in time

  • The vibrancy of the colors represents the intensity of different moments or memories

I saw a connection between Kelly's work and the assignment's theme of organizing time. Just as Kelly arranged colors by chance, I wanted to create a digital piece that would fill with colors over time, representing the accumulation of moments, and then continually change, symbolizing how our perception of past events can shift.

Developing the Idea:

Before diving into coding, I sketched out my idea and developed a pseudo code outline to clarify the logic:

  1. Start with an empty grid

  2. Gradually fill the grid with random colors

  3. Once filled, periodically change all colors

This process would represent:

  • The gradual accumulation of experiences over time

  • The randomness of events in our lives

  • How our perception or memory of past events can change

I planned to use a 20x20 grid, giving me 400 "moments" to work with. Each square would be a different color, sampled from Kelly's artwork.

Here's the full pseudo code I developed:

INITIALIZE:
    Create array of colors from Kelly's artwork
    Set grid size to 20x20
    Create empty array 'pixels' of size 400 (20x20)
    Create array 'emptyPixels' with numbers 0 to 399
    Set boolean 'fillingComplete' to false

FUNCTION setup:
    Create canvas 400x400 pixels
    Calculate size of each grid square

FUNCTION draw:
    Clear canvas with background color

    IF NOT fillingComplete:
        CALL fillPixel
    ELSE IF it's time to change colors (every 0.5 seconds):
        CALL changeAllColors

    CALL drawPixels

FUNCTION fillPixel:
    IF emptyPixels is not empty:
        Choose random index from emptyPixels
        Set pixels[chosen index] to random color from color array
        Remove chosen index from emptyPixels
    ELSE:
        Set fillingComplete to true

FUNCTION changeAllColors:
    FOR EACH pixel in pixels:
        Set pixel to new random color from color array

FUNCTION drawPixels:
    FOR EACH pixel in pixels:
        IF pixel is not null:
            Calculate x position: (index % 20) * square size
            Calculate y position: (index / 20, rounded down) * square size
            Draw square at (x, y) with pixel's color

REPEAT draw function continuously

This pseudo code outlines the core logic of the sketch:

  • Initializing the necessary data structures

  • The main draw loop that manages the state of the animation

  • Functions for filling pixels, changing colors, and drawing the grid

By planning out the logic in this way, I was able to clearly see how each part of the sketch would work before starting to code. This made the implementation process much smoother and helped me identify potential issues early on.

Final Product and Code

The final product is an sketch that creates an animated, colorful grid representing the passage and perception of time. The animation creates a mesmerizing visual representation of time, with squares gradually appearing and then all shifting colors in unison, evoking the idea of collective moments and changing perceptions.

Here's the full code for the sketch:

// Array of colors sampled from Ellsworth Kelly's "Spectrum Colors Arranged by Chance III"
// These colors will be used to fill our grid, representing different moments or events in time
const colors = [
  "#F2385A",
  "#F5A503",
  "#E9F1DF",
  "#4AD9D9",
  "#36B1BF",
  "#E3B8B5",
  "#FFD872",
  "#E1D0B3",
  "#BFD9B5",
  "#A8D9D3",
  "#D9AC8E",
  "#F2C2B8",
  "#F2B5D4",
  "#94E2F2",
  "#52B9D3",
  "#6C49B8",
  "#8E3D87",
  "#D3B0B0",
  "#D9C589",
  "#8FD3B5",
];

// Define the size of our grid. 20x20 gives us 400 "moments" to represent, (doing this turns our 2D drawing into 2D)
const gridSize = 20;

// This array will store the color of each square in our grid
// Initially, all elements are emptyu
let pixels = [];

// The size of each square in our grid, calculated based on canvas size
let pixelSize;

// A Boolean to indicate when we've filled all squares and should start changing colors
let fillingComplete = false;

// This array keeps track of which grid positions are still empty
// This will help us select random unfilled positions in the "grid"
let emptyPixels = [];

function fillPixel() {
  if (emptyPixels.length > 0) {
    // Randomly select an empty position from the array
    // Generates a random index in the emptyPixels array by rounding a random float between 0 and emptyPixels.length using floor

    const index = floor(random(emptyPixels.length));
    const pixelIndex = emptyPixels[index];

    // Fill this position with a random color from colour array
    pixels[pixelIndex] = random(colors);

    // Removes one element from emptyPixels at the specified index, modifying the array (splice(): This is a JavaScript array method that changes the contents of an array by removing, replacing, or adding elements.)

    emptyPixels.splice(index, 1);
  } else {
    // If no empty positions left, we're done with the filling phase
    fillingComplete = true;
  }
}

function changeAllColors() {
  // Assign a new random color to every position in our grid

  for (let i = 0; i < pixels.length; i++) {
    pixels[i] = random(colors);
  }
}

function drawPixels() {
  for (let i = 0; i < pixels.length; i++) {
    if (pixels[i]) {
      // Only draw squares that have been filled
      // Calculate x position:
      // i % gridSize gives us the column number (0-19)
      // Multiplying by pixelSize converts to canvas coordinates
      const x = (i % gridSize) * pixelSize;

      // Calculate y position:
      // Math.floor(i / gridSize) gives us the row number (0-19)
      // Multiplying by pixelSize converts to canvas coordinates
      const y = Math.floor(i / gridSize) * pixelSize;

      // IMP ( By using % for x and / for y, we're essentially "unwrapping" our 1D array into a 2D grid. The modulo wraps around for each row (giving us the column), while the division tells us which row we're on.)

      // Set the fill color for this square
      fill(pixels[i]);

      // Draw the square at (x, y) with size pixelSize
      square(x, y, pixelSize);
    }
  }
}

function setup() {
  createCanvas(400, 400);

  // Calculate the size of each grid square
  pixelSize = width / gridSize;

  // We don't want outlines on our squares
  noStroke();

  // Initialize our grid: all positions start empty (null) and are added to emptyPixels, doing this in setup so when our functions are implemented they have a data structure ready to go into for the pixels
  for (let i = 0; i < gridSize * gridSize; i++) {
    pixels.push(null);
    emptyPixels.push(i);
  }
}

function draw() {
  background("#F4F2EF");

  // we're working in two phases: filling empty squares, then changing all colors, (!fillingiComplete checks wether the boolean is still flase, it will turn true from the fillPixel function over time as the grid is filled
  if (!fillingComplete) {
    fillPixel(); // Fill one random empty square
  } else if (frameCount % 30 === 0) {
    // Once filled, change all colors every 30 frames (0.5 seconds at 60fps). if we remove this each pixel will flashe super quickly.
    changeAllColors();
  }

  // Draw all of our colored squares
  drawPixels();
}
References
  1. Nik's Blog
  2. Claude by Anthropic
  3. Ellen for being such a great teacher
  4. https://p5js.org/reference
  5. Kelly, E. (1951). Spectrum Colors Arranged by Chance III. [Painting].
  6. Shiffman, D. (n.d.). The Coding Train. https://thecodingtrain.com/ (For p5.js tutorials and inspiration)

©2019-2025 SURYA NARREDDI.

©2019-2025 SURYA NARREDDI.