Week 2- Generative Artwork- Visual Art themed

overview

This generative artwork, inspired by Wassily Kandinsky’s “Circles in Circles,” showcases a vibrant and dynamic composition. The canvas size is set to 600×600 pixels with a beige background and a black-bordered transparent circle at the center. Colorful animated circles, each with random positions, sizes, colors, and movement patterns, create an ever-changing visual experience. Additionally, eight animated lines move horizontally, resetting when they go off-screen. The viewer can interact with the artwork by clicking on different areas, and changing the background color dynamically. This code combines randomness and structure to produce a captivating, abstract artwork reminiscent of Kandinsky’s geometric abstractions.

Who is Wassily Kandinsky?

Wassily Kandinsky (1866-1944) was a pioneering Russian painter and art theorist, often hailed as one of the founders of abstract art. He believed that art should evoke emotions and spiritual experiences through non-representational forms and colors. Kandinsky’s “Circles in Circles” is a seminal artwork created in 1923, during his Bauhaus period. It is a prime example of his abstract style, featuring geometric shapes and vibrant colors. In this work, a large red circle dominates the canvas, encompassing smaller circles in various hues, with each circle seemingly floating or orbiting within the composition. “Circles in Circles” embodies Kandinsky’s fascination with the spiritual and emotional power of abstract forms and color harmonies.

Figure 1: “Circles in Circles” by Wassily Kandinsky (1923)

 

 

 

 

 

 

 

