xxxxxxxxxx
194
/*ASSIGNMENT #2: STILL LIFE
This project was inspired by autumn, the comfort of steam and a hot coffee.
MOVE your mouse around to move the steam.
HOLD CLICK to shake from coffee jitters.
The original sine wave code was taken from Daniel Shiffman's processing reference example https://processing.org/examples/sinewave.html.
I altered it as follows:
- made it vertical instead of horizontal
- made the spacing smaller so the wave looks smooth and not like individual ellipses
- mapped mouseX and made smoke expand and contract with it (more explanation in calcSteam();
The coffee was also animated with altered noise wave code (also from Daniel Shiffman, https://processing.org/examples/noisewave.html).
The main change was giving it more noise when shake animation is playing.
*/
// GLOBAL VARIABLES
let xspacing = 20;
let w;
let theta = 0.0;
let amp = 20;
let dx = 0.0;
let yvalues = [];
let period = 500.0;
let yoff = 0.0;
// COLORS
let bg = "#a18a6a"; // orange
let cup = "#d1cbc2"; // cream
let cupShadow = "#bab5ad"; // grey
let liquid = "#4f3f28"; // coffee
let table = "#423b2e"; // brown
let castShadow = "#24211b"; // dark
let lightColor = "#f5b771"; // yellow
function setup() {
createCanvas(1920, 1080);
w = width + xspacing;
dx = (TWO_PI / period) * xspacing;
for (let i = 0; i < w / xspacing; i++) {
yvalues[i] = 0;
}
}
function draw() {
background(bg);
noStroke();
fill(lightColor);
ellipse(960, 400, 1000, 1000);
// if mouse pressed, shake the coffee cup
coffeeJitters();
// inside of cup
fill(cupShadow);
ellipse(956, 675, 379, 104);
// liquid
fill(liquid);
ellipse(950, 700, 379, 40);
renderCoffee();
// steam
calcSteam();
renderSteam();
// table
fill(table);
rect(-10, 800, 1940, 800);
// cast shadow
fill(castShadow);
ellipse(900, 874, 422, 80);
// cup
fill(cup);
beginShape();
vertex(766, 678);
bezierVertex(766, 777, 829, 870, 952, 875);
bezierVertex(1013, 876, 1059, 860, 1092, 825);
bezierVertex(1130, 784, 1147, 687, 1147, 678);
bezierVertex(1047, 725, 949, 726, 798, 690);
endShape(CLOSE);
// cup handle
strokeCap(ROUND);
stroke(cup);
strokeWeight(50);
noFill();
arc(765, 755, 100, 100, 0, PI + HALF_PI, OPEN);
noStroke();
// cup shadow
noStroke();
fill(cupShadow);
beginShape();
vertex(760, 698);
bezierVertex(770, 775, 829, 870, 952, 875);
bezierVertex(1013, 876, 1059, 860, 1092, 825);
bezierVertex(979, 820, 917, 797, 823, 741);
endShape(CLOSE);
// cup handle shadow
noFill();
stroke(cupShadow);
noStroke();
strokeWeight(30);
strokeCap(PROJECT);
arc(765, 765, 120, 100, QUARTER_PI, PI);
// calculate THIRD_PI
let THIRD_PI = PI / 3;
arc(800, 755, 190, 90, PI, PI + THIRD_PI);
}
// HELPER FUNCTIONS
// translates everything on the canvas a random float between -10 and 10px for a shaking effect
function coffeeJitters() {
let randomX = random(-10, 10);
if (mouseIsPressed) {
translate(randomX, 0);
}
}
// this is an altered version of additive wave.
// adds noise to the coffee inside the cup, and increases it while shaking
function renderCoffee() {
// inside of cup
fill(cupShadow);
ellipse(956, 675, 379, 104);
// liquid
fill(liquid);
ellipse(950, 700, 379, 40);
beginShape();
let xoff = 10;
for (let x = 780; x <= 1130; x += 10) {
let y = map(noise(xoff, yoff), 0, 1, 660, 720);
vertex(x, y);
xoff += 0.09;
}
if (mouseIsPressed) {
yoff += 0.2;
} else {
yoff += 0.01;
}
vertex(1120, 760);
vertex(775, 750);
endShape(CLOSE);
noStroke()
}
// STEAM FUNCTIONS
// calcSteam() calculates parameters for each ellipse and stores it in array yvalues for renderSteam() to use
function calcSteam() {
// map restricts smoke amplitude to +-60 from center of canvas (x=960)
let mouseXaltered = map(mouseX, 250, 1670, 900, 1020);
theta += 0.02; // controls speed: higher number = faster
let x = theta;
// amplitude changes depending on mapped mouseX position
// but still has an amp of at least 20
for (let i = 0; i < yvalues.length; i++) {
amp = -1 * (960 - mouseXaltered) + 20;
yvalues[i] = sin(x) * amp;
x += dx;
}
}
// renderSteam() draws the ellipses based on array yvalues filled by calcSteam()
function renderSteam() {
fill(255, 255, 255, 50);
let ellipseWidth = 100;
let half = 20; // Approx vertical center of steam between top of canvas and cup
for (let x = 0; x < yvalues.length; x++) {
if (x < half) {
ellipseWidth += 5;
} else if (x >= half) {
ellipseWidth -= 5;
}
ellipse(width / 2 + yvalues[x], x * xspacing, ellipseWidth, ellipseWidth + 50, PI);
}
noStroke();
}
function mask() {
rect(766, 600, 378, 100);
}