Your browser does not support the canvas tag.

previous        Show / Hide Source        Download        next
//Mood-Chooser
//An Interactive Drawing by Peter Francis

//How are you feeling right now?
//Move the mouse left, right, up, and down
//Don't forget to try clicking in the top-left and bottom-right!

void setup() {
  size(400, 400);

  //lay down some sweet anti-aliasing for ya nerves
  smooth();
}

void draw() {

  //set the framerate to a brisk, crisp 60fps.
  frameRate(60);

  //draw a dynamic background wish shifting colours.
  //The base is grey-blue at (200,200). Each corner has its own colour. 
  background(150+((mouseX-200)+(mouseY-200))-((mouseX-200)-(mouseY-200))/8-mouseY/4, 
    150+((mouseX-200)-(mouseY-200))/8, 
    190+((mouseY-200)-(mouseX-200))/8-mouseY/8); 

  //Draw a rectangle over the background that gets darker in the bottom corners
  noStroke();
  rectMode(CORNER);
  fill(255-(mouseX+mouseY)/8, 125);
  rect(0, 0, width, height);

  //Looming Darkness
  //Draw dark rectangles that descend during sad moods
  fill(0, -170+mouseY/2); 
  rect(0, -220+mouseY/2.2+mouseX/10, 400, 100);
  rect(0, -220+mouseY/2.2+mouseX/10, 400, 130);
  rect(0, -220+mouseY/2.2+mouseX/10, 400, 160);
  
  //Sunshine and daylight
  //Draw come background effects that fade in near 0,0
  fill(247,247,168,100-(mouseX+mouseY)/2);
  ellipse(10,10,100,100);
  ellipse(10,10,110,110);
  ellipse(10,10,130,130);
  ellipse(10,10,170,170);
  fill(255,255,255,75-(mouseX+mouseY)/2);
  rect(0,0,400,150);
  rect(0,0,400,300);

  //Sundburst of Pride 
  //Draw the animated sunburst that fades in as X increases and Y decreases.
  noStroke();
  fill(245, 244, 185, -100+(mouseX-mouseY)/2);
  triangle(0, 250, 0, 150, 250, 200);
  triangle(400, 250, 400, 150, 150, 200);
  triangle(150, 0, 250, 0, 200, 250);
  triangle(150, 400, 250, 400, 200, 150);
  //Sunburst wobbles according to sine and framecount
  ellipse(200, 200, 240+(sin(frameCount*0.1))*8, 240+(sin(frameCount*0.1))*8);
  ellipse(200, 200, 270+(sin(frameCount*0.1))*8, 270+(sin(frameCount*0.1))*8);

  //Draw the base of the cute face
  fill(235, 219, 153); 
  ellipse(200, 200, 200, 200);
  fill(255, 239, 173); 

  //A second ellipse makes the face feel 3D
  ellipse(195, 195, 175, 175); 

  //Every shape from this point on has "+(mouseY-200)/10" or something 
  //similar on the Y value. This is because the whole face now moves up/down
  //with the mouse.

  //Eyes
  stroke(0);
  fill(0);
  strokeWeight(5); 
  ellipse(160, 180+(mouseY-200)/10, 14, 22); //left
  ellipse(240, 180+(mouseY-200)/10, 14, 22); //right

  //Mouth 
  //Looks happy or sad with Y, widens and narrows with X
  bezier(160-(pmouseX-200)/22, (pmouseY-200)/12+235+(mouseY-200)/20, 
    187.5-(pmouseX-200)/12, 235-(pmouseY-200)/12+(mouseY-200)/20, 
    215+(pmouseX-200)/12, 235-(pmouseY-200)/12+(mouseY-200)/20, 
    240+(pmouseX-200)/22, (pmouseY-200)/12+235+(mouseY-200)/20); 

  //Cheeks and Brows 
  //Skin-coloured quads that reshape the eyes
  //Brows - Left is "sad", Right is "mad"
  rectMode(CENTER);
  fill(255, 239, 173);
  noStroke();
  //Left brow
  quad(180, (167+(mouseX-200)/22)+mouseY/30+(mouseY-200)/10, //bottomright
    140, (167-(mouseX-200)/22)+mouseY/30+(mouseY-200)/10, //bottomleft
    140, 155+(mouseY-200)/10, 180, 155+(mouseY-200)/10);  
  //Right brow 
  quad(260, (166-(mouseX-200)/22)+mouseY/30+(mouseY-200)/10, //bottomright
    220, (167+(mouseX-200)/22)+mouseY/30+(mouseY-200)/10, //bottomleft
    220, 155+(mouseY-200)/10, 260, 155+(mouseY-200)/10);

  //Cheeks
  //A skin-coloured rectangle that narrows the eyes to make smiles look happier
  rect(200, 210-(400-mouseY)/20+(mouseY-200)/10, 100, 10);

  //Growl/Squint Bar 
  //This is a skin-coloured bezier that changes the shape of the mouth and eyes.
  //It makes the mouth grimace, and the eyes narrow, when Y is high.
  //At Y=300 and above, it quickly vanishes so it doesn't interrupt other faces. 
  fill(255, 239, 173, -300+mouseY*2);
  bezier(140, 210, 180, 210+(mouseY/8), 220, 210+(mouseY/8), 260, 210);

  //Cute rosy cheeks
  //The cheeks only appear near (0,0)
  fill(201, 79, 109, 100-(mouseX+mouseY)/2); 
  ellipse(250, 200+(mouseY-200)/10, 30, 20);
  ellipse(150, 200+(mouseY-200)/10, 30, 20);

  //Tears
  fill(135, 190, 245, -90+(mouseY-mouseX)/2);
  rect(160, 305, 10+(sin(frameCount*0.1)), 195);//left tears
  rect(240, 305, 10+(sin(frameCount*0.1)), 195);//right tears

  //Tearflow (the moving sheen on the tear waterfall)
  //Taking the remainder of 60 put into the frame count let me make falling tears. 
  //5 white lines are moving down 60 pixels and then snapping back to their original
  //positions but it looks like they're all continuously flowing!
  stroke(255, -90+(mouseY-mouseX)/2);
  strokeWeight(4);
  //Left Eye Tear stream
  bezier(157, 215+frameCount%60, 158, 218+frameCount%60, 161.5, 212+frameCount%60, 163, 215+frameCount%60);
  bezier(157, 275+frameCount%60, 158, 278+frameCount%60, 161.5, 272+frameCount%60, 163, 275+frameCount%60);
  bezier(157, 335+frameCount%60, 158, 338+frameCount%60, 161.5, 332+frameCount%60, 163, 335+frameCount%60);
  bezier(157, 395+frameCount%60, 158, 398+frameCount%60, 161.5, 392+frameCount%60, 163, 395+frameCount%60);
  //Right Eye Tear Stream
  bezier(237, 215+frameCount%60, 238, 218+frameCount%60, 241.5, 212+frameCount%60, 243, 215+frameCount%60);
  bezier(237, 275+frameCount%60, 238, 278+frameCount%60, 241.5, 272+frameCount%60, 243, 275+frameCount%60);
  bezier(237, 335+frameCount%60, 238, 338+frameCount%60, 241.5, 332+frameCount%60, 243, 335+frameCount%60);
  bezier(237, 395+frameCount%60, 238, 398+frameCount%60, 241.5, 392+frameCount%60, 243, 395+frameCount%60);

  //Anger Forehead
  fill(225, 209, 143, -400+(mouseX+mouseY)-abs(mouseX-mouseY));
  stroke(225, 209, 143, -400+(mouseX+mouseY)-abs(mouseX-mouseY));
  strokeWeight(3);
  quad(200, 150+(mouseX+mouseY)/20, 210, 140+(mouseX+mouseY)/20, 200, 145+(mouseX+mouseY)/20, 190, 140+(mouseX+mouseY)/20);

  //Stormclouds
  //Various transparent clouds that move and fade in at different speeds
  fill(120, -400+(mouseX+mouseY)-abs(mouseX-mouseY));
  stroke(100, -400+(mouseX+mouseY)-abs(mouseX-mouseY));
  strokeWeight(10); 
  rect(480-(mouseX+mouseY)/7, -10, 230, 65, 20); 
  rect(480-(mouseX+mouseY)/4, 25, 130, 75, 20); 
  rect(-80+(mouseX+mouseY)/3, 10, 143, 55, 20); 
  rect(-80+(mouseX+mouseY)/7, -20, 280, 85, 20);
  rect(-290+(mouseX+mouseY)/2.3, 30, 110, 70, 20);
}

//Actions that occur when the mouse is clicked
void mousePressed() {
  frameRate(5);

  //the lightning flash
  stroke(255, -400+(mouseX+mouseY)-abs(mouseX-mouseY));
  strokeWeight(5);
  line(40, 40, 100, 140); 
  strokeWeight(4);
  line(100, 140, 80, 200);
  strokeWeight(2);
  line(80, 200, 100, 260);
  line(92, 165, 120, 200); 
  strokeWeight(1);
  line(87, 225, 70, 245); 

  //the wink
  noStroke(); 
  fill(255, 239, 173, 370-(mouseX+mouseY)*3);
  quad(180, 165, 140, 160, 140, 125, 180, 125); 
  quad(180, 167, 140, 162, 140, 170, 180, 170);
}