Code Details; Highlights of the code that I am particularly proud of 

  • To precisely replicate the colors found within the painting, I first extracted its color palette. Subsequently, I meticulously identified and stored the exact hexadecimal color codes in an array. These hex codes were then used to randomly assign colors to the circles in my artwork, ensuring an accurate representation of the original painting’s color scheme
  • // Array of hex colors for the circles
    let circleColors = ["#c7999b", "#b8bbaf", "#8e4040", "#82a596", "#e4c95b", "#585e3a", "#364664", "#694350", "#282927"];
  • The original painting featured precisely 21 circles, and through the utilization of loops, I successfully replicated this exact count within my artwork. and just like the original painting the circles had random stroke weight and the circles have a certain sense of transperacy just as the original painting
  • for (let i = 0; i < 21; i++) {
        let x = random(width); // Random x-coordinate within canvas width
        let y = random(height); // Random y-coordinate within canvas height
        let radius = random(10, 80); // Random radius between 10 and 80 pixels
    
        // Randomly select a color from the circleColors array
        let fillColor = color(random(circleColors));
        
        // Generate a random stroke weight for the circle (border thickness)
        let strokeWeightValue = random(1, 5);
        
        let xspeed = random(-2, 2); // Random horizontal speed
        let yspeed = random(-2, 2); // Random vertical speed

    embedded sketch


problems I ran into:

While the code initially employed a reversal of direction (multiplying by -1) when circles encountered the canvas edges, it became apparent that certain circles exhibited shaky behavior. To mitigate this issue, a damping effect was introduced. Initially, there were reservations about this approach, as it seemed to halt the circles’ motion. However, upon further consideration, it was realized that the damping effect, while tempering the motion, also contributed to a smoother and less overwhelming overall movement.

After applying the damping effect 

code (commented with the use of loops and classes as requested) :

// Batool AL Tameemi, Intro to IM Week 3 homework
// Generative art work

let circles = [];
let backgroundColors = [];
let lines = [];

function setup() {
  createCanvas(600, 600); // Create a canvas with a size of 600x600 pixels
  noStroke(); // Disable stroke (borders) for shapes
  frameRate(60); // Set the frame rate to 30 frames per second

  // Add the RGB values of the colors from the painting to the backgroundColors array
  backgroundColors.push(color(226, 216, 203)); // Light beige
  backgroundColors.push(color(146, 125, 75)); // Dark beige
  backgroundColors.push(color(130, 165, 150)); // Greenish gray
  // Add more background colors as needed

  // Array of hex colors for the circles
  let circleColors = ["#c7999b", "#b8bbaf", "#8e4040", "#82a596", "#e4c95b", "#585e3a", "#364664", "#694350", "#282927"];

  for (let i = 0; i < 21; i++) {
    let x = random(width); // Random x-coordinate within canvas width
    let y = random(height); // Random y-coordinate within canvas height
    let radius = random(10, 80); // Random radius between 10 and 80 pixels

    // Randomly select a color from the circleColors array
    let fillColor = color(random(circleColors));
    
    // Generate a random stroke weight for the circle (border thickness)
    let strokeWeightValue = random(1, 5);
    
    let xspeed = random(-2, 2); // Random horizontal speed
    let yspeed = random(-2, 2); // Random vertical speed
    
    // Create an instance of AnimatedCircle and add it to the circles array
    circles.push(new AnimatedCircle(x, y, radius, fillColor, strokeWeightValue, xspeed, yspeed));
  }

  // Create animated lines
  for (let i = 0; i < 8; i++) {
    let x1 = random(width); // Random x-coordinate for the starting point of the line
    let y1 = random(height); // Random y-coordinate for the starting point of the line
    let x2 = random(width); // Random x-coordinate for the ending point of the line
    let y2 = random(height); // Random y-coordinate for the ending point of the line
    let lineColor = color(0, 0, 0); // Black color for lines
    let lineWeight = random(1, 5); // Random stroke weight for lines

    // Create an instance of AnimatedLine and add it to the lines array
    lines.push(new AnimatedLine(x1, y1, x2, y2, lineColor, lineWeight));
  }
}

function draw() {
  for (let i = 0; i < backgroundColors.length; i++) {
    fill(backgroundColors[i]); // Fill the background with one of the background colors
    noStroke();
    rect(0, i * (height / backgroundColors.length), width, height / backgroundColors.length);
    // Draw a colored rectangle for each background color
  }

  for (let circle of circles) {
    circle.move(); // Move each animated circle
    circle.display(); // Display each animated circle
  }

  for (let line of lines) {
    line.move(); // Move each animated line
    line.display(); // Display each animated line
  }
  
  // Draw a single black-bordered transparent circle inside
  strokeWeight(8); // Set the stroke weight (border thickness) for the ellipse
  stroke(0); // Set the stroke color to black
  noFill(); // Don't fill the ellipse with color
  ellipse(width / 2, height / 2, 400, 400); // Draw the ellipse at the center of the canvas
}

function mousePressed() {
  // Calculate the index of the background color based on the mouse click position
  let index = int(mouseY / (height / backgroundColors.length));
  fill(backgroundColors[index]); // Fill with the selected background color
  rect(0, index * (height / backgroundColors.length), width, height / backgroundColors.length);
  // Draw a colored rectangle based on the mouse click position
}

// AnimatedCircle class definition
class AnimatedCircle {
  constructor(x, y, radius, fillColor, strokeWeightValue, xspeed, yspeed) {
    this.x = x;
    this.y = y;
    this.radius = radius;
    this.fillColor = fillColor;
    this.strokeWeightValue = strokeWeightValue; // Store stroke weight
    this.xspeed = xspeed;
    this.yspeed = yspeed;
    this.fillColor = color(red(fillColor), green(fillColor), blue(fillColor), 200); // Set the alpha value to 150 for transparency
  }

move() {
    // Define a damping factor (adjust as needed)
    let damping = 0.95;

    // Update the x-coordinate based on speed
    this.x += this.xspeed;
    
    // Apply damping to reduce shaking near the edges
    this.xspeed *= damping;

    // Update the y-coordinate based on speed
    this.y += this.yspeed;

    // Apply damping to reduce shaking near the edges
    this.yspeed *= damping;

    if (this.x > width - this.radius || this.x < this.radius) {
        this.xspeed *= -1; // Reverse horizontal speed if the circle hits canvas edge
    }

    if (this.y > height - this.radius || this.y < this.radius) {
        this.yspeed *= -1; // Reverse vertical speed if the circle hits canvas edge
    }
}

  display() {
    strokeWeight(this.strokeWeightValue); // Set the stroke weight
    stroke(0); // Set the stroke color to black
    fill(this.fillColor); // Fill with the specified color
    ellipse(this.x, this.y, this.radius * 2, this.radius * 2); // Draw the circle
  }
}

// AnimatedLine class definition
class AnimatedLine {
  constructor(x1, y1, x2, y2, lineColor, lineWeight) {
    this.x1 = x1;
    this.y1 = y1;
    this.x2 = x2;
    this.y2 = y2;
    this.lineColor = lineColor;
    this.lineWeight = lineWeight;
    this.speed = random(0.5, 2); // Random line animation speed

  }

  move() {
    // Move the lines horizontally
    this.x1 += this.speed;
    this.x2 += this.speed;

    // Reset lines when they go off-screen
    if (this.x1 > width) {
      this.x1 = 0;
      this.x2 = random(width);
      this.y1 = random(height);
      this.y2 = random(height);
    }
  }

  display() {
    strokeWeight(this.lineWeight); // Set the stroke weight
    stroke(this.lineColor); // Set the stroke color
    line(this.x1, this.y1, this.x2, this.y2); // Draw the line
}

}

 

 

 

Homework 2- Animated self portrait – catch up

Hi everyone, my name is Batool Al tameemi, I joined this class on Sunday so I am trying to catch up the work

Overview:

This dynamic self-portrait, crafted using the expressive capabilities of p5.js, offers an intriguing blend of artistic finesse and interactive elements. It breathes life into the digital canvas with a symphony of visual animations and engaging features.

Enchanting Cloud Animation: The canvas adorns itself with ethereal clouds that gracefully drift across the sky, bestowing an atmospheric and immersive aura upon the portrait. These celestial wanderers move with a fluid elegance, enhancing the overall visual allure.

Meticulous Facial Representation: The self-portrait meticulously captures the quintessence of a visage, with a particular focus on its defining characteristics – the eyes, nose, lips, and cheeks. These features are intricately designed, resulting in a lifelike and evocative portrayal.

Dynamic Blinking Eyes: This project introduces a captivating blink animation for the eyes, infusing the portrait with an element of realism and endearing quirkiness. The eyes gracefully transition between open and closed states, establishing a captivating connection with the observer.

 

Embedded sketch

A Highlight of a code I am proud of:

One of the code segments that truly stands out in this self-portrait project is the implementation of interactive eye movement. This feature elevates the portrait’s interactivity and brings it to life in a captivating manner.

Within the code, the calculation of the new positions for the pupils based on the mouse cursor’s movement is a testament to both creativity and technical finesse. The snippet carefully calculates the angle between the mouse cursor’s position and the position of each eye. It then determines the new coordinates for the pupils, resulting in the illusion of the eyes tracking the viewer’s actions.

  // Calculate the angle between the mouse and each eye
  let leftEyeAngle = atan2(mouseY - leftPupilY, mouseX - leftPupilX);
  let rightEyeAngle = atan2(mouseY - rightPupilY, mouseX - rightPupilX);

  // Calculate the new positions for the pupils based on the angle
  let pupilRadius = 15; // Adjust the pupil size as needed
  leftPupilX = 170 + cos(leftEyeAngle) * pupilRadius;
  leftPupilY = 175 + sin(leftEyeAngle) * pupilRadius;
  rightPupilX = 230 + cos(rightEyeAngle) * pupilRadius;
  rightPupilY = 175 + sin(rightEyeAngle) * pupilRadius;

  fill(139, 69, 19);
  ellipse(leftPupilX, leftPupilY, 20, 20);
  ellipse(rightPupilX, rightPupilY, 20, 20);
}

Reflection:

Creating this self-portrait project in p5.js was an exciting journey that allowed for a fusion of artistic expression and interactive coding.

Future Improvements:

  1. Enhanced Realism: To push the boundaries of realism further, I plan to explore the incorporation of even more intricate facial details. Elements such as eyelashes, wrinkles, or variations in skin texture can elevate authenticity and immerse the viewer deeper into the self-portrait.
  2. Background Storytelling: To enrich the viewer’s experience, I intend to delve into the addition of a meaningful background or narrative context. Crafting a compelling backdrop can provide insights into the subject’s personality, convey specific moods, or tell a captivating story.
  3. Gesture and Pose: I look forward to experimenting with different facial expressions, poses, or gestures in future self-portrait projects. This exploration will enable me to convey various emotions or themes through the artwork, adding diversity to my portfolio.

Code:

//Batool Al Tameemi , Intro to IM 
//Homework 1 
function setup() {
  createCanvas(400, 400); // Creates a canvas with a size of 400x400 pixels
  background(0, 0, 250); // Sets the background color to blue
}

function draw() {
  let centerX = width / 2; // Calculate the x-coordinate of the center of the canvas
  let centerY = height / 2; // Calculate the y-coordinate of the center of the canvas

  let skinColor = color(255, 204, 153); // Define a custom skin color using RGB values

  // Draw the face background
  fill(87); // Set the fill color to a shade of gray
  noStroke(); // Disable outline (stroke)
  ellipse(200, 420, 250, 200); // Draw an ellipse as the face's background
  fill(0); // Set the fill color to black
  noStroke(); // Disable outline (stroke)
  ellipse(centerX, centerY, 230, 250); // Draw an ellipse as the face
  rect(225, 200, 90, 230); // Draw a rectangular shape as the neck
  ellipse(200, 330, 90, 50); // Draw an ellipse as the mouth area
  fill(skinColor); // Set the fill color to the custom skin color
  ellipse(centerX, centerY, 170, 200); // Draw an ellipse as the skin
  
  fill(0, 0, 0, 100); // Translucent black
  stroke(255);
  ellipse(170, 100, 50, 40); 
  ellipse(230, 100, 50, 40);
  line(195, 100, 205, 100);

  // Draw eye whites
  fill(255); // Set the fill color to white
  noStroke(); // Disable outline (stroke)
  ellipse(170, 175, 40, 30); // Draw the left eye white
  ellipse(230, 175, 40, 30); // Draw the right eye white

  // Draw eye pupils
  fill(139, 69, 19); // Set the fill color to brown
  ellipse(170, 176, 20, 20); // Draw the left eye pupil
  ellipse(230, 176, 20, 20); // Draw the right eye pupil

  // Draw the cheeks
  fill(255, 182, 193); // Set the fill color to pink
  ellipse(144, 240, 40, 40); // Draw the left cheek
  ellipse(256, 240, 40, 40); // Draw the right cheek

  // Draw the nose
  fill('#C4A484'); // Set the fill color to a light brown
  ellipse(200, 210, 20, 30); // Draw the nose

  // Draw light eyebrows
  fill(0); // Set the fill color to black
  noStroke(); // Disable outline (stroke)
  ellipse(170, 145, 30, 8); // Draw the left eyebrow
  ellipse(230, 145, 30, 8); // Draw the right eyebrow

  // Draw the mouth
  fill(255, 0, 0); // Set the fill color to red
  arc(200, 250, 50, 50, 0, PI); // Draw a semi-circle as the mouth (smile)

  // Draw the lips
  stroke(0); // Set the stroke color to black
  strokeWeight(2); // Set the stroke weight (line thickness)
  noFill(); // Disable fill for the lips (outline only)
}

 

Homework week 1 Self Portrait- Catching up :)

Hi everyone, my name is Batool I joined this class on Sunday and this is my HW1

Overview: 

In this artistic self-portrait project crafted using p5.js, I’ve created a graphical representation of myself especially adding the sunglasses because I think they represent me so much. The canvas dimensions have been meticulously set to 450×450 pixels, with a background color reminiscent of a tranquil blue sky.

  • A highlight of some code that you’re particularly proud of
// Draw the face background
fill(87); // Set the fill color to a shade of gray
noStroke(); // Disable outline (stroke)
ellipse(200, 420, 250, 200); // Draw an ellipse as the face's background
fill(0); // Set the fill color to black
noStroke(); // Disable outline (stroke)
ellipse(centerX, centerY, 230, 250); // Draw an ellipse as the face
rect(225, 200, 90, 230); // Draw a rectangular shape as the neck
ellipse(200, 330, 90, 50); // Draw an ellipse as the mouth area
fill(skinColor); // Set the fill color to the custom skin color
ellipse(centerX, centerY, 170, 200); // Draw an ellipse as the skin

fill(0, 0, 0, 100); // Translucent black
stroke(255);
ellipse(170, 100, 50, 40); 
ellipse(230, 100, 50, 40);
line(195, 100, 205, 100);

I am proud of the sunglasses sketch While the process of drawing them was relatively straightforward, it led me into a fascinating realm of discovery and experimentation, particularly concerning the use of the translucent shade of black. It’s in these nuanced details that I discovered the power of subtle design choices, and it brought a satisfying depth to the overall composition.

Reflection and ideas for future work or improvements

Reflection:

In creating this self-portrait through the utilization of p5.js, I’ve garnered valuable insights into the realm of digital art and creative coding. The process emerged as both enlightening and fulfilling, yielding a range of noteworthy insights.

Primarily, I ascertained that the fusion of geometric configurations and judicious selection of hues can yield a visually stunning impact. The capacity to manipulate shapes and color palettes for the portrayal of intricate facial components, including the eyes, nose, lips, and cheeks, proved to be an enthralling exercise in the manifestation of creativity.

Ideas for Subsequent Undertakings or Enhancement:

While I derive satisfaction from this self-portrait endeavor, I also discern domains warranting further exploration and refinement:

  1. Texture and Elaboration: The incorporation of heightened intricacies and textures could elevate the verisimilitude of the portrait. Delving into techniques like texture brushes or introducing supplementary geometrical forms might confer enhanced captivation to the artwork.
  2. Interactivity: The infusion of interactivity into the portrait, enabling users to manipulate facial expressions or color schemes, holds promise for engendering heightened engagement. This could be realized via user-initiated input and adept event management.
  3. Background Dynamics: The realm of dynamic or animated backgrounds is ripe for exploration. By engrafting subtle movements or nuanced visual effects into the background, the viewer’s focal point could be duly engaged.
  4. Variations and Personalization: The provision of options for viewers to tailor specific facets of the portrait, such as hair color or facial attributes, would extend an invitation for greater interaction and emotional resonance.
  5. Emulating Artistic Exemplars: Imbibing the methodologies and artistic styles of other digital virtuosos can provide wellsprings of inspiration and catalysts for refinement in my own oeuvre. Learning from the rich tapestry of the creative community stands as an invaluable repository.

Code:

//Batool Al Tameemi , Intro to IM 
//Homework 1 
function setup() {
  createCanvas(400, 400); // Creates a canvas with a size of 400x400 pixels
  background(0, 0, 250); // Sets the background color to blue
}

function draw() {
  let centerX = width / 2; // Calculate the x-coordinate of the center of the canvas
  let centerY = height / 2; // Calculate the y-coordinate of the center of the canvas

  let skinColor = color(255, 204, 153); // Define a custom skin color using RGB values

  // Draw the face background
  fill(87); // Set the fill color to a shade of gray
  noStroke(); // Disable outline (stroke)
  ellipse(200, 420, 250, 200); // Draw an ellipse as the face's background
  fill(0); // Set the fill color to black
  noStroke(); // Disable outline (stroke)
  ellipse(centerX, centerY, 230, 250); // Draw an ellipse as the face
  rect(225, 200, 90, 230); // Draw a rectangular shape as the neck
  ellipse(200, 330, 90, 50); // Draw an ellipse as the mouth area
  fill(skinColor); // Set the fill color to the custom skin color
  ellipse(centerX, centerY, 170, 200); // Draw an ellipse as the skin
  
  fill(0, 0, 0, 100); // Translucent black
  stroke(255);
  ellipse(170, 100, 50, 40); 
  ellipse(230, 100, 50, 40);
  line(195, 100, 205, 100);

  // Draw eye whites
  fill(255); // Set the fill color to white
  noStroke(); // Disable outline (stroke)
  ellipse(170, 175, 40, 30); // Draw the left eye white
  ellipse(230, 175, 40, 30); // Draw the right eye white

  // Draw eye pupils
  fill(139, 69, 19); // Set the fill color to brown
  ellipse(170, 176, 20, 20); // Draw the left eye pupil
  ellipse(230, 176, 20, 20); // Draw the right eye pupil

  // Draw the cheeks
  fill(255, 182, 193); // Set the fill color to pink
  ellipse(144, 240, 40, 40); // Draw the left cheek
  ellipse(256, 240, 40, 40); // Draw the right cheek

  // Draw the nose
  fill('#C4A484'); // Set the fill color to a light brown
  ellipse(200, 210, 20, 30); // Draw the nose

  // Draw light eyebrows
  fill(0); // Set the fill color to black
  noStroke(); // Disable outline (stroke)
  ellipse(170, 145, 30, 8); // Draw the left eyebrow
  ellipse(230, 145, 30, 8); // Draw the right eyebrow

  // Draw the mouth
  fill(255, 0, 0); // Set the fill color to red
  arc(200, 250, 50, 50, 0, PI); // Draw a semi-circle as the mouth (smile)

  // Draw the lips
  stroke(0); // Set the stroke color to black
  strokeWeight(2); // Set the stroke weight (line thickness)
  noFill(); // Disable fill for the lips (outline only)
}