Julia Nishizaki – Project 06 – Abstract Clock

sketch

//Julia Nishizaki
//Section B
//jnishiza@andrew.cmu.edu
//Project 06, Abstract Clock

var islandX = 240; //starting X coordinate of island center
var islandY = 210; //y coordinate of island center, stays constant
var islandHalfWidth = 75; 
var islandH = 100; //tallest height of island mountain
var islandSpeed = 0.001; //controls the lag of island movement
var sheepSpeed = 0.01;
var gearWidth = 12; //the radius of the gear (represents radius of inner "circle")
var gearThick = 2; 
var sheepW = 20;
var sheepH = 15;
var sheepHeadW = 8;
var sheepHeadH = 12;
var ear = 4; //size of sheep ear ellipse
var eye = 2; //size of sheep eye ellipse
var sheepX = 0;

function setup() {
    createCanvas(480, 480);
    rectMode(CENTER);
    angleMode(DEGREES);
}

function draw() {
    background(220);
    var h = hour(); //24 hour clock
    var m = minute();
    var s = second();
    difisland = islandX - mouseX;
    islandX = constrain(islandX, islandHalfWidth * 3, width - islandHalfWidth * 3) + difisland * islandSpeed; //causes the island to move slowly to mouse position

    //sky, fades as time changes
    colorMode(HSB, 100); //change color mode in order to help with darkening/lightening the sky
    if (h > 18 & h < 24 || h > -1 && h < 6) {
        b = 15;    
    }if (h > 5 & h < 13) {
        b = 15 + (h * 7);
    } if (h > 11 & h < 19) {
        b = 99 - ((h - 12) * 7);
    }
    c = color(55, 60, b);
    fill(c);
    rect(width / 2, height / 2, width, height);

    //ground
    colorMode(RGB); //switch back to RGB from HSB
    fill(92, 147, 13);
    rect(width * 0.5, height - 25, width, 50);

    //mountain on island
    stroke(92, 147, 13);
    fill(92, 147, 13);
    strokeWeight(14);
    strokeJoin(ROUND);
    beginShape(); //vertices that form the mountain
    vertex(islandX - islandHalfWidth, islandY);
    vertex(islandX - islandHalfWidth * 0.3, islandY - islandH * 0.75);
    vertex(islandX - islandHalfWidth * 0.1, islandY - islandH * 0.6);
    vertex(islandX + islandHalfWidth * 0.2, islandY - islandH);
    vertex(islandX + islandHalfWidth * 0.65, islandY - islandH * 0.3);
    vertex(islandX + islandHalfWidth * 0.8, islandY - islandH * 0.3);
    vertex(islandX + islandHalfWidth, islandY);
    vertex(islandX - islandHalfWidth, islandY);
    endShape();

    //door in mountain
    var doorH = 45
    noStroke();
    fill(58, 109, 29);
    rect(islandX - islandHalfWidth * 0.3, islandY - doorH * 0.5, 20, doorH, 15, 15, 0, 0);
    noStroke(); //door knob
    fill(44, 84, 41);
    ellipse(islandX - islandHalfWidth * 0.375, islandY - doorH * 0.5, 3, 3);
    
    //window in mountain
    var winHalfLength = 25 * 0.5 //radius of window
    if (h > 7 & h < 19) {
    fill(58, 109, 29);
    ellipse(islandX + islandHalfWidth * 0.2, islandY - islandH * 0.5, 25, 25);
    } else { //makes the window glow yellow when it's "dark" outside
        fill(255, 197, 68);
        ellipse(islandX + islandHalfWidth * 0.2, islandY - islandH * 0.5, 25, 25);
    }
    stroke(44, 84, 41);
    strokeWeight(3); //bars of the window:
    line((islandX + islandHalfWidth * 0.2) - winHalfLength, islandY - islandH * 0.5, (islandX + islandHalfWidth * 0.2) + winHalfLength, islandY - islandH * 0.5);
    line(islandX + islandHalfWidth * 0.2, (islandY - islandH * 0.5) - winHalfLength, islandX + islandHalfWidth * 0.2, (islandY - islandH * 0.5) + winHalfLength);
    
    //underneath the island
    stroke(44, 84, 41);
    fill(44, 84, 41);
    strokeWeight(18);
    beginShape(); //vertices that form the underside
    vertex(islandX - islandHalfWidth, islandY);
    vertex(islandX - islandHalfWidth * 0.75, islandY + islandH * 0.4);
    vertex(islandX - islandHalfWidth * 0.5, islandY + islandH * 0.5);
    vertex(islandX - islandHalfWidth * 0.3, islandY + islandH * 0.75);
    vertex(islandX - islandHalfWidth * 0.1, islandY + islandH * 0.85);
    vertex(islandX + islandHalfWidth * 0.2, islandY + islandH * 0.6);
    vertex(islandX + islandHalfWidth * 0.5, islandY + islandH * 0.5);
    vertex(islandX + islandHalfWidth * 0.65, islandY + islandH * 0.3);
    vertex(islandX + islandHalfWidth * 0.8, islandY + islandH * 0.25);
    vertex(islandX + islandHalfWidth, islandY);
    vertex(islandX - islandHalfWidth, islandY);
    endShape();

    //gear, rotates every second
    push();
    strokeWeight(2);
    stroke(255);
    translate(islandX + islandHalfWidth * 0.99, islandY + islandH * 0.1);
    for (var g = 0; g < 60; g ++) {
        if (g > s || g < s) {
            push();
            rotate(180 + g * 6);
            line(0, gearWidth, 0, gearWidth + gearThick);
            pop();    
        } else { //highlights the second hand on the gear
            push();
            stroke(124, 17, 17);
            rotate(180 + g * 6);
            gearMiddle(0, 0); //rotates the center cutouts of the gear
            line(0, gearWidth, 0, gearWidth + 2 * gearThick); //the second hand
            pop();
        } 
    }
    pop();

    //ladder, increases by one rung each minute
    var ladderH = 5; 
    var ladderW = 15;
    var ladderX = islandX - islandHalfWidth;
    stroke(153, 124, 232);
    strokeWeight(2);
    line(ladderX, islandY - 9, ladderX, islandY);
    line(ladderX + ladderW, islandY - 9, ladderX + ladderW, islandY);
    for (var i = 0; i < m; i += 1) {
        var ladderY = (islandY - 3)  + 4 * i; //Y coordinate for the start of the ladder
        if (i < 9 || i > 9 & i < 19 || i > 19 && i < 29 || i > 29 && i < 39 || i > 39 && i < 49 || i > 49) { //creates everything but the 10's
        stroke(255);
        line(ladderX, ladderY, ladderX + ladderW, ladderY); //the rungs of the ladder that correspond to everything but the multiples of 10
        } else {
        stroke(153, 124, 232);
        line(ladderX, ladderY, ladderX + ladderW, ladderY); //the rungs of the ladder that correspond to every 10 minutes
        }
        stroke(153, 124, 232);
        line(ladderX, ladderY - ladderH, ladderX, ladderY + ladderH); //left vertical rail of ladder
        line(ladderX + ladderW, ladderY - ladderH, ladderX + ladderW, ladderY + ladderH); //right vertical rail of ladder
    }

    //text: hour, minute, second, colons
    noStroke();
    textSize(14);
    var textX = width * 0.5;
    var textY = height - 20;
    var coltextdistX = 20;
    var coltextdistY = 2; //adds to the Y coordinates for the colons, to visually center them vertically
    fill(255);
    rect(textX, textY - 5, 100, 25, 30, 30, 30, 30);
    fill(255, 197, 68);
    textAlign(RIGHT); //hour text
    if (h < 10) {
        text(nf(h, 1, 0), textX - 1.4 * coltextdistX, textY);
    } else {
        text(nf(h, 2, 0), textX - 1.4 * coltextdistX, textY);
    }
    fill(92, 147, 13);
    textAlign(CENTER); //colon and minute text
    text(':', textX - coltextdistX, textY - coltextdistY); //colon between hour and minute
    text(':', textX + coltextdistX, textY - coltextdistY); //colon between minute and second
    fill(153, 124, 232);
    text(nf(m, 2, 0), textX, textY);
    textAlign(LEFT); //second text
    fill(124, 17, 17);
    if (s < 10) {
        text(nf(s, 1, 0), textX + 1.4 * coltextdistX, textY);
    } else {
        text(nf(s, 2, 0), textX + 1.4 * coltextdistX, textY);
    }

    //sheep stack
    difsheep = mouseX - sheepX;
    sheepX = constrain(sheepX, sheepW, (width - sheepW * 1.5)) + difsheep * sheepSpeed; //causes the sheep to move slowly to mouse position
    for (var y = 0; y < h; y += 1) {
        sheep(sheepX, (height * 0.95 - sheepH * 2) - (y * sheepH * 1.15));
        if ((sheepX - mouseX) > 0) {
        sheepHead(- sheepW * 0.25 + (sheepX  * 0.5), (height * 0.95 - sheepH * 2) - (y * sheepH * 1.15));       
        } else {
        sheepHead(sheepW * 0.25 + (sheepX  * 0.5), (height * 0.95 - sheepH * 2) - (y * sheepH * 1.15));
        }
    }
}

//gear cutouts
function gearMiddle(x, y) { //creates the center cutouts of the gear
    for (var d = 0; d < 4; d ++) {
        push()
        stroke(255);
        strokeWeight(2);
        rotate(d * 45);
        line(x, y - gearWidth - 2 * gearThick, x, y + gearWidth + 2 * gearThick);
        pop();
    }
}

//sheep
function sheep(x, y) {
    push();
    translate(x, y);
    stroke(0);
    strokeWeight(2);
    line(-sheepW * 0.25, 0, -sheepW * 0.25, sheepH * 0.6); //sheep leg left
    line(sheepW * 0.25, 0, sheepW * 0.25, sheepH * 0.6); //sheep leg right
    noStroke();
    fill(0);
    ellipse(-sheepW * 0.5, 0, ear, ear); //sheep tail left
    ellipse(sheepW * 0.5, 0, ear, ear); //sheep tail right
    fill(255);
    stroke(255, 197, 68)
    strokeWeight(1.25);
    rect(0, 0, sheepW, sheepH, 15, 15, 15, 15); //sheep body
    pop();
}

function sheepHead(x, y) {
    push();
    translate(x, y);
    noStroke();
    fill(0);
    rect(x, y / 600, sheepHeadW, sheepHeadH, 3, 3, 15, 15); //sheep head
    ellipse(x - sheepHeadW * 0.5, (y / 600) - sheepHeadH * 0.2, ear, ear); //left sheep ear
    ellipse(x + sheepHeadW * 0.5, (y / 600) - sheepHeadH * 0.2, ear, ear); //right sheep ear
    fill(255);
    ellipse(x - 2, y / 600, eye, eye); //left sheep eye
    ellipse(x + 2, y / 600, eye, eye); //right sheep eye
    pop();
}

While I didn’t really explore unconventional ways to read time through this project, I tried to seamlessly embed time into a simple but fun illustration, so that it became more of an artefact, rather than something really practical. I was initially inspired by the concept of cuckoo clocks, but my clock eventually warped into a floating island. I ended up creating a 24 hour clock, where the number of sheep represent the hour, the number of rungs on the ladder represent the minute, and the gear on the island shows the seconds.

Leave a Reply