For my first assignment, I decided to start with the basic shapes to make sure that I was comfortable with the foundations. I did not want to be too meticulous about the details; rather, I used my imagination and spatial thinking to draw fun yet precise face features that would properly display what game/social media avatars usually do.
Basic shapes – the avatar itself.
In the first stage of my work, I created a head, eyes, eyeballs, ears, and nose using straightforward ellipse()
and circle()
commands. I searched the Web for the most real-looking skin color RGB code and used it.
The next step was to find out the way to draw mouth, eyebrows, and hair. Again, I wanted my sketch to be similar to the real person’s features, so I decided to spend more time searching for proper code options. Looking at the examples from the past students’ work and watching the videos from The Coding Train helped me to get the idea of using arc()
and quad()
functions. The lesson that I learned from using these two functions is that you should be very precise with values and pay attention to details, otherwise you might mess up the drawing. It is especially important to learn how PI values work.
Moving on to the torso and the tank top, I used a little trick to visually separate the head and make it look like the neck (thanks to the arc()
function that I had just learned). I used rect()
and ellipse()
to create the torso and then used triangle()
to visually separate the body from the arms. Inspired by one of the works from previous years I also decided to add sunglasses and create a shape similar to the sunglasses that I usually wear using arc()
, and use Alpha value fill()
to make my eyes still visible through the lenses.
Background and animations.
To add more entertainment to my self-portrait, I first decided to add some interactivity. As I had just learned about random()
and mouseClicked()
, I decided to combine them to make the top tank color change with every click. Next, I created the background using rectangular shapes – the beach, the sea, and the sky. I searched for the most realistic RGB color codes, and I think colors look pretty good.
Lastly, I decided to challenge myself a little bit by trying to implement techniques I used in Python here in p5.js. To catch up with the syntax differences, I watched a couple of YouTube videos and searched the Reference on the p5.js website. The thing I am most proud of is the sun movements that I implemented using a Bezier curve. First, I drew the sun’s movement trajectory using bezier()
, and then I followed the instructions written in the Reference to use bezierPoint()
and make the sun move back and forth. This is a part of the code I am the most proud of.
//Curve for Sun Movement
x1 = 0
x2 = 100
x3 = 300
x4 = 400
y1 = 150
y2 = 0
y3 = 0
y4 = 150
noFill()
let x = bezierPoint(x1, x2, x3, x4, t)
let y = bezierPoint(y1, y2, y3, y4, t)
t += 0.001 * move_sun_dir //regulating the speed of the sun
if (t > 1 || t < 0) {
move_sun_dir *= -1
} //not letting the sun to go away from the screen
//Sun
fill(255,255,112)
noStroke()
circle(x, y, 50)
//Beach
fill(255, 234, 200)
noStroke()
rect(200, 400, 400, 200)
//Sea
fill(0, 105, 148)
noStroke()
rectMode(CORNER)
rect(0, 280, 400, sea_level)
sea_level += 0.05 * move_sea_dir //regulating the speed of the sea level
if (sea_level > 40) {
move_sea_dir = -1;
}
else if (sea_level < 30) {
move_sea_dir = 1;
} // keeping the sea level between the rectangle size values
As you might notice, just for the fun of it, I decided to use a similar coding technique to make the sea level rise and fall (in fact it is just the size of the rectangle that changes :)).
Conclusion.
I enjoyed working on my self-portrait, and I am satisfied with the result. I created a nice-looking sketch and already started to integrate some animations and interactivity into my work. Of course, there is tons to learn, and my self-portrait could be even more advanced. I was thinking of adding moving clouds to the sky, drawing palm trees on the beach, or adding ships going back and forth in the sea. I could add many more details, and I am looking forward to learning new tools and features to implement it. The coolest thing that I wanted to add but couldn’t is the change between day and night. As I made the sun move, I realized that it would look awesome if the brightness dimmed every time the sun went down, and vice-versa. I could also add the moon and the stars at night, and make them disappear in the morning.
Overall, this assignment was a great start to my journey in Interactive Media, and I can’t wait to see where this journey will lead me.
The Whole Code:
let r, g, b;
let t = 0;
let move_sun_dir = 1;
let move_sea_dir = 1;
let sea_level = 30;
function setup() {
createCanvas(400, 400);
r = random(255)
g = random(255)
b = random(255);
}
function draw() {
background(135, 206, 235);
//Curve for Sun Movement
x1 = 0
x2 = 100
x3 = 300
x4 = 400
y1 = 150
y2 = 0
y3 = 0
y4 = 150
noFill()
let x = bezierPoint(x1, x2, x3, x4, t)
let y = bezierPoint(y1, y2, y3, y4, t)
t += 0.001 * move_sun_dir //regulating the speed of the sun
if (t > 1 || t < 0) {
move_sun_dir *= -1
} //not letting the sun to go away from the screen
//Sun
fill(255,255,112)
noStroke()
circle(x, y, 50)
//Beach
fill(255, 234, 200)
noStroke()
rect(200, 400, 400, 200)
//Sea
fill(0, 105, 148)
noStroke()
rectMode(CORNER)
rect(0, 280, 400, sea_level)
sea_level += 0.05 * move_sea_dir //regulating the speed of the sea level
if (sea_level > 40) {
move_sea_dir = -1;
}
else if (sea_level < 30) {
move_sea_dir = 1;
} // keeping the sea level between the rectangle size values
// Head
fill(255,205,148)
noStroke()
ellipse(200, 200, 120, 150);
// Eyes
fill('white')
circle(175, 185, 15);
circle(225, 185, 15);
//Eyeballs
fill('black')
circle(175, 185, 5);
circle(225, 185, 5);
//Mouth
fill('white')
stroke('rgb(255,189,201)')
strokeWeight(4)
arc(200, 235, 35, 25, 0, PI, CHORD);
//Nose
fill(224,172,105)
noStroke()
ellipse(200, 210, 10, 20);
//Ears
fill(255,205,148)
ellipse(140, 190, 20, 30);
ellipse(260, 190, 20, 30);
//Side Hair
fill('black')
quad(145, 145, 165, 150, 160, 185, 145, 180);
quad(248, 140, 235, 145, 240, 185, 257, 180);
//Top Hair
fill('black')
ellipse(width / 2 - 5, 135, 110, 50);
//Eyebrows
noFill()
stroke('black')
arc(175, 180, 16, 16, PI + 0.6, TWO_PI - 0.5)
arc(225, 180, 16, 16, PI + 0.6, TWO_PI - 0.5)
//Tank top and Torso
noStroke()
fill(255,205,148)
ellipse(150, 370, 100, 200)
ellipse(250, 370, 100, 200);
rectMode(CENTER)
fill(r, g, b)
rect(200, 370, 115, 200);
stroke(255, 234, 200)
strokeWeight(5)
triangle(137, 400, 140, 325, 140, 400)
triangle(260, 400, 260, 325, 263, 400)
//Neck
noStroke()
fill(255,205,148)
arc(200, 270, 50, 50, 0, PI, CHORD);
//SunGlasses
fill(0, 0, 0, 100)
stroke('black')
strokeWeight(0.2)
arc(175, 178, 22, 37, 0, PI, CHORD)
arc(225, 178, 22, 37, 0, PI, CHORD)
strokeWeight(2)
line(143, 175, 164, 185)
line(236, 185, 257, 175)
line(186, 185, 214, 185)
}
// Changing color of the tank top
function mouseClicked() {
r = random(255)
g = random(255)
b = random(255)
}