I had a lot of trouble coming up with ideas, but I really liked one of the ancient time keeping tool that only tracked time to the hours. In addition I also wanted to crate a clock that can blends into the everyday routine that you shouldn't need to pay much attention to. I was then inspired by "rainy mood (https://rainymood.com/)" which I listen to while working as the rain sound can keep me calm and concentrated. Thus I decided to make this clock that is all about that. It is designed so that you don't really need to pay much attention to the visuals. For every hour that passed by, there will be a thunder sound to remind you that it's now the next hour.
I am overall satisfied with the final product. I originally imagined this to be a full scale projection that blends into a wall to create the illusion of a rainy day. However, I had to scale it down due to 1). time constraints and 2). the style of computer graphics might not be the best to create that illusion(?).
Sketch:
var rain = []; var offset = 30; var s; var m; var h; var preH=-1; var sizeY = 10; var sizeO = 9; function preload() { rainSound = loadSound("rain.ogg"); thunder = loadSound("thunder.ogg"); } function setup() { createCanvas(500,500); frameRate(30); rainSound.loop(); } function draw() { drawBackground(); s = second(); m = minute(); h = hour(); if (h != preH){ thunder.play(); preH=h; } if (frameCount % 10 == 0){ createNewDrop(); } push(); for (var elem=0; elem < rain.length; elem++){ rain[elem].move(); if (rain[elem].bound() && elem != rain.length-1){ rain.splice(elem,1); } rain[elem].render(); } pop(); drawWall(); drawCandle(); } function drawCandle(){ //plate push(); translate(width*2/3-20, height*2/3-20); fill("lightpink"); noStroke(); rect(-80,0,160,7); ellipse(0,7,160,20); fill("pink"); ellipse(0,0,160,20); pop(); push(); translate(width*2/3-20, height*2/3-20); noStroke(); fill("offWhite"); if(h < 12){// candle length mapped to miuntes && burn for 12h each //candle1 var c1 = map(h*60+m, 0, 720, -60, -5); ellipse(-30,c1-3,50,10); rect(-55,c1-3,50,-c1); ellipse(-30,-3,50,10);//stationary stroke(0); strokeWeight(2); line(-30,c1-3,-30,c1-7); drawFire(-30,c1-7); //candle2 noStroke(); ellipse(25,-58,50,10); rect(0,-58,50,60); ellipse(25,2,50,10);//stationary stroke(0); strokeWeight(2); line(25,-58,25,-62); } else { ellipse(-30,-8,50,10); rect(-55,-8,50,5); ellipse(-30,-3,50,10);//stationary stroke(100); strokeWeight(2); line(-30,-8,-30,-12); var c2 = map(h%12*60+m, 0, 720, -60, -5); noStroke(); ellipse(25,c2+2,50,10); rect(0,c2+2,50,-c2); ellipse(25,2,50,10);//stationary stroke(0); strokeWeight(2); line(25,c2+2,25,c2-2); drawFire(25,c2-2); } pop(); } function drawFire(x,y){ push(); translate(x,y); noStroke(); fill(225,243,94,100); if (s%2 == 0){ sizeY += 0.5; sizeO += 0.1; } else{ sizeY -= 0.5; sizeO -= 0.1; } ellipse(0,-4,8,sizeY); fill(231,122,19,200); ellipse(0,-3,7,sizeO); fill(241,60,47,240); ellipse(0,-2,4,7); pop(); } function drawBackground(){ background(150); var r0 = 0; var g0 = 76; var b0 = 153; var r1 = 70; var g1 = 130; var b1 = 180; for (var i=0; i < 30; i++){ noStroke(); var r = map(i,0,30,r0,r1); var g = map(i,0,30,g0,g1); var b = map(i,0,30,b0,b1); fill(r,g,b); rect(0,i*10,width/2+offset*2-5,10); } } function drawWall(){ push(); fill( 251, 241, 224); noStroke(); rect(width/2+offset*2,0,width/2+30,height); rect(0,height*2/3-38,width,height/2); push(); // fill(245,232,202); fill(220,210,180); translate(width/2+offset*2,0); quad(0,0,20,0,20,299,0,290); pop(); push(); fill(255,250,250); translate(0,height*2/3-45); quad(0,0,width/2+75,0,width/2+80,10,0,10); pop(); pop(); drawFrame(); } function drawFrame(){ push(); fill(92,53,33); noStroke(); quad(width/2+offset*2-5,0,width/2+offset*2+15,0, width/2+offset*2+15,height*2/3-45,width/2+offset*2-5,height*2/3-60);//right fill(97,62,38); quad(0,height/2+23,width/2+offset*2-5,height/2+23, width/2+offset*2+16,height/2+39,0,height/2+39);//bottom pop(); drawStand(); drawFlower(); drawBucket(); } function drawBucket(){ push(); translate(50,height*0.8); strokeWeight(5); stroke(80); noFill(); ellipse(0,0,160,20); push(); strokeWeight(10); stroke(161,122,99); strokeJoin(ROUND); beginShape(); curveVertex(60,-60); curveVertex(60,-60); curveVertex(70,-90); curveVertex(78,-100); curveVertex(90,-103); curveVertex(100,-100); curveVertex(104,-94); curveVertex(105,-90); curveVertex(105,-85); curveVertex(103,-85); endShape(); //umbrella noStroke(); scale(1.5); translate(-25,0); fill(119,191,225); triangle(40,-50,70,-40,0,200); fill(107,172,229); triangle(45,-50,75,-40,0,200); fill(115,185,247); triangle(50,-50,80,-40,0,200); fill(117,199,252); triangle(60,-48,80,-42,0,200); fill(115,185,247); triangle(70,-44,90,-35,0,200); pop(); line(80,0,70,100); line(80,0,70,5); line(70,5,60,8); line(60,8,52,100); line(60,8,50,9); line(50,9,40,9.5); line(40,10,35,100); line(40,9.5,20,9.5); line(20,10,18,100); line(20,9.5,10,9.5); line(0,10,0,100); line(-20,10,-18,100); line(-40,9,-35,100); pop(); } function drawStand(){ push(); translate(width/3-20,height/2+offset*2); noStroke(); fill(216,200,225); quad(20,0,380,0,400,30,0,30); fill(216,191,216); rect(0,30,400,15); fill(201,186,209); rect(10,45,380,250); //drawer1 fill(220,204,209); quad(50,60,430,60,420,70,55,70); quad(55,130,430,130,430,135,50,135); fill(242,224,230); quad(50,60,55,70,55,130,50,135); //drawer2 fill(220,204,209); quad(50,160,430,160,420,170,55,170); fill(242,224,230); quad(50,160,55,170,55,230,50,240); pop(); } function drawFlower(){ push(); //draw stem translate(width/2+170,height/3+25); stroke(52,131,34); strokeWeight(4); line(-20,-100,55,128); line(5,-30,10,-50); line(10,-50,50,-90); line(10,-50,12,-90); line(23,30,60,-40); line(10,-9,-70,-60); line(-33,-35,-60,-20); line(-20,-100,-50,-120); line(-20,-100,-20,-130); //draw buds noStroke(); fill(220,182,225); star(10,-50, 10, 20,7); star(50,-90, 13, 25,7); star(12,-90, 13, 25,7); star(60,-40, 13, 25,7); star(-70,-60, 13, 25,7); star(-33,-35, 10, 20,7); star(-50,-120, 10, 20,7); star(-25,-80, 13, 25,7); star(-15,-115, 13, 25,7); star(0,-15, 13, 25,7); star(-60,-20, 10, 20,7); fill("offwhite"); ellipse(10,-50,7); ellipse(50,-90,7); ellipse(12,-90,7); ellipse(60,-40,7); ellipse(-70,-60,7); ellipse(-33,-35,7); ellipse(-50,-120,7); ellipse(-25,-80,7); ellipse(-15,-115,7); ellipse(0,-15,7); ellipse(-60,-20,7); pop(); //draw vessel push(); fill(198,228,255,200); noStroke(); rect(width/2+170,height/3+25,60,130); ellipse(width/2+200,height/3+155,60,10); pop(); } function createNewDrop(){ for (var i = 0; i < 10; i++){ var newDrop = new rainDrop(int(random(-20,width/2+offset*2)), int(random(-20,height/3))); rain.push(newDrop); } } function rainDrop(x, y){ this.x = x; this.y = y; this.s = 1; this.pos = [[this.x, this.y]]; this.velX = int(random(1,3)); this.velY = 2; this.render = function(){ stroke(204,229,255); if (this.pos.length == 1) { ellipse(this.x, this.y, this.s, this.s); } else { for (var i=1; i<this.pos.length; i++){ strokeWeight(this.s); line(this.pos[i-1][0], this.pos[i-1][1], this.pos[i][0], this.pos[i][1]); } } } this.move = function() { this.x += this.velX; this.y += this.velY; this.pos.push([this.x, this.y]); if (random() < 0.8){ this.velX = int(random(2)); } else { this.velX = int(random(-2,3)); } this.checkLength(); } pop this.checkLength = function() { if (this.pos.length > 15){ this.pos.shift(0); } } this.bound = function() { if (this.pos[0][0] > width/2+offset*2 || this.pos[0][1] > height*2/3-38){ return true; } else { return false; } } } //taken from:https://p5js.org/examples/form-star.html function star(x, y, radius1, radius2, npoints) { var angle = TWO_PI / npoints; var halfAngle = angle/2.0; beginShape(); for (var a = 0; a < TWO_PI; a += angle) { var sx = x + cos(a) * radius2; var sy = y + sin(a) * radius2; vertex(sx, sy); sx = x + cos(a+halfAngle) * radius1; sy = y + sin(a+halfAngle) * radius1; vertex(sx, sy); } endShape(CLOSE); } |