(Try Clicking on the Mouth when it’s Open!)
I had a few ideas of how I wanted to depict myself, none of which included a real depiction of my face, but more or less characters that I resonated with. I quickly scrapped that idea when I felt like it wouldn’t really be challenging me if I drew a depiction of an already existing illustration.
With my limited coding experience it would be certainly difficult to go from concept into actualization using just my keyboard and the funny colored words on screen, but I was committed to making something worth looking at.
One of the first things I tried to understand coming from a long photoshop/graphic design background was how layers would work on p5.js. Understanding this early gave me a lot of confidence that I wasn’t going to make something uncanny-looking. I made each body segment its own function and called it in the order from the lowest layer to the highest layer in draw()
function draw() { //draw runs on loop 60/sec background(110,40,80);//change later? //Draws Body Parts in Layers drawHair(); drawTorso(90); drawHead(); drawLeftEye(6.7);//parameter is for gap between lines drawRightEye(6.7) drawMouth(); drawHands(); drawBangs(); }
As I learned more about p5.js through tutorials, I wrote down lots of notes and reminders to myself. One tip that really helped me out initially was putting fill() before the shape I wanted to draw. When I was listening to the demonstration in class I thought it would make more sense for fill() to have parameters for what you wanted to fill, but after working with the shapes today I realized that would’ve caused a big confusing wall of text very quickly. Putting notes next to how many parameters and what each parameter did for each function was also really helpful in my learning process.
I wasn’t quite sure how to depict the face at first with just simple geometry but by removing the outline “strokes” and blending shapes I started sculpting some much nicer shapes.
I really wanted my avatar’s arms to be interactable with the user’s mouse values so I initially allowed the top Y-positions of the arm segments to be controlled using the mouse. I obviously didn’t want it to go out of bounds so I looked through the p5js reference until I found the constrain() function. This was a huge lifesaver for both this aspect of the self-portrait and some other aspects I worked on after this.
let armY = constrain(mouseY, 430, 500); //restricted value, min, max let armX = constrain(mouseX, 200, 350); //LEFT quad( armX-60, armY, //top left 220~ armX-10, armY+20, //top right 280~ 220, 600, //bottom right 100, 600 //bottom left ); //RIGHT ARM quad( armX+110, armY, //top left 380~ armX+60, armY+20, //top right 320~ width-220, 600, //bottom right width-100, 600 //bottom left );
This snippet was taken as I was working out the arm animation and tracking. Mini-me was very deprived of any type of hair back then. He was also very gray.

I feel like the hand movements made the avatar feel so much more alive and responsive, making good use of p5.js in ways beyond just turning code into still images. This would go a step beyond when I added the cookie into mini-me’s hands then another step beyond when the mouth would respond to having a cookie in front of it.
//COOKIE fill(210, 180, 140); stroke(190, 160, 120); cookieX = armX+25 //main cookie area if (cookieEaten) { arc(cookieX,armY,150,75,5.7,3.5) //cookie missing the top corner console.log("Cookie was Eaten") } else { arc(cookieX,armY,150,75,0,2*PI) //a full cookie } //chocolate chips fill(90, 60, 40); noStroke(); //top left to bottom right ellipse(cookieX-50,armY-10,19,14) ellipse(cookieX-21,armY-2,16,10) ellipse(cookieX-37,armY+10,12,7) ellipse(cookieX+3,armY+8,17,12) ellipse(cookieX+22,armY-6,12,8) ellipse(cookieX+29,armY+20,15,10) ellipse(cookieX+38,armY+2,18,13)
At first I didn’t have any chocolate chips on the cookie and my friend thought it was holding an empty plate so I decided to add some chocolate chips even though the way I did it was probably not very efficient. I considered using random variables like I’ve seen some previous projects utilize for their backgrounds but the choco chips needed to avoid a very specific area of the cookie that would be “bitten” into while looking well balanced.
One of my goals with the cookie in hand was to let the user be able to eat it by clicking on the mouth of mini-me, but I didn’t know how to program a bite mark into the ellipse so I decided to change it into an arc() halfway through and use the arc’s unique properties to cut out a portion of it near the mouth, making it appear like it had been bitten into. I was pretty proud of how I worked with my limited knowledge here.
cookieEaten = false function mouseClicked() { console.log(mouseX,mouseY) if (mouseX > 280 && mouseX < 320 && mouseY > 330 && mouseY < 400){ cookieEaten = true; console.log("clicked mouth"); } } //lots of stuff here in between in the real code... if (cookieEaten) { arc(cookieX,armY,150,75,5.7,3.5) //cookie missing the top corner console.log("Cookie was Eaten") } else { arc(cookieX,armY,150,75,0,2*PI) //a full cookie }
By far the most unsatisfying part to me was definitely the way I did my hair. There were just so little polygons to work with to properly express what type of hairstyle I wanted for mini-me. However, a lot of my friends said they actually really liked how I depicted the hair so perhaps I’m fixating on it too much.
My biggest regret was that I only learned after I was nearly done with my self-portrait that I could’ve changed the angleMode() to degrees the whole time… I spent so much time trying to remember middle school math just to work out the PI angles for certain arcs.
//the upper lip arc(cenX - 210/4, faceCenY, 150, 150, PI/4, PI/2); //left side arc(cenX + 210/4, faceCenY, 150, 150, PI/2, 3*PI/4);//right side
If I were to do this exercise again, I would probably create more variables to make certain parameters look a little more organized and efficient. I changed a few parts to stuff like “width-X” rather than calculating it myself but there was definitely more I could’ve done to make everything look cleaner.
Overall for my first experience with p5.js and my limited experience with JavaScript , I think I would be proud of myself even later down the line.