Week 1 – Self-Portrait

 

Overview

Following the sessions on Week 1, our first assignment was to create a self-portrait using p5.js. Last semester I took Communications Lab, so I was familiar with the website, but I haven’t gone into such depts before, and for this assignment I decided to create my self-portrait with a little additional information about me, which is that I don’t like the rain.

I really wanted to use as many of the available 2D shapes as possible, such as the arc, the ellipse, the circle, the line, and the rectangle, along with some of the other resources like mouseX, mouseY, the mouseIsPressed, or constrain. I have tried to create myself a little challenge but also not put too much pressure on myself to put absolutely everything into this first assignment.

 

Process

For this assignment I decided to create an entirely new project and make my portrait out of scratch. I was sure that I wanted to add some basic interaction, just for a little practice and to make it more fun. I made the biggest components first, my head, my body, and my hair, and then moved on to the smaller details like my bangs, my eyes, nose, mouth, and my glasses. For all of these elements, I relied heavily on the p5.js references, but didn’t use any other external sources. I also decided after my body was fully made to put something in the background as well, just to make it a little less plain, and then came the idea that I will use my interaction here and show how much I don’t like standing in the rain. As a last touch, I also added some shading, just to play a little with the layers as well, and to add a little depth to it.

The Code

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

function draw() {
  background("lightblue");

//Sun
  fill("yellow");
  circle(50, 50, 60);
  
fill("black");
textFont('Courier New');
text('click and see what happens', 110, 60);
  
noStroke();


  
//Hair Shadow
  fill(127, 80);
  rect(104, 203, 200, 210,); 


//Hair
  fill("yellow");
  rect(100, 200, 200, 210,);

//Body Shadow on BG
  fill(120, 120);
  triangle(209, 300, 110, 600, 300, 600);
  
//Body
  fill("brown");
  triangle(200, 300, 110, 600, 300, 600);

//Shadow on Body 
  fill(127, 70);
  noStroke();
  ellipse(200, 400, 60, 30);
  
//Head
  fill("#F7D4C4");
  circle(200, 300, 200);
  
//Glasses
  noFill();
  stroke(0);
  strokeWeight(2);
  rect(145, 283, 45, 35, 5);
  rect(205, 283, 45, 35, 5);
  line(190, 300, 205, 300);

//Eyes
  fill(255);
  stroke(-2);
  circle(170, 300, 30);

  let px = constrain(mouseX, 165, 175);
  let py = constrain(mouseY, 295, 308);

  fill (0);
  circle(px, py, 10);

  fill(255);
  stroke(0);
  circle(225, 300, 30);
  
  let px2 = constrain(mouseX, 222, 230);
  let py2 = constrain(mouseY, 295, 310);
  
  fill (0);
  circle(px2, py2, 10);
  
//Nose
  stroke(1);
  strokeWeight(2);
  line(197, 315, 197, 330);

//Bangs shadow
  noStroke();
  fill(127,30);
  arc(100, 205, 200, 200, 0, HALF_PI);
  arc(300, 205, 200, 200, HALF_PI, PI);
  
//Bangs
  noStroke();
  fill("yellow");
  arc(100, 200, 200, 200, 0, HALF_PI);
  arc(300, 200, 200, 200, HALF_PI, PI);



//Mouth
  noFill();
  stroke(255, 0, 0);
  strokeWeight(4);
  arc(200, 340, 60, 40, 0, PI);
  
//Hand shadow
  noStroke();
  fill(127, 127);
  rect(164, 473, 20, 50);
  rect(229, 473, 20, 50);
  
//Hands
  fill("#F7D4C4");
  rect(160, 470, 20, 50);
  rect(225, 470, 20, 50);
  


  if(mouseIsPressed){
  background(220);
  noStroke();

//Clouds
  fill(255);
  circle(60,50,40);
  circle(85,50,50);
  circle(108,50,40);
  circle(210,120,60);
  circle(245,120,70);
  circle(280,120,60);

//Rain
    stroke("blue");
    strokeWeight(3);
    line(70, 90, 80, 120);
    line(90, 110, 100, 140);
    line(100, 90, 120, 150);
 
 noStroke();  

//Hair Shadow
  fill(127, 80);
  rect(104, 203, 200, 210,); 
    
//Hair
  fill("yellow");
  rect(100, 200, 200, 210,);

//Body Shadow on BG
  fill(120, 120);
  triangle(209, 300, 110, 600, 300, 600);
    
//Body
  fill("brown");
  triangle(200, 300, 110, 600, 300, 600);

//Shadow on Body 
  fill(127, 70);
  noStroke();
  ellipse(200, 400, 60, 30);
    
    
//Head
  fill("#F7D4C4");
  circle(200, 300, 200);

//Glasses
  noFill();
  stroke(0);
  strokeWeight(2);
  rect(145, 283, 45, 35, 5);
  rect(205, 283, 45, 35, 5);
  line(190, 300, 205, 300);

//Nose
  stroke(1);
  strokeWeight(2);
  line(197, 315, 197, 330);

//Bangs shadow
  noStroke();
  fill(127,30);
  arc(100, 205, 200, 200, 0, HALF_PI);
  arc(300, 205, 200, 200, HALF_PI, PI);

//Bangs
  noStroke();
  fill("yellow")
  arc(100, 200, 200, 200, 0, HALF_PI);
  arc(300, 200, 200, 200, HALF_PI, PI);

//Eyes
  fill(255);
  stroke(0);
  circle(170, 300, 30);

  fill (0);
  circle(170, 300, 10);

  fill(255);
  stroke(0);
  circle(225, 300, 30);
  
  fill (0);
  circle(225, 300, 10);

//Mouth
  noFill();
  stroke(255, 0, 0);
  strokeWeight(4);
  arc(200, 365, 60, 40, PI, TWO_PI);

//Hand shadow
  noStroke();
  fill(127, 127);
  rect(164, 473, 20, 50);
  rect(229, 473, 20, 50);

//Hands
  noStroke();
  fill("#F7D4C4");
  rect(160, 470, 20, 50);
  rect(225, 470, 20, 50);

  }
  

}

 

I can be a rather messy person in real life, and to compensate that I try to keep my online life a little more organised. I tried my best to divide all parts of the code, make it clear what piece of code is which part of the portrait and that made it a lot easier to later go back to it and adjust or correct certain things. It came in very handy for example when I was adding the shadows, especially the bangs, because it was a lot easier to find the “Glasses” and the “Bangs” chunks, between which I wanted to place my shadow.

Something that took a little more time but made me very happy to see it work were the moving eyes. I used the constrain calculation, which I had to try multiple times to work. I had to understand which parameter constrains which side, but after I figured that out, I was able to constrain my “pupil” to stay in the “eye” but still move.

//Eyes
  fill(255);
  stroke(-2);
  circle(170, 300, 30);

  let px = constrain(mouseX, 165, 175);
  let py = constrain(mouseY, 295, 308);

  fill (0);
  circle(px, py, 10);

  fill(255);
  stroke(0);
  circle(225, 300, 30);
  
  let px2 = constrain(mouseX, 222, 230);
  let py2 = constrain(mouseY, 295, 310);
  
  fill (0);
  circle(px2, py2, 10);

 

Reflection and Ideas

As a reflection, I had a lot of ideas for this project that I couldn’t do in the end. For example, I originally wanted my bangs to move as if it were the wind messing them up (which is another very important part of my everyday life), but I found it a little too difficult. I would love to explore more libraries in the future to find out about new techniques that could have also made the process of making this portrait easier or just different. Another thing I would also love to learn is how to make the movements smoother. I really love the eyes, however I would prefer them to move smoother than they do right now. But despite knowing that there is a lot of room for improvement, for this first project, my goal was not to go overboard but rather to explore the basics of p5.js, so overall I am happy with the results.

Leave a Reply