Semantic Structures:

Transformation(s) Parameters Iterations Instances

Transformation(s)

The first step in building a generative design system with p5.js is called a transformation. It is the behavior or interaction between two or more elements in the sense of computer vision.

Transformations are found in a wide range of everyday situations involving objects, humans, and even nature. For example, when we hold a pencil with our hand and apply it on a paper, we transform those elements (pencil, hand, paper) into a drawing action. Transformations also occur in nature. For instance, the sail of a sailboat interacts with the wind and water, transforming the inanimate boat into a moving one.

Generative grids

A grid is the simplest yet most fundamental form of transformation with p5.js. It is the result of a row (X-Axis) interacting with a column (Y-Axis) or vice versa in a coordinate system where the upper left corner is the value 0 for both axes. Both elements are transformed into a grid where each cell can be accessed and manipulated through different code combinations thanks to the for loop function.

 
    function setup() {
        createCanvas(600, 600);
      }
      
      function draw() {
        background(255);
        let cellSize = 100; 
        let rows = height
        let cols = width 
      
        // Draw grid
        for (let x = 0; x < rows; x+=100) {
          for (let y = 0; y < cols; y+=100) {
      
              fill(255)
            rect(x,y, cellSize);
      
            // Display position inside each rectangle
            if (y === 0 & x > 0) {
              fill(0);
              textAlign(CENTER, CENTER);
              text(x, x + cellSize / 2, y + cellSize / 2);
            } else if (x === 0 && y > 0) {
              fill(0);
              textAlign(CENTER, CENTER);
              text(y, x + cellSize / 2, y + cellSize / 2);
            }
          }
        }
      }              
                          
                        

A simple grid is just a base. We can access the grid through different creative ways lets using new coding functions. For instance, we can create conditions to fill certain parts of the grid with a new color. These conditions are executed with for loops. In each variation, we tell the program to paint certain sections of the grid depending on a minimum value on the X axis and Y axis.

 
    function setup() {
        createCanvas(800, 800);
        noLoop();
      }
      
      function draw() {
        background(255);
        let cellSize = 100; 
        let rows = height;
        let cols = width;
      
        for (let x = cellSize; x < rows + cellSize; x += cellSize) {
          for (let y = cellSize; y < cols + cellSize; y += cellSize) {
      
           fill(100, 255, 255);
            
            if ( x % 300 == 0) { 
              
              fill(255, 0, 0);
            } 
          
            rect(x - cellSize, y - cellSize, cellSize, cellSize);
      
          }
        }
      }            
                        
Grid Variation 1
x is between 5 and 200.
Y is between 5 and 200.
Grid Variation 2
x is bigger than 500.
Y is bigger than 0.
Grid Variation 3
X is between 100 and 300.
Y is bigger than 0.
Grid Variation 4
X is between 100 and 800.
Y is between 300 and 500.
Grid Variation 4
X is bigger than Y % (cellSize*20)
Grid Variation 4
X is bigger than Y % (cellSize*5)

Transformations in motion

A transformation with creative coding has also the capability to move. For instance, a transformation of 2 moving bodies that listen to each other and change their movement direction accordingly. The body “A” loops from left to right inside its container, and body “B” loops from top to bottom inside its container. If one body reaches the maximum value within its given container, the other body will start moving, creating a repetition. This example uses the most basic form of motion with p5.js, adding a value of 1 to a variable every frame, and incrementing the total value of the variable continuously.

 
    
            var posX;
            var posY;
            var speedX;
            var speedY;
            
            //change the object size, which affects its behaviour
            var diameter = 40;
            
            // change the width ratio aspect
            var factor = 0.5;
            
            //change the speed of either moving object
            var globalSpeedX = 5;
            var globalSpeedY = 5;
            
            var valHeight;
            var valWidth;
            
            function setup() {
              createCanvas(600, 600);
            
              posX = 0;
              posY = diameter;
              speedX = globalSpeedX;
              speedY = 0;
            
              valHeight = height;
              valWidth = width;
            }
            
            function draw() {
              background(255);
              fill(0);
            
              var factormapped = map(factor, 0.0, 1.0, 1.0, 0.0);
            
              stroke(255);
              strokeWeight(2);
            
              rect(0, 0, valWidth * factor, valHeight, 20);
              rect(valWidth * factor, 0, valWidth * factormapped, valHeight, 20);
            
              noStroke();
              fill(255);
              textSize(diameter);
              text("A", posX, valHeight / 2);
              text("B", valWidth - (valWidth * factormapped) / 2, posY);
            
              posX += speedX;
              posY += speedY;
            
              if (posX >= valWidth * factor - diameter) {
                speedX = 0;
                speedY = globalSpeedY;
              }
            
              if (
                posY >= valHeight - diameter / 4 &&
                posX >= valWidth * factor - diameter
              ) {
                speedY = 0;
                speedX = -globalSpeedX;
              }
            
              if (posX < diameter / 2 && posY >= valHeight - diameter) {
                speedX = 0;
                speedY = -globalSpeedY;
              }
            
              if (posX < diameter / 2 && posY < diameter) {
                speedY = 0;
                speedX = globalSpeedX;
              }
            }            
                      
Open the sketch in the p5 editor ↗

NEXT:

Learn parameters

Applied structures

Use the tools↗

Watch use cases