• Black Vimeo Icon

©2020 BY JENNY LIN

Animating with Codes - Self Portrait Motion Graphics

Updated: Sep 19, 2018



I thought creating an art work with codes was what was the most of a hassle, yet, designing the interaction experience for the users as well as thinking about the context turned out to be even more challenging.


Try moving the cursor around me, towards me, on me, and pressing the mouse!


I tried modifying my self portrait from last week, and made a little story line around it.

  • Each time the page is reloaded, the color of the sun is different. Like the weather in NYC, sometimes it is sunny, sometimes it is cloudy or even raining.

  • The lighting changes as users move the cursor from top to down, indicating the time of the day, from day to night.

  • My glasses changes its color according to the sun light as well.

  • I blush more the more the cursor gets closer to my face, as I like being approached and liked by other people.

  • Once the cursor get on to my face, I close my eyes and smile, as I like to be close to those dear to me.

  • However, if the user poke my face by pressing the mouse, I would frown and make a face (which is exactly what I would do if you poke my real face :P). And my glasses would shake to express me being shocked.

  • Finally, the constantly moving hearts around me symbolize my strong and extreme passion and affection.


This is my first draft of the portrait motion graphics, I altered the display of the hearts in the background to how it looks right now. Which one do you like better?



Problem Encountered

Originally, I wanted to make the hearts in the background rotate to the center of each hearts, but still have not figured out how to do it without changing the relative rotation of the square and the circles, which consist the hearts, as a result.


Later, I had another idea, I would like the hearts to be upstraight, and lay out as a beautiful pattern with the next row of the hearts being slightly towards the right relative to the previous row in the background, while the hearts move diagonally. Yet, I just cannot figure out how. I wonder if it is the "rotate" function that is making it so hard. (The hearts were driving me crazy, just like how human's hearts are the hardest to deal with :P)





Codes


let bgr;

let bgg;

let bgb;

let glfr = {

tx: 235,

ty: 190,

w: 90,

h: 60

};

let eyebr = {

lx: 220,

ly: 150,

w: 40

};

let hrts = [];


function setup() {

createCanvas(600, 360);

// bgr = random(200, 255);

// bgg = random(100, 130);

bgb = random(100, 255);

// background(bgr, bgg, bgb);

rectMode(CENTER);


for (let i = 0; i < 1000; i++) {

let x = 0 + 5 * i;

let y = 20 + 5 * i;

let colr = random(200, 255);

let colg = random(50, 100);

let colb = random(50, 100);

hrts[i] = new Heart(x, y, colr, colg, colb);

}


}


function draw() {

bgr = map(mouseY, 0, 360, 255, 0);

bgg = map(mouseY, 0, 360, 255, 0);

background(bgr, bgg, bgb);


//hearts

push();

for (let i = 0; i < hrts.length; i++) {

hrts[i].move();

hrts[i].col();

hrts[i].show();

}

pop();


//hair

noStroke();

fill(0, 30, 0);

arc(280, 180, 300, 300, PI + HALF_PI, TWO_PI);

ellipse(280, 75, 60, 100);

ellipse(420, 220, 60, 100);

ellipse(400, 250, 80, 100);

ellipse(350, 270, 100, 100);

arc(255, 170, 180, 260, PI, PI + HALF_PI);

ellipse(180, 200, 80, 100);

ellipse(200, 250, 100, 100);

ellipse(250, 270, 100, 100);



//face

noStroke();

fill(255, 215, 150);

arc(300, 190, 200, 250, 0, PI, CHORD);

rect(300, 180, 200, 55);

arc(255, 160, 110, 150, PI, PI + HALF_PI);

arc(255, 164, 203, 160, PI + HALF_PI, TWO_PI);


//ears

ellipse(390, 220, 30, 50);

ellipse(210, 220, 40, 60);



//cheeks

let blushA = map(dist(mouseX, mouseY, width / 2, height / 2), 0, 370, 100, 0);

fill(255, 50, 50, blushA);

ellipse(230, 235, 60);

ellipse(356, 235, 60);


//bang

fill(0, 30, 0);

arc(405, 140, 100, 160, HALF_PI, PI);

triangle(185, 200, 200, 190, 210, 250);

arc(220, 275, 50, 30, 0, PI + QUARTER_PI);


//eyebrows

noFill();

stroke(0);

strokeWeight(3);

line(eyebr.lx, eyebr.ly, eyebr.lx + eyebr.w, eyebr.ly);

line(eyebr.lx + 93, eyebr.ly, eyebr.lx + 93 + eyebr.w, eyebr.ly);


if (mouseIsPressed) {

if (mouseX > 200 && mouseX < 400 && mouseY > 84 && mouseY < 315) {

arc(eyebr.lx + eyebr.w, eyebr.ly - 6, 10, 10, 0, HALF_PI);

arc(eyebr.lx + 93, eyebr.ly - 6, 10, 10, HALF_PI, PI);

} else {

arc(eyebr.lx, eyebr.ly + 6, 10, 10, PI, PI + HALF_PI);

arc(eyebr.lx + 93 + eyebr.w, eyebr.ly + 6, 10, 10, PI + HALF_PI, TWO_PI);

}

} else {

arc(eyebr.lx, eyebr.ly + 6, 10, 10, PI, PI + HALF_PI);

arc(eyebr.lx + 93 + eyebr.w, eyebr.ly + 6, 10, 10, PI + HALF_PI, TWO_PI);

}


//eyes

// let eyea = map(dist(mouseX, mouseY, 290, 200), 0, 135, 0, 255);


let eyearc = map(dist(mouseX, mouseY, 290, 200), 0, 152, -0.38, 0);

let irisy = map(dist(mouseX, mouseY, width / 2, height / 2), 0, 152, 0, 15);

if (mouseX > 200 && mouseX < 400 && mouseY > 84 && mouseY < 315) {


//left eye

// noFill();

// stroke(0, eyea);

// strokeWeight(5);

// arc(248, 185, 30, 15, PI, TWO_PI);


stroke(0);

strokeWeight(5);

push();

translate(248, 185);

rotate(eyearc);

arc(0, 0, 17, 17, 0, PI + QUARTER_PI);

pop();


// noStroke();

// fill(20, eyea);

// ellipse(248, 185, 15, irisy);


//right eye

// noFill();

// stroke(0, eyea);

// strokeWeight(5);

// arc(328, 185, 30, 15, PI, TWO_PI);


push();

translate(328, 185);

rotate(eyearc);

arc(0, 0, 17, 17, 0, PI + QUARTER_PI);

pop();


// noStroke();

// fill(20, eyea);

// ellipse(328, 185, 15, irisy);


} else {

//left eye

noFill();

stroke(0, 255);

strokeWeight(5);

arc(248, 185, 30, 15, PI, TWO_PI);


stroke(0);

arc(248, 185, 17, 17, 0, PI + QUARTER_PI);


noStroke();

fill(20, 255);


ellipse(248, 185, 15, 15);


//right eye

noFill();

stroke(0, 255);

strokeWeight(5);

arc(328, 185, 30, 15, PI, TWO_PI);


stroke(0);

arc(328, 185, 17, 17, 0, PI + QUARTER_PI);


noStroke();

fill(20, 255);


ellipse(328, 185, 15, 15);

}


if (mouseIsPressed) {

//left eye

noFill();

stroke(0, 255);

strokeWeight(5);

arc(248, 185, 30, 15, PI, TWO_PI);


stroke(0);

arc(248, 185, 17, 17, 0, PI + QUARTER_PI);


noStroke();

fill(20, 255);

ellipse(248, 185, 15, 15);


//right eye

noFill();

stroke(0, 255);

strokeWeight(5);

arc(328, 185, 30, 15, PI, TWO_PI);


stroke(0);

arc(328, 185, 17, 17, 0, PI + QUARTER_PI);

push();

noStroke();

fill(20, 255);

ellipse(328, 185, 15, 15)

pop();

}


//mouth

if (mouseX > 200 && mouseX < 400 && mouseY > 84 && mouseY < 315) {

stroke(255, 50, 50);

arc(294, 255, 60, 30, 0, PI);

} else {

noStroke();

fill(255, 50, 50, 255);

arc(294, 255, 60, 60, 0, PI);

fill(255, 255);

quad(267, 258, 320, 258, 317, 265, 270, 265);

}


//glasses

glasses();

if (mouseIsPressed) {

if (mouseX > 200 && mouseX < 400 && mouseY > 84 && mouseY < 315) {

glfr.tx = 235 + random(-5, 5);

glfr.ty = 190 + random(-5, 5);

}

}

}



function glasses() {

stroke(77, 51, 0);

strokeWeight(3);


let gla = map(mouseY, 0, 180, 220, 0);

fill(0, 0, 20, gla);

arc(glfr.tx, glfr.ty, glfr.w, glfr.h, PI, TWO_PI);

arc(glfr.tx, glfr.ty, glfr.w, glfr.h + 30, 0, PI);

arc(glfr.tx + 105, glfr.ty, glfr.w, glfr.h, PI, TWO_PI);

arc(glfr.tx + 105, glfr.ty, glfr.w, glfr.h + 30, 0, PI);

noFill();

arc(glfr.tx + 52, glfr.ty - 5, glfr.w - 80, glfr.h - 55, PI, TWO_PI);

}


class Heart {

constructor(_x, _y, _colr, _colg, _colb) {

this.x = _x;

this.y = _y;

this.r = _colr;

this.g = _colg;

this.b = _colb;

}


move() {

this.x = this.x + 1;

this.y = this.y + 1;

if (this.x == width || this.y == height){

this.x = 0;

this.y = 20;

}

}


col() {

fill(this.r, this.g, this.b);

}


show() {

noStroke();

ellipse(this.x - 5, this.y - 5, 15);

ellipse(this.x + 5, this.y - 5, 15);

translate(this.x, this.y);

rotate(PI / 4.0);

rect(0, 0, 15, 15);

}

}


#ITP #ICM #coding #programming #motiongraphics #selfportrait