nerual-Clock

 

Between 1am and 8am, BERT-O-CLOCK sleeps, but he can be woken to give you the time. Between 8am and 10am, he sleeps, and he won't wake up. Otherwise, he's awake and keeping time.

And at a very particular time, BERT-O-CLOCK likes to have some fun.

I was really interested in the notion of using hands and fingers to count time, like how small children learn math. This lead me on this path of a childish aesthetic and manner of interaction with the piece. I thought it would be interesting to have this snarky little entity that "keeps" the time. So it "keeps time" by keeping track of what time it is, but sometimes it sleeps, and keeps the time from you that way, and sometimes it sleeps and refuses to wake up. I wanted to capture this sense of time being out of your control, something that seems to act on its own accord. And I think that although this is rather apparent to children, it's something we tend to forget as we grow older.

I think I made the right choice following the whim that lead down this hole. It has some liveliness to it, and I think the tick tock animation at the top was a good touch. I personally think it's fun to interact with, especially if you had this as a small app on your mobile device. It doesn't involve much more than basic javascript functions, and my style ended up being guided by what I could figure out in p5.js. The color scheme is an attempt at something, but the success of that attempt is questionable. The binary representation with the fingers was done more out of practicality than purpose, but it contributes to the frustration I intended the viewer to have with the small creature. Whether that frustration translates to anything, I can't say.

Future Work:

  • make Bert into a mobile app
  • animate his hands going up and down
  • animate his mouth

Sketches:

Code:

var r = 175;
var cx,cy;
var e = 60;
var bop = 3;
var state; //"sleep","snark"
var nappyTime = [1,8];
var snarkTime = [8,9];
var funTime = [2,34,60];
var bodyColor = '#f7786b';
var clicked;
var snarked;
 
var H, M, S, mil;
 
function setup() {
  createCanvas(400,600);
  cx = width/2;
  cy = height;
  console.log("setup complete");
  state = "sleep";
  colorBody();
  clicked = false;
  var snarked = false;
}
 
function draw() {
  H = hour();
  M = minute();
  S = second();
  mil = millis();
  background('#00f5eb');
  //debug();
  if (H==funTime[0] && M==funTime[1])
    party();
  updateState();
  drawBert();
  drawText();
  if (snarked)
    snark();
}
 
function debug(){
  text((S >>> 0).toString(2),width/2, 100);
  text(H + ":" + M + ":" + S ,width/2, 120);
  text(bin(H,2) ,width/2, 140);
}
 
function drawText(){
  var def= "This is a \n BERT-O1-CLOCK.\nHe keeps the time."
  var sleep = "Bert is asleep right now. \nI wonder when he'll wake up...\n Maybe you should poke him?";
  var wake = "He's a 1's and 0's\n kind of guy. Have fun.";
  textFont("Courier New");
  stroke('#fdff5c'); fill('#fdff5c');
  //colorBody();
  textSize(30);
  textAlign(CENTER);
  text(def, width/2, height/5);
 
  stroke('#0'); fill('#0');
  textSize(20);
  if (state=="sleep" || (state=="snark" && !snarked)){
    text(sleep, width/2, height/2);
  }
  else{
    text(wake, width/2, height/2 - 50);
  }
 
  if(S%2==1)
    text("tick", 60,60);
  else
    text("tock", width-60, 60);
 
}
 
function colorBody(){
  fill('#f7786b');
    //fill('#ff5147');
  //fill(255,153,153);
}
 
function getTime(){
  return [hour(), minute(), second()];
}
 
function snark(){
  stroke(255); fill(255);
  textSize(20);
  var snark = "BERT-O1-CLOCK wakes up \n when he damn well pleases."
  text(snark, width/2,height/2);
  snarked = true;
}
 
 
function updateState(){
  var t = getTime();
  var yay = false;
  if (nappyTime[0]<=t[0] && t[0]<=nappyTime[1]){
    if(!clicked)
      state = "sleep";
      snarked = false;
  }
  else if (snarkTime[0]<=t[0] && t[0]<=snarkTime[1]){
    state = "snark";
  }
  else{
    state = "wake";
    snarked = false;
  }
  console.log(state);
}
 
function mousePressed(){
  console.log("click");
  if (state=="wake")
    state="sleep";
  else if (state=="snark"){
    if (!snarked)
      snark();
    else
      snarked = false;
  }
  else
    state="wake";
  clicked = true;
}
 
function party(){
  push();
  background('#f000eb');
  textSize(45);
  textStyle(BOLD);
  colorBody();
  text("IT IS THE HOUR",width/2,60);
  stroke(255); fill(255);
  text("IT IS THE HOUR",width/2+5,60+5);
  rotate(PI/4);
  translate(width/2,-height/2);
  pop();
}
 
 
function calcBop(){
  var t = map(mil, 0, 999, 0, 1);
  var yPos = map(cos(t * TWO_PI), -1, 1, 0, bop);
  translate(0,yPos);
}
 
function drawBert(){
  if (state=="wake")
    drawHands();
  push();
    calcBop();
    drawBody();
  pop();
}
 
function drawBody(){
  //draw boi
  noStroke();
  colorBody();
  ellipse(cx, cy, 2*r, 2*r);
  //draw eyes
  drawEyes();
  drawMouth();
  //nose
  stroke(255);
  strokeWeight(5);
  colorBody();
  var nose = 100;
  arc(cx,cy-r/2+10,nose/2,nose,0,PI);
}
 
function drawEyes(){
  if (state=="wake"){
    noStroke();
    fill(255);
    ellipse(cx-r/2, cy-r/2, e, e/2);
    ellipse(cx+r/2, cy-r/2, e, e/2);
    fill(0);
    ellipse(cx-r/2, cy-r/2, e/2, e/2);
    ellipse(cx+r/2, cy-r/2, e/2, e/2);
  }
  else{
    stroke(255);
    strokeWeight(5);
    noFill();
    arc(cx-r/2, cy-r/2, e, e/2, 0, PI);
    arc(cx+r/2, cy-r/2, e, e/2, 0, PI);
  }
}
 
 
//add to this
function drawMouth(){
  //mouth
  stroke(255);
  strokeWeight(5);
  fill(255);
  if (state=="wake")
    ellipse(cx,cy-r/4+10, r, r/10);
  else
    line(cx-r/4,cy-r/4,cx+r/4,cy-r/4);
 
}
 
function drawHands(){
  rectMode(CENTER);
  noStroke();
      colorBody();
  //left
  push();
  translate(cx-r/3,cy);
  drawHand(1,2); //hr1
  translate(-r/3-10, 0);
  drawHand(1,3); //hr2
  pop();
  //right
  push();
  translate(cx+r/3,cy);
  drawHand(-1, 1);  //min2
  translate(r/3+10,0);
  drawHand(-1, 0); //min1
  pop();
}
 
function bin(p, i){
  var b = (p >>> 0).toString(2);
  if (i >= b.length)
    return '0';
  else
    return b.charAt(b.length-i-1);
}
 
var cap = 10;
var w = 50;
var fw = 10; //finger width
var fcap = 5;
var fl = 60;
var arml = r*3
function drawHand(side, place=5){
  //place=0 - min1
  //place=1 - min2
  //place=2 - hr
  colorBody();
  //arm
  rect(0, 0, w, arml, cap);
  switch (place) {
    case 0:
      drawFinger(3, bin(M,3)==1);
      drawFinger(2, bin(M,2)==1);
      drawFinger(1, bin(M,1)==1);
      drawFinger(0, bin(M,0)==1);
      break;
    case 1:
      drawFinger(3, bin(M,7)==1);
      drawFinger(2, bin(M,6)==1);
      drawFinger(1, bin(M,5)==1);
      drawFinger(0, bin(M,4)==1);
      break;
    case 2:
      drawFinger(3, bin(H,3)==1);
      drawFinger(2, bin(H,2)==1);
      drawFinger(1, bin(H,1)==1);
      drawFinger(0, bin(H,0)==1);
      break;
    case 3:
      drawFinger(3, bin(H,7)==1);
      drawFinger(2, bin(H,6)==1);
      drawFinger(1, bin(H,5)==1);
      drawFinger(0, bin(H,4)==1);
      break;
    case 4:
      drawFinger(3, bin(S,3)==1);
      drawFinger(2, bin(S,2)==1);
      drawFinger(1, bin(S,1)==1);
      drawFinger(0, bin(S,0)==1);
      break;
    default:
      drawFinger(3);
      drawFinger(2);
      drawFinger(1);
      drawFinger(0);
      break;
  }
  //thumb
  push();
  translate(side*w/2,fw-arml/2);
  rotate(-PI/2);
  rect(0,0, fw, fl/2, fcap);
  pop();
}
 
function drawFinger(n,up=true) {
  colorBody();
  noStroke();
  var yPos = -arml/2;
  if (!up) 
    yPos=yPos + 2*fl/5;
  switch(n){
    case 3:
      rect(-w/2+fw/2, yPos, fw, fl, fcap);
      break;
    case 2:
      rect(-w/4+fw/2, yPos, fw, fl, fcap);
      break;
    case 1:
      rect(w/4-fw/2, yPos, fw, fl, fcap);
      break;
    case 0:
      rect(w/2-fw/2, yPos, fw, fl, fcap);
      break;
    default:
      fill(0);
      elllipse(width/2,height/2,100,100);
  }
}