Day 16 - Art 1

Generative palette

Color Harmony Generator

This generative art piece creates a dynamic grid of colors, continuously shifting between five distinct color harmonies: complementary, monochromatic, analogous, triadic, and tetradic. Every 5 seconds, the color mode changes, producing a new palette that fills the grid. The colors are randomly generated within the chosen harmony, creating visually interesting and evolving patterns. The piece explores color theory and its application in generative art, offering a constantly changing visual experience.

    // Define the size of the grid (number of rows and columns)
    let gridSize = 20; 
    // Array to hold the colors for each grid cell
    let colors = [];
    // Variable to define the size of each grid cell
    let cellSize;
    // Variable to track the current color mode (0: Complementary, 1: Monochromatic, 2: Analogous, 3: Triadic, 4: Tetradic)
    let currentMode = 0; 
    // Variable to hold the canvas element
    let canvas;
    
    function setup() {
      // Create a 400x400 canvas and attach it to a parent container
      canvas = createCanvas(400, 400);
      canvas.parent('canvas-container');
      
      // Set color mode to HSB for easier manipulation of hue, saturation, and brightness
      colorMode(HSB, 360, 100, 100);
      
      // Calculate the size of each grid cell based on the canvas width and grid size
      cellSize = width / gridSize;
      
      // Generate the initial color palette
      generatePalette();
      
      // Set up a timer to switch the color mode every 5 seconds
      setInterval(switchMode, 5000);
    }
    
    function draw() {
      // Set the background color of the canvas
      background(220);
      
      // Draw the color palette on the grid
      drawPalette();
    }
    
    // Generate a color palette based on the current mode
    function generatePalette() {
      // Clear the previous colors
      colors = [];
      
      // Generate a random base hue for the color palette
      let baseHue = random(360);
      
      // Loop through each grid cell and generate a color based on the current mode
      for (let y = 0; y < gridSize; y++) {
        for (let x = 0; x < gridSize; x++) {
          let newColor;
          switch (currentMode) {
            case 0:
              // Complementary colors: Colors that are opposite each other on the color wheel
              newColor = getComplementary(baseHue);
              break;
            case 1:
              // Monochromatic colors: Variations of a single hue with different saturation and brightness
              newColor = getMonochromatic(baseHue);
              break;
            case 2:
              // Analogous colors: Colors that are next to each other on the color wheel
              newColor = getAnalogous(baseHue);
              break;
            case 3:
              // Triadic colors: Three colors evenly spaced around the color wheel (120° apart)
              newColor = getTriadic(baseHue);
              break;
            case 4:
              // Tetradic colors: Four colors that form a rectangle on the color wheel
              newColor = getTetradic(baseHue);
              break;
          }
          // Add the generated color to the colors array
          colors.push(newColor);
        }
      }
    }
    
    // Draw the color palette on the grid
    function drawPalette() {
      // Loop through each grid cell and draw a rectangle filled with the corresponding color
      for (let y = 0; y < gridSize; y++) {
        for (let x = 0; x < gridSize; x++) {
          let index = x + y * gridSize; // Calculate the index in the colors array
          fill(colors[index]); // Set the fill color
          rect(x * cellSize, y * cellSize, cellSize, cellSize); // Draw the rectangle
        }
      }
    }
    
    // Switch to the next color mode and regenerate the palette
    function switchMode() {
      // Cycle through the color modes (0 to 4)
      currentMode = (currentMode + 1) % 5;
      // Regenerate the color palette based on the new mode
      generatePalette();
    }
    
    // Generate a complementary color (180° opposite on the color wheel)
    function getComplementary(baseHue) {
      return color((baseHue + 180) % 360, random(60, 100), random(60, 100)); // Random saturation and brightness
    }
    
    // Generate a monochromatic color (same hue with varying saturation and brightness)
    function getMonochromatic(baseHue) {
      return color(baseHue, random(20, 60), random(60, 100)); // Vary saturation and brightness
    }
    
    // Generate an analogous color (colors next to each other on the color wheel)
    function getAnalogous(baseHue) {
      let shift = random([-30, 30]); // Small shift for analogous colors
      return color((baseHue + shift + 360) % 360, random(60, 100), random(60, 100)); // Random saturation and brightness
    }
    
    // Generate a triadic color (120° apart on the color wheel)
    function getTriadic(baseHue) {
      let shift = random([120, 240]); // Triadic colors are 120° apart
      return color((baseHue + shift) % 360, random(60, 100), random(60, 100)); // Random saturation and brightness
    }
    
    // Generate a tetradic color (four colors forming a rectangle on the color wheel)
    function getTetradic(baseHue) {
      let tetradicHues = [
        baseHue,
        (baseHue + 90) % 360,
        (baseHue + 180) % 360,
        (baseHue + 270) % 360,
      ];
      let hue = random(tetradicHues); // Randomly pick one of the tetradic hues
      return color(hue, random(60, 100), random(60, 100)); // Random saturation and brightness
    }