Assignment 1: (self) Portrait – Aneeka


(Click on screen- Audio on)

For this assignment, I initially wanted to create a self-portrait. However, I didn’t like the idea of recreating myself using basic shapes because they could never encompass some of my features. I was then thinking of a character that I would like to create a portrait of. I decided on the character Satoru Gojo from the anime Jujutsu Kaisen for two reasons: one being that I’m currently obsessed with the show, and second being that he covers his eyes usually with a blindfold which meant that I didn’t need to spend time on creating eyes.

I chose mostly simplistic features so that my code doesn’t become too complex. The portrait was inspired by this particular scene below.

I decided to animate the background as a moving gradient. The direction of the gradient switches after a while. I was inspired by this code: https://editor.p5js.org/stalgiag/sketches/webaJ2Dpe and I modified the algorithm to move the gradient downwards and change the colors (pink was to refer to the scene, blue was to refer to his bright blue eyes under the blindfold). This is the part of my code that I wanted to highlight since it added a different dynamic to my portrait.

if (startColor > height + 255 || startColor < 255) {
    speedAnimate *= -1; } //reversing direction if goes beyond screen
  startColor += speedAnimate;
  let numRectangles = 21;
  let rectHeight = height / numRectangles;
  for (let y = 0; y < height; y += rectHeight) {
    let pinkShade = startColor - y; //calculates  pink shade based on the distance from the top of the canvas.
    let red = 255-pinkShade; // Adjust red color to create gradient
    fill(red, 191, 210); 
    rect(0, y, width*2, rectHeight);
  }

I also wanted to add an interactive feature. When one clicks on the portrait, it plays the character’s signature laugh. I used this tutorial to add the audio: https://www.youtube.com/watch?v=MDX5VaMOzZg

Overall, I am happy with the result and how some features such as the hair turned out. If I had to improve on this particular portrait, I would try to add shading and more details. I would also add an alternate version of him without the blindfold. Furthermore, I want to experiment more with animation and audio in future assignments.

Week 1 Assignment: Self-Portrait

While I had some experience with Processing through Intro to CS, I was new to JavaScript and especially p5, so this assignment took longer than I expected. My goal was to make the portrait as detailed and true to life as possible with just basic shapes on p5.js, while at the same time not drowning in code. My final result is a compromise between these two parameters.

For my portrait, I first took a few pictures of myself as a reference. I began by basing the basic proportions of the shapes based on the proportions of different parts of my face.

I knew that a simple ellipse would not be enough to represent my face, so I decided to combine a rectangle with multiple arcs to get the “rounded square” shape of my face. A few more arcs (yes, this is a recurring theme throughout this assignment) were used to round out the jaw and the chin and then I was done with the first part.

I then decided to work on the neck and the shirt, as that would be easy to get out of the way. They just required a rectangle and a quadrilateral respectively, and I used more arcs to round out the shoulders and collar to avoid a blocky look.

Next, I worked on the eyes which, which was probably the most time-consuming step. Inspired by examples on the Intro to IM website, I decided to challenge myself by making some Bezier curves. This tutorial was very helpful in understanding how they work. Yet, it was time-consuming to make a decent shape out of them, especially as they are not as intuitive as they would be on graphics editing software such as Adobe Illustrator (and according to me, they’re not very intuitive even there). I settled for combining an arc for the upper portion of the eye, and a Bezier curve for the lower portion, which I feel gives the desired result. While learning to use Bezier curves took more time than I would have wanted, it was valuable for other steps in this assignment and in future ones.

function drawDayEyes(){
  //cornea
  strokeWeight(2);
  stroke(hairColor);
  fill(corneaColor);
  //right
  arc(4.13*width/10, 4.28*height/10, 0.8*width/10,
0.55*height/10, PI+0.1, -0.1, OPEN);
  bezier(3.73*width/10,4.23*height/10,4*width/10,
4.5*height/10, 4.25*width/10, 4.45*height/10,
4.5*width/10, 4.23*height/10);
  //left
  arc(5.87*width/10, 4.28*height/10, 0.8*width/10,
0.55*height/10, PI+0.1, -0.1, OPEN);
  bezier(5.47*width/10, 4.23*height/10, 5.77*width/10,
4.45*height/10, 6.07*width/10, 4.5*height/10, 
6.27*width/10, 4.23*height/10);
  //irises
  noStroke();
  fill(irisColor);
  ellipse(4.13*width/10, 4.2*height/10, 0.34*width/10);
  ellipse(5.87*width/10, 4.2*height/10, 0.34*width/10);
  //pupils
  fill("black");
  ellipse(4.13*width/10, 4.2*height/10, 0.18*width/10);
  ellipse(5.87*width/10, 4.2*height/10, 0.18*width/10);
}

After the eyes came the obvious next step, my glasses. The basic frame was not too hard to make, but required a bit of trial and error to get a decent-looking shape. Within the glasses, I decided to include the optical lensing that occurs due to the high negative power of my lens, which makes it appear as if my face is shrunken inward when viewed face-to-face. This also helped me correct for making my eyes inadvertently small as I had forgotten that the reference also had the optical lensing effect.

Next were the lips and the nose. I was afraid of using Bezier curves for a shape as complex as lips but decided that I didn’t need them anyway. I simulated the shape of the lips using arcs and triangles, which seemed suitable enough. The nose too was similarly done, with the nostrils being made of simple ellipses, the apex being made of a moderately thick arc, and the dorsum (the front part of the nose) being made of thinner arcs. I still used Bezier curves to get the iconic shifted curved look of the nasal alae (the “wings” of the nose around each nostril).

This is when I decided to add hair to my portrait. The head hair was just a bunch of triangles, ellipses, and arcs overlapping to get the hair’s fringes. The eyebrows were also arcs drawn using a thick stroke weight. I wanted to include eyelashes, but they were annoying to implement, so I skipped them.

Next were the ears, which were also daunting. I knew that this required a complex Bezier curve shape. I experimented with the beginShape() and bezierVertex() functions to get the complex shape needed for the ears. This too required a lot of trial and error to get the shapes and sizes right.

  //right ear
  beginShape();
  vertex(2.85*width/10, 3.8*height/10);
  bezierVertex(2.5*width/10, 3.6*height/10, 2.4*width/10, 4.025*height/10, 2.55*width/10, 4.55*height/10);
  bezierVertex(2.625*width/10, 4.65*height/10, 2.4*width/10, 5.05*height/10, 2.8*width/10, 5*height/10)
  endShape();
  //left ear
  beginShape();
  vertex(7.15*width/10, 3.8*height/10);
  bezierVertex(7.5*width/10, 3.6*height/10, 7.6*width/10, 4.025*height/10, 7.45*width/10, 4.55*height/10);
  bezierVertex(7.375*width/10, 4.65*height/10, 7.6*width/10, 5.05*height/10, 7.2*width/10, 5*height/10)
  endShape();

At the very end, I decided to include some rudimentary interactivity by making a lamp that could be clicked on to cycle between “wake” and “sleep”. If-else statements dictate which elements to draw or not, and I quickly made a pair of “closed eyes” which are essentially just a pair of arcs.

Here is what my final self-portrait looked like:

Overall, I am really happy with the result. It did take a long while and quite a bit of effort, but I feel it was worth it to help set a strong foundation in p5.js while also making a decent self-portrait.

 

Assignment 1 – Self Portrait (Haziel)

For this assignment, I decided to create a simple 2D portrait using primitive shapes and a few of my favorite colors. The concept and objective was to represent key characteristics of my appearance, which became quite challenging as I don’t have much experience with p5. So, I drew my current black hair (Emphasizing this because I used to change my hair color really often :D) and a Brazilian t-shirt. Additionally, I used green for the background, since it’s my favorite color and the tone also gave a good contrast with my drawing.

In portrait itself, I used basic geometric shapes. Ellipse to create the face and eyes; Arc for the hair, mouth, eyebrows, and the t-shirt; and triangle for the nose.

When it comes to the reflection, I believe there are some areas where I could improve to enhance the representation of my identity in the portrait. One key aspect would be to add more details, such as incorporating more complex shapes or finer lines to capture the nuances of my appearance. For example, my curly hair could be depicted with a more diverse range of shapes and textures.

Looking ahead, I’m excited to learn more advanced skills and techniques using p5. Exploring new methods for digital art and honing my abilities with the software will enable me to create more dynamic and expressive projects in the future. So, I’m really looking forward to experimenting with different styles and approaches to further develop my artistic side.

Here’s my code:

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

function draw() {
  background('#59A65C');
  
  // Face
  fill(255, 204, 153);
  ellipse(200, 200, 200, 250);
  
  // Hair 
  fill(0);
  arc(200, 140, 180, 130, PI, TWO_PI);
  
  // Eyes
  fill(0);
  ellipse(160, 180, 30, 30);
  ellipse(240, 180, 30, 30);
  
  // Eyebrows
  noFill();
  strokeWeight(3);
  arc(160, 170, 40, 10, PI, TWO_PI);
  arc(240, 170, 40, 10, PI, TWO_PI);
  
  // Mouth
  fill(255);
  strokeWeight(1);
  arc(200, 220, 50, 50, 0, PI);
  
  // Nose
  fill(255, 204, 153);
  triangle(200, 200, 190, 230, 210, 230);
  
  // Brazilian T-shirt
  fill('yellow');
  arc(200, 380, 200, 160, 0, PI);
  fill('green');
  arc(200, 380, 200, 160, PI, TWO_PI);
}

☆Alexandra’s Self Portrait☆

For this assignment, since I am (very!) new to coding, I decided to take it easy and to simply explore the options available on p5 in order to create my self-portrait. I therefore opted for something rather realistic than creative so I could focus on the code itself.

However, I couldn’t help but go further and add some extra things that would make this portrait more like me. The main thing I added are the three stars in the background. My last name, “Najm”, means star in Arabic. Therefore, the star has become a very symbolic element in my life. Even as an artist, my signature is an eye with a star as a pupil. So, the star means a lot to me in my personal life, extending into my art.

 // star!
fill(255, 217, 102);
stroke(0, 10, 134);
strokeWeight(3);
beginShape();
vertex(470, 430);
vertex(500, 430);
vertex(510, 400);
vertex(520, 430);
vertex(550, 430);
vertex(530, 450);
vertex(540, 480);
vertex(510, 460);
vertex(480, 480);
vertex(490, 450);
vertex(470, 430);
endShape();

Above is my code for one of the stars. I particularly enjoyed coding this part as I had to figure out how to use the beginShape() function, and I found it fun. I then copied the code and simply changed the coordinates in order to play around with size and position. I would eventually like to learn how to animate them, although as of now I still can’t grasp the whole variable animation thing.

Here is what my self-portrait looked like in the end:

There are two things to note, which I would like to improve for next time:

  1. In the code itself, I repeat the fill() and stroke() functions unnecessarily. I understand that these functions will apply to the following ones until I want to create a new shape or element with different characteristics. However, I just found it easier for today to add the same color multiple times in a row. It did clutter my code a bit though.
  2. I really couldn’t figure out how the arguments for the curve function work. The anchor points made sense but the control points didn’t. I ended up just playing around with those (for the eyebrows, eyelashes, and necklace) until they looked satisfying; trial and error basically. I wanted to also do the front pieces of my hair with the curves but I couldn’t get it right for the life of me.

Assignment 1 – Self Portrait – Bubbling Portrait

I just tried to paly around with p5.js after the class. My first lesson about this was “Auto-refresh” does not mean “Auto-save”. I learnt this the hard way. After turning the Auto-refresh on, I proceed to finish my code without the thought the save it. However, after an incident with losing the internet connections, my work was lost after the page was refreshed and I had to rewrite the code from scratch. Learning from mistakes, I saved my code after every changes and turned of “Auto-refresh”.

I sketch the portrait mostly by ellipse and arc. I started from the head which then includes eyes, nose, mouth, and hair. The eyes include a few different ellipses for the eyeballs. Nose and mouth are much simpler, just a single arc for each is sufficient.

However, the most difficult part for me was the hair. To make the front part, I used the arc to produce a half circle. Furthermore, I want to have highlights on the hair. I used the arc function with changes in stroke colors to mimic the hair strands. The most difficult thing in this step is to know the exact starting point and ending point of the arc. Below is the codes for it:

noFill();
stroke("white");
arc(width / 2 + 20, height / 2 - 15, 150, 120, PI, PI + HALF_PI - QUARTER_PI);
arc(width / 2 + 20, height / 2 - 15, 100, 120, PI, PI + HALF_PI - QUARTER_PI);
arc(
  width / 2 - 10,
  height / 2 - 15,
  150,
  120,
  PI + HALF_PI + QUARTER_PI,
  TWO_PI
);
arc(
  width / 2 - 20,
  height / 2 - 15,
  100,
  120,
  PI + HALF_PI + QUARTER_PI,
  TWO_PI
);

I then added a pony tail using the Bezier curve. The final steps were adding ears and body using simple ellipse codes.

Finally, I attempt to do animation in p5.js. Using circles, I assign random position for each circle after every reloading. Each circle will start with a random size. They will increase and decrease in size as time pass. This was done using the sin() function:

circle(10, 10, sin(x)*100);
x = x + 0.01;

for (let i = 0; i < 15; i++){
  circle(posLst[i][0], posLst[i][1], sin(sizeLst[i])*100);
  sizeLst[i] = sizeLst[i] + 0.01;
}

My sketch:

Reflection:

After trying this assignment, I realize that a lot of things can be replaced with variables. Then, the positions of the eyes, nose, etc. will be relative from that variable positioning. This would make any fix much easier in terms of position. I realized this halfway of my code when I want to move things a bit downwards. The more I have on the sketch, the long it takes for me to fix all of the position coordinates.

What I want to do next is to add interactivity into the sketch. My sketch currently only has some simple animation on the background. I also want to have animation on the portrait character as well as some interaction with the portrait.

(not) a Self-Portrait

So basically, I was using Duolingo and I noticed the new characters they added a while ago. I always liked the design of these characters and how they are just a bunch of smooth shapes together with nothing complicated. So I thought I would create a character that uses only circular edges shapes.

I also tried to add some interactivity to it. So, I made the eyes move with the mouse but only if the mouse is inside the eyes; other than that the eyes would be stuck to the side where the mouse is.

if (mouseX > 145 && mouseX < 175) {
  fill(00000);
  if (mouseY < 185 && mouseY > 150) {
    fill(00000);
    ellipse(mouseX, mouseY, 20, 35);
    ellipse(mouseX + 57, mouseY, 20, 35);
  } else if (mouseY >= 185) {
    fill(00000);
    ellipse(mouseX, 185, 20, 35);
    ellipse(mouseX + 57, 185, 20, 35);
  } else if (mouseY <= 150) {
    fill(00000);
    ellipse(mouseX, 150, 20, 35);
    ellipse(mouseX + 57, 150, 20, 35);
  } else {
    ellipse(mouseX, 170, 20, 35);
    ellipse(mouseX + 57, 170, 20, 35);
  }
}

The character is basically just a face with eyes, eyelids, “hair”, a fragment of the body of it, a mouth, and a tongue.

Honestly, I also was thinking of adding the functionality of clicking on the tongue of the character pulling it, and moving it forward. I tried it but it kept generating weird fragments of visuals where stuff started collapsing and not making sense visually.

Assignment 1 – Self portrait

For this self portrait assignment, I wanted to illustrate the 2d version of myself in a creative background. The code consists of a setup and draw functions and uses variables for the coordinates, directions, and speed of the animated background balls. The canvas is initially set to a size of 520×520, and the setup function populates an array named ‘balls’ with 20 instances of the Ball class, each representing a colored bouncing ball. The animated balls, governed by the Ball class, contribute a playful and dynamic element to the scene, bouncing randomly within the canvas boundaries.

As for my portrait, it is depicted with distinct features, including dark brown hair in an arc formation, a face represented by an ellipse, ears illustrated as arcs, and bangs with dark brown arcs above the forehead. Additional facial elements consist of black eyebrows, eyeshadow in dark semicircles, eyes depicted as dark brown ellipses with white eyeballs, and eyeglasses fashioned with black rectangular frames connected by a line. 

Further on, I would like to add more smoother and complex animations and user interactivity to it.

Highlighted code:

let balls = [];


function setup() {
  createCanvas(520, 520)
  // Create initial balls
  for (let i = 0; i < 20; i++) {
    balls.push(new Ball());
  }
}

function draw() {
  background(76, 160, 245);
  for (let ball of balls) {
    ball.move();
    ball.display();
  }
  //code for the portrait 
}

class Ball {
  constructor() {
    this.x = random(width);
    this.y = random(height);
    this.diameter = random(10, 30);
    this.color = color(random(255), random(255), random(255));
    this.xSpeed = random(-2, 4);
    this.ySpeed = random(-2, 4);
  }

  move() {
    this.x += this.xSpeed;
    this.y += this.ySpeed;

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

    if (this.y < 0 || this.y > height) {
      this.ySpeed *= -1;
    }
  }

  display() {
    fill(this.color);
    noStroke();
    ellipse(this.x, this.y, this.diameter, this.diameter);
  }
}

 

 

Assignment #1 – Self Portrait | Rashed Alshamsi

For this assignment, I did not want to recreate an image of myself, but I also wanted to add elements of my personality. One thing everyone knows about me is my ongoing passion for music; I collect vinyl records, CDs, and Cassettes. I cannot go anywhere without my headphones and I thought it would be a great idea to include that particular element as well as my ongoing love for music in my self-portrait.

I was particularly proud of the animated musical notes. Originally, I was not planning on animating them but I wanted to challenge myself to try and play around with creating variables and the “If()” function. I initially knew how to animate them but I did not know how to have them bouncing back and forth in the same location. I resorted to YouTube and watched a tutorial on how to animate in P5.js https://youtu.be/s2PZvaP4dSg?si=Q81GurZ6GAjqfVSs . Even after watching the video, I did not know how I could animate multiple variables at the same time that could move altogether. I then realized I could add the condition that if the variable “MusicNoteY1” would exceed a certain point, it would have the variable “ySpeed” equal negative “ySpeed” which would make it move in the opposite direction. Then I had all other music note variables move in their own value + ySpeed which had them all move together.

//Variables
let MusicNoteY1 = 130
let MusicNoteY2 = 70
let MusicNoteY3 = 120
let MusicNoteY4 = 60
let MusicNoteY5 = 81
let MusicNoteY6 = 69
let MusicNoteY7 = 55
let MusicNoteY8 = 70
let MusicNoteY9 = 395
let MusicNoteY10 = 335
let MusicNoteY11 = 330
let MusicNoteY12 = 350
let MusicNoteY13 = 360
let MusicNoteY14 = 341
let ySpeed = 2

function setup() {
  
  createCanvas(500, 500);
}
function draw() {
  background(104,191,255);
  
  //Grass
  noStroke();
  fill(157,231,121)
  arc(250, 500, 700, 250, PI,0,OPEN)
  
  print(mouseX + "," + mouseY);
  
  //Musical Note
  fill('black')
  ellipse(40,MusicNoteY1, 35,25);
  rect(48,MusicNoteY2, 10,60);
  ellipse(92,MusicNoteY3, 35,25);
  rect(100,MusicNoteY4, 10,60);
  quad(48,MusicNoteY5,48,MusicNoteY6,110, MusicNoteY7,110,MusicNoteY8)
  ellipse(442,MusicNoteY9, 35,25);
  rect(450,MusicNoteY10, 10,60);
  quad(450,MusicNoteY11, 450, MusicNoteY12, 474, MusicNoteY13,477,MusicNoteY14);
  MusicNoteY1 = MusicNoteY1 + ySpeed
  MusicNoteY2 = MusicNoteY2 + ySpeed
  MusicNoteY3 = MusicNoteY3 + ySpeed
  MusicNoteY4 = MusicNoteY4 + ySpeed
  MusicNoteY5 = MusicNoteY5 + ySpeed
  MusicNoteY6 = MusicNoteY6 + ySpeed
  MusicNoteY7 = MusicNoteY7 + ySpeed
  MusicNoteY8 = MusicNoteY8 + ySpeed
  MusicNoteY9 = MusicNoteY9 + ySpeed
  MusicNoteY10 = MusicNoteY10 + ySpeed
  MusicNoteY11 = MusicNoteY11 + ySpeed
  MusicNoteY12 = MusicNoteY12 + ySpeed
  MusicNoteY13 = MusicNoteY13 + ySpeed
  MusicNoteY14 = MusicNoteY14 + ySpeed
  
  if (MusicNoteY1 > 180) {
  ySpeed = -ySpeed;  
  }
  if (MusicNoteY1 < 100) {
    ySpeed = -ySpeed;
  }

I am looking forward to adding an interactive element to my work in the future.

 

Assignment #1 – Me, in a weird abstract way

For assignment #1, I found myself wanting to do something a bit unusual, as the emergent ideas that popped up in my brain told me to do something weird and abstract, like a self-portrait of myself but with weirdness added as a layer. So, thanks that I have a bit of knowledge using applications such as GIMP, I did a sketch of what I wanted to code, but taking into account that I did not want to make around 600+ lines of code.

The first step for this was to take a photo of myself, and then crop it to the 400×400 resolution to be allowed to use as a pixel reference. After cleaning the image and drawing what I would like to program, as shown in the screenshots below, it allowed me to proceed with the code implementation.

Figure 1. Preparing the image in GIMP (adding layers).
Figure 2. Using the image created in GIMP as a reference to code the image in p5.js

For the silhouette, I was a bit worried of not finding a particular function to allow drawing a free shape, but thanks to p5.js’ documentation, I found that the function beginShape(); can do what I wanted, so it was only a matter of drawing a lot of vertices with vertex(x,y);, according to the X and Y coordinates in GIMP, to fully draw my silhouette and proceed with the rest of the details.

The beginShape();code part is written like this for the sketch:

beginShape(); //I found this function helpful, as it allowed me to make the silhouette.
   vertex(2,383)
   vertex(0,400)
   vertex(346,400)
   vertex(325,375)
   vertex(315,382)
   vertex(300,369)
   vertex(304,351)
   vertex(283,348)
   vertex(316,230)
   vertex(312,211)
   vertex(328,190)
   vertex(316,106)
   vertex(313,100)
   vertex(310,46)
   vertex(285,26)
   vertex(269,22)
   vertex(248,10)
   vertex(200,10)
   vertex(164,17)
   vertex(126,45)
   vertex(95,78)
   vertex(83,117)
   vertex(86,179)
   vertex(73,192)
   vertex(79,236)
   vertex(94,255)
   vertex(112,258)
   vertex(120,325)
   vertex(105,347)
   vertex(80,357)
   vertex(64,359)
   vertex(2,383)
 endShape(); //Custom shape ends here.

This sketch took a lot of time as there were too many details, such as the many squares that act as the transparency placeholder for editing software and the triangles with abnormal X and Y positions. I have to admit it was fun and liberating to create something like this, but it took a lot of time, patience, and creativity to found a way to bring my idea into reality.

For future works, maybe I can implement other software to fully grasp the scope of what I want to create, as how I used GIMP to make the sketch and X and Y references. And regarding future improvements, maybe limit myself to only use p5.js (as an artist with only a stencil, its knowledge, and a white canvas) and integrate interactivity.

Assignment 1- Self Portrait (Me Before and After Hiking) by Sihyun Kim

One trivia about me is that I really love hiking, but I’m not very good at it. For most of my life, I’ve lived in a mountainous area in the Philippines, providing me with ample opportunities to go hiking. While I love the activity, I easily get tired and take hours to reach the top of a mountain. I thought it would be nice to create a self-portrait about my hiking experiences. Inspired by Pauline Wee’s Koala portrait from the examples provided, I decided to add some interactive elements when the mouse is pressed.

The concept is ‘Me  Before and After Hiking.’ I have created changes in facial expression and background color that occur when the mouse is pressed. Specifically, when the mouse is not pressed, you can see me with a happy face with blushes, indicating excitement before hiking. And, when the mouse is pressed, you can see me sweating with an exhausted face and a change of background color to indicate the exhaustion after hiking and the passage of time.

The section of code that I am particularly proud of is presented below. I was particularly proud of this section of code made for the change of facial expression when the mouse is pressed because I felt like I did a great job in making my code concise. Originally, I had multiple if-statements for each of the changes. However, I realized that I could just combine all these if-statements into one! It was quite challenging to combine the if-statements because I had to consider all the orders of the shapes to make a great-looking self-portrait.

// change of facial expression when mouse is pressed
  if (mouseIsPressed) {
    //left eye
    line(146, 193, 168, 203);
    line(146, 209, 166, 203);
    //right eye
    line(256, 193, 233, 203);
    line(256, 209, 233, 203);

    // mouth
    fill("red");
    arc(faceX, faceY + 73, 40, 40, PI, 0);
    line(faceX - 20, faceY + 73, faceX + 20, faceY + 73);

    // sweat drops
    sweatdrops(0);
    sweatdrops(30);
    sweatdrops(60);
  }
  //when mouse is not pressed
  else {
    //eyes
    fill(0);
    ellipse(160, 200, 15, 18); //left eye
    ellipse(242, 200, 15, 18); //right eye

    // eyelashes
    line(146, 193, 154, 197); //left eyelash
    line(256, 193, 250, 197); //right eyelash

    // mouth
    fill("red");
    arc(faceX, faceY + 53, 40, 40, 0, PI);
    line(faceX - 20, faceY + 53, faceX + 20, faceY + 53);

    // blush
    stroke("#FE847E");
    fill("#FE847E");
    ellipse(faceX - 60, 245, 20, 15);
    ellipse(faceX + 60, 245, 20, 15);
  }

Overall, I am very satisfied with the outcome of this assignment, although it may not be perfect. I find my self-portrait quite cute. This was my first time working with P5.js, and I found it very fun. Actually, I found this experience to be  similar to my experiences with Python and Processing. For improvements, I think adding animations like pouring rain or dripping sweat to my self-portrait would have made it more interesting. Also, it would have been more engaging to add additional interactions, like the body moving in response to cursor position.