creyes1 Project-06 (Abstract Clock)
//Christopher Reyes
//Section D
//creyes1@andrew.cmu.edu
//Project-06 (Abstract Clock)
var prevSec;
var millisRolloverTime;
var moonX = 280;
var moonY = 160;
var moonSize = 260;
var moonShadowSize = moonSize*.9
var bgColor = [192, 214, 180];
var jewelHue;
var bgColorH;
var cx = moonX;
var cy = moonY;
function setup() {
createCanvas(480, 480);
colorMode(HSL);
angleMode(DEGREES);
background(bgColor);
millisRolloverTime = 0;
}
function draw() {
var H = hour();
var M = minute();
var S = second();
if (prevSec != S) {
millisRolloverTime = millis();
}
prevSec = S;
var mils = floor(millis() - millisRolloverTime);
var secondsWithFraction = S + (mils / 1000.0);
var secondsWithNoFraction = S;
//Converts current time to a number between 0 and 24
var currentTime = H + (M/60) + (secondsWithFraction/3600);
//Changes background color every minute, lighter in AM, darker in PM
var bgColorH = map(currentTime%6, 0, 6, 0, 360);
var bgColorS = map(currentTime, 0, 24, 30, 60);
var bgColorL = map(currentTime, 0, 24, 80, 20);
background(bgColorH, bgColorS, bgColorL);
//Lighter background ellipse towards bottom
noStroke();
fill(bgColorH, bgColorS-5, bgColorL+5);
ellipse(width/2, height, 500, 315);
//Moon
fill(0, 0, 90, 1);
ellipse(moonX, moonY, moonSize);
fill(0, 100, 100, 1);
ellipse(moonX, moonY, moonSize*.95);
fill(0, 0, 90, 1);
moonDetail(moonX, moonY);
//Moves shadow throughout the day, creating an eclipse at noon
var moonShadowX = map(currentTime, 0, 24,
moonX-(moonSize/2+moonShadowSize/2),
moonX+(moonSize/2+moonShadowSize/2));
//Moon Shadow, changes color along with background
fill(bgColorH, bgColorS, bgColorL, 1);
ellipse(moonShadowX, moonY, moonShadowSize);
//Clockwise spinnning ring based on current secondsWithFraction
stroke(0, 100, 100, 1);
noFill();
strokeWeight(5);
push();
translate(moonX, moonY);
rotate(map(secondsWithFraction, 0, 60, 0, 360));
arc(0, 0, moonSize*1.75, moonSize*1.75, 10, 110);
arc(0, 0, moonSize*1.75, moonSize*1.75, 130, 230);
arc(0, 0, moonSize*1.75, moonSize*1.75, 250, 350);
pop();
//Counter-clockwise spinning ring, also based on current secondsWithFraction
strokeWeight(2);
push();
translate(moonX, moonY);
rotate(map(secondsWithFraction, 0, 60, 360, 0));
arc(0, 0, moonSize*1.7, moonSize*1.7, 10, 110);
arc(0, 0, moonSize*1.7, moonSize*1.7, 130, 230);
arc(0, 0, moonSize*1.7, moonSize*1.7, 250, 350);
pop();
noStroke();
//Creates clouds that float across the screen every minute
var cloudX = map(secondsWithFraction, 0, 60, -100, width+140);
fill(0, 0, 95, .8);
cloud((cloudX-40)*1.05, 250+35, 1);
cloud((cloudX-30)*.9, 250-20, 1);
cloud(cloudX, 250, 1);
cloud((cloudX+20)*.95, 250-30, 1);
cloud((cloudX+30)*1.1, 250+30, 1);
cloud(cloudX+50, 250-25, 1);
//Jewel color is 180 degrees less the background's hue, including wraparound
var jewelHue = bgColorH - 180;
if (bgColorH < 180) {
jewelHue = 360 - (180-bgColorH);
} else {
var jewelHue = bgColorH - 180;
}
//Static jewels
jewel(115, 275, 1, jewelHue);
jewel(160, 350, .6, jewelHue);
jewel(65, 375, .8, jewelHue);
//Rotates 3 jewels around moon in a clock-like fashion according to time
var handOffset = 270; //Readjusts hands to start at 0 mark of the clock
var handPlace = moonSize;
//Second hand
var handAngleS = map(secondsWithFraction, 0, 60,
handOffset, 360+handOffset);
jewel(computeX(handPlace, handAngleS), computeY(handPlace, handAngleS),
.2, jewelHue);
//Minute hand
var handAngleM = map(M+(secondsWithFraction/60), 0, 60,
handOffset, 360+handOffset);
jewel(computeX(handPlace, handAngleM), computeY(handPlace, handAngleM),
.2, jewelHue);
//Hour hand
var handAngleH = map(currentTime%12, 0, 12, handOffset, 360+handOffset);
jewel(computeX(handPlace, handAngleH), computeY(handPlace, handAngleH),
.2, jewelHue);
}
function cloud(x, y, SCALE) {
quad(x, y+(20*SCALE), x+(40*SCALE), y, x, y-(20*SCALE), x-(40*SCALE), y);
}
function moonDetail(x, y) {
var moonDetailX = [x+55, x-25, x+20, x, x+70, x+103, x-70, x-55];
var moonDetailY = [y-15, y-45, y-78, y+30, y+30, y-10, y, y+55];
var moonDetailScale = [1.8, 1.2, .65, .8, .9, .5, .5, .3];
for (var i = 0; i < 8; i++) {
push();
translate(moonDetailX[i], moonDetailY[i]);
rotate(45)
cloud(0, 0, moonDetailScale[i]);
pop();
}
}
function jewel(x, y, SCALE, col) {
//I || Base shape
fill(col, 54, 71);
quad(x+(35*SCALE), y+(10*SCALE),
x, y-(83*SCALE),
x-(35*SCALE), y+(10*SCALE),
x, y+(83*SCALE));
//II
fill(col, 68, 80);
triangle(x-(35*SCALE), y+(10*SCALE),
x-(10*SCALE), y+(20*SCALE),
x, y-(83*SCALE));
//III
fill(col, 75, 75);
triangle(x-(35*SCALE), y+(10*SCALE),
x-(10*SCALE), y+(20*SCALE),
x, y+(83*SCALE));
//IV
fill(col, 46, 64);
triangle(x+(35*SCALE), y+(10*SCALE),
x-(10*SCALE), y+(20*SCALE),
x, y+(83*SCALE));
}
//Computes the X position of a point on a circle according to given parameters
function computeX(handRadius, angle) {
return cx + handRadius*cos(angle);
}
//Computes the Y position of a point on a circle according to given parameters
function computeY(handRadius, angle) {
return cy + handRadius*sin(angle);
}
For this project I wanted to loosely base it off of the eclipse mechanic I included in my Dynamic Drawing assignment, but still create a unique stand-alone image.
The shadow of the moon displays the time on a 24-hour cycle, eclipsing at noon every day, and all the colors of the image change throughout the course of the day in hue, saturation, and lightness. A lot of my process regarding this project simply came from experimenting and adding layers of elements to see what was effective.
Through the creation of this, I enjoyed being able to play around with the timing of my elements and seeing the little interactions between them as their cycles played out.