Assignment 3: Generative Art using OOPS, Functions & Arrray’s

Concept: My generative art created using P5.js presents a captivating display of colorful circles arranged in a dynamic pattern using OOPS, Arrays and Functions. I have integrated few interactive functions to make it more interesting. Inspired by the interplay of randomness and user interaction as discussed in class, this artwork embodies the concept of controlled chaos.

Main Inspiration:

At initial phase: At first, I had the idea to create artwork like the one in the video, but instead of using curves, I wanted to use circles. Each circle in my artwork has its own size, color gradient, and movement, which all come together to make the overall picture interesting. I added an interactive feature so people can join in and make the artwork themselves by clicking the mouse to add new circles. This makes the artwork more dynamic and engaging. The colors of the circles change gradually based on their position on the screen, which gives the artwork depth and liveliness. Additionally, each circle rotates at its own speed, adding a sense of flow and motion. Overall, my artwork demonstrates how randomness can be controlled to create harmony, inviting viewers to appreciate the beauty of unpredictability.

[Initial Output] This is how it looks! Try tapping anywhere in canvas to create more fun circles.. 

Initial Art Code:

let circles = [];

function setup() {
  createCanvas(600, 600);
  
  // Create an initial set of circles
  for (let i = 0; i < 50; i++) {
    let circle = new Circle(random(width), random(height), random(10, 50));
    circles.push(circle);
  }
}

function draw() {
  background(255);

  // Update and display each circle
  for (let circle of circles) {
    circle.update();
    circle.display();
  }
}

function mousePressed() {
  // Add a new circle at the mouse position when clicked
  let newCircle = new Circle(mouseX, mouseY, random(10, 50));
  circles.push(newCircle);
}

// Circle class definition
class Circle {
  constructor(x, y, diameter) {
    this.x = x;
    this.y = y;
    this.diameter = diameter;
    this.color1 = color(random(255), random(255), random(255));
    this.color2 = color(random(255), random(255), random(255));
    this.speedX = random(-2, 2);
    this.speedY = random(-2, 2);
    this.rotation = random(TWO_PI); // Random initial rotation
    this.rotationSpeed = random(-0.05, 0.05); // Random rotation speed
  }

  update() {
    // Move the circle
    this.x += this.speedX;
    this.y += this.speedY;

    // Bounce off the walls
    if (this.x > width || this.x < 0) {
      this.speedX *= -1;
    }
    if (this.y > height || this.y < 0) {
      this.speedY *= -1;
    }

    // Update rotation
    this.rotation += this.rotationSpeed;
  }

  display() {
    // Draw the circle with color gradient and rotation
    let gradientColor = lerpColor(this.color1, this.color2, map(this.y, 0, height, 0, 1));
    fill(gradientColor);
    noStroke();
    push();
    translate(this.x, this.y);
    rotate(this.rotation);
    ellipse(0, 0, this.diameter, this.diameter);
    pop();
  }
}

I felt that my artwork needed some additional features to make it more engaging, so I decided to incorporate three new elements:

1. Interactive Drawing: Now, users can click and drag their mouse to draw colorful circles directly onto the canvas. This adds an interactive dimension to the artwork, allowing people to actively participate in its creation.

2.Dynamic Color Palette: To enhance visual appeal, I introduced a dynamic color palette. Each circle is filled with colors randomly selected from a predefined palette, adding variety and vibrancy to the overall composition.

3.Transparency Effect: To create a sense of depth and visual interest, I implemented a transparency effect. The transparency of each circle varies based on its diameter, resulting in a captivating depth effect as circles overlap on the canvas.

Final Output (Tap and drag the mouse anywhere in the canvas)

This is how it looks if the user added more circles:

Final Code:

let circles = [];
let colorPalette = ['#FFC857', '#F4A35F', '#EE6C4D', '#F95738', '#FF5733', '#FF355E', '#D40C6B', '#7A00FF', '#0045FF', '#0088FF']; //Creating an array filled with color palettes. 

function setup() {
  createCanvas(800, 600);
  
  // Creating an initial set of circles
  for (let i = 0; i < 100; i++) {
    let x = random(width);
    let y = random(height);
    let diameter = random(10, 50);
    let colorIndex = floor(random(colorPalette.length));
    let circle = new Circle(x, y, diameter, colorPalette[colorIndex]);
    circles.push(circle);
  }
  
  // Adding interactive features (just need to tap and drag)
  background(0);
  textAlign(CENTER, CENTER);
  textSize(36);
  fill(255);
  text("Click and drag to draw!", width / 2, height / 2);
}

function draw() {
  // Updating and displaying each circle
  for (let circle of circles) {
    circle.update();
    circle.display();
  }
}

function mouseDragged() {
  // Add a new circle at the mouse position when dragged
  let diameter = random(10, 50);
  let colorIndex = floor(random(colorPalette.length));
  let circle = new Circle(mouseX, mouseY, diameter, colorPalette[colorIndex]);
  circles.push(circle);
}

// Defining Circle class 
class Circle {
  constructor(x, y, diameter, color) {
    this.x = x;
    this.y = y;
    this.diameter = diameter;
    this.color = color;
    this.speedX = random(-2, 2);
    this.speedY = random(-2, 2);
    this.rotation = random(TWO_PI); // Random initial rotation
    this.rotationSpeed = random(-0.05, 0.05); // Random rotation speed
  }

  update() {
    // Moving the circle
    this.x += this.speedX;
    this.y += this.speedY;

    // Bouncing off the walls
    if (this.x > width || this.x < 0) {
      this.speedX *= -1;
    }
    if (this.y > height || this.y < 0) {
      this.speedY *= -1;
    }

    // Updating rotaion
    this.rotation += this.rotationSpeed;
  }

  display() {
    // Drawing the circle with rotation and transparency effect
    push();
    translate(this.x, this.y);
    rotate(this.rotation);
    fill(this.color);
    noStroke();
    let alpha = map(this.diameter, 10, 50, 50, 200); 
    // Varrying transparency based on diameter
    fill(red(this.color), green(this.color), blue(this.color), alpha);
    ellipse(0, 0, this.diameter, this.diameter);
    pop();
  }
}

Code I’m proud of: Initially, I found implementing the transparency effect challenging in my artwork. Understanding how to vary the transparency based on the diameter of each circle was tricky. However, I managed to overcome this difficulty by experimenting with the map() function in the display() method of the Circle class. By mapping the diameter of each circle to a range of transparency values, I was able to achieve the desired effect. This involved adjusting the parameters of the map() function until I achieved the desired transparency levels, ultimately resulting in a visually appealing depth effect as circles overlapped on the canvas. Overall, successfully implementing this feature added an extra dimension to my artwork that I’m proud of.

Additional Art Work: With Valentine’s Day approaching, I decided to enhance my artwork by making some adjustments to the code. Here’s the updated look!

Here’s the code for the Valentine’s Day themed artwork:

let hearts = [];
let colorPalette = ['#FF4D6D', '#FF6381', '#FF7992', '#FF8BA3', '#FFA3B5', '#FFBFC7', '#FFD1D9', '#FFEDF2'];

function setup() {
  createCanvas(800, 600);
  
  // Addinng a sweet message
  background(255);
  textAlign(CENTER, CENTER);
  textSize(36);
  fill(150);
  text("Happy Valentine's Day!", width / 2, height / 2 - 50);
  text("Click and drag to create love!", width / 2, height / 2 + 50);
}

function draw() {
  // Updating and displaying each heart
  for (let heart of hearts) {
    heart.update();
    heart.display();
  }
}

function mouseDragged() {
  // Adding a new heart at the mouse position when dragged
  let size = random(30, 100);
  let colorIndex = floor(random(colorPalette.length));
  let heart = new Heart(mouseX, mouseY, size, colorPalette[colorIndex]);
  hearts.push(heart);
}

// Heart class definition
class Heart {
  constructor(x, y, size, color) {
    this.x = x;
    this.y = y;
    this.size = size;
    this.color = color;
    this.speedX = random(-2, 2);
    this.speedY = random(-2, 2);
    this.rotation = random(TWO_PI); // Random initial rotation
    this.rotationSpeed = random(-0.05, 0.05); // Random rotation speed
  }

  update() {
    // Moving the heart
    this.x += this.speedX;
    this.y += this.speedY;

    // Bounce off the walls
    if (this.x > width || this.x < 0) {
      this.speedX *= -1;
    }
    if (this.y > height || this.y < 0) {
      this.speedY *= -1;
    }

    // Update rotation
    this.rotation += this.rotationSpeed;
  }

  display() {
    // Drawing the heart with rotation and transparency effect
    push();
    translate(this.x, this.y);
    rotate(this.rotation);
    fill(this.color);
    noStroke();
    let alpha = map(this.size, 30, 100, 50, 200); // Vary transparency based on size
    fill(red(this.color), green(this.color), blue(this.color), alpha);
    beginShape();
    vertex(0, -this.size / 2);
    bezierVertex(this.size / 2, -this.size / 2, this.size, 0, 0, this.size);
    bezierVertex(-this.size, 0, -this.size / 2, -this.size / 2, 0, -this.size / 2);
    endShape(CLOSE);
    pop();
  }
}

Conclusion:  In conclusion, my inspired Bouncing Circles Art and Valentine’s Day-artwork successfully integrates the principles of generative art, interactive elements, and dynamic features using circles. The addition of an interactive drawing feature, a dynamic color palette, and a transparency effect enhances the overall aesthetic appeal, allowing users to engage with the artwork in a meaningful way. To speak more about the Valentines artwork,  the fusion of vibrant colors and interactive drawing adds a festive touch, making it suitable for the Valentine’s Day theme.

While I am pleased with the outcome, there are areas for potential improvement. One aspect to consider is enhancing user interaction further by introducing additional interactive features or refining existing ones to make the artwork even more engaging. Additionally, exploring different color palettes and experimenting with more complex patterns could elevate the visual impact of the artwork. Overall, this project has provided valuable insights and opportunities for growth, and I look forward to continuing to refine my skills and expand my creative horizons in future projects.

Leave a Reply