xxxxxxxxxx
/* engineer: jWilliamDunn 2023.1105
What if there was a clock where the 'hour-hand' indicates
the month and the 'minute-hand' points to the day?
where Jan 1 00:00 = hands of clock point straight up
Seasons are rounded to quarters [e.g. northern winter = 0° to 90°]
2024.0929: add scaling to respond to screen size
*/
let x = 170,
y = 150,
feb = 28,
showNum = false, side, sf=1.0,
yrVal, lYAbV = 0,
pal=[["hsl(204,100%,36%)","hsl(204, 100%, 22%)"], // winter
["hsl(120,100%,36%)","hsl(120, 100%, 22%)"], // spring
["hsl(0,100%,36%)","hsl(0, 100%, 22%)"], // summer
["hsl(40,100%,36%)","hsl(40, 100%, 22%)"]], // autumn
pdx;
// Minimal [MUCH faster] version of map() with no parameter checking [only 3 steps vs 378 steps]
p5.prototype.map2 = function(n, start1, stop1, start2, stop2) {
return ((n - start1) / (stop1 - start1)) * (stop2 - start2) + start2;
};
function setup() {
side = min(windowWidth, windowHeight);
//scaling factor if side is less than 800
sf = side>=800?1.0:side/800.0;
createCanvas(windowWidth, windowHeight);
pixelDensity(2);
strokeCap(SQUARE);
angleMode(DEGREES);
noLoop();
setInterval(loop, 1000); // no need to run continuously
textSize(22);
}
function draw() {
let hr = hour(),
mn = minute(),
dy = day(),
mh = month(),
yr = year(),
dLimit = 30;
background(0);
///////////////////////////////////////
// test a month,day,hour,minute combo
//mh=1,dy=16,hr=13,mn=45;
///////////////////////////////////////
//adjust for leap years
yrVal = yr / 4;
lYAbV = yrVal % 1;
if (lYAbV == 0) feb = 29;
// 2024.0229 stackoverflow.com/questions/73712418/leap-year-solution-check
if(new Date(yr, 1, 29, 12, 0, 0).getMonth() === 1) feb = 29;
//apply day limits depending on the current month
if (mh == 1 || mh == 3 || mh == 5 || mh == 7 || mh == 8 || mh == 10 || mh == 12) dLimit = 31;
if (mh == 2) dLimit = feb;
//shift to zero index for month and day
mh--, dy--;
//set up seasonal palette index
pdx = floor(mh / 3);
push();
translate(width / 2, height / 2);
rotate(-90); // set the start of rotation to the top of the screen
scale(2);
scale(sf);
strokeWeight(4);
noFill();
//gray HOUR arc ------------------------------------
stroke(60);
let endH = map2(hr + mn / 60, 0, 24, 0, 360);
arc(0, 0, 290, 290, 0, endH);
//hour hand
push();
rotate(endH);
line(0, 0, 100, 0);
pop();
//darker color DAY arc ------------------------------------
stroke(pal[pdx][1]);
let endD = map2(dy + hr / 24 + mn / 60 / 24, 0, dLimit, 0, 360);
arc(0, 0, 310, 310, 0, endD);
//day hand
strokeWeight(4);
push();
rotate(endD);
line(0, 0, 120, 0);
pop();
//lighter color MONTH arc ------------------------------------
stroke(pal[pdx][0]);
let endMh = map2(mh + dy / dLimit + hr / 24 / dLimit, 0, 12, 0, 360);
arc(0, 0, 330, 330, 0, endMh);
//month hand
push();
rotate(endMh);
line(0, 0, 80, 0);
pop();
// minute dot
t = (mn + second() / 60) * TAU / 60;
v = p5.Vector.fromAngle(t);
v.mult(136);
//line(0, 0, v.x, v.y);
noStroke();
fill(120);
circle(v.x, v.y, 5);
//center cap
fill(60);
strokeWeight(0);
ellipse(0, 0, 6, 6);
strokeWeight(8);
pop();
// Conditionally display digits
if (showNum) {
let prem = '',
pres = '';
if (minute() < 10) prem = '0';
if (second() < 10) pres = '0';
noStroke();
fill(map2(mouseY,0,800, 255,0));
text(month() + "/" + day() + " " + hour() + ":" + prem + minute() + ":" + pres + second(), 20, 40);
translate(width / 2, height / 2);
push();
scale(sf);
strokeWeight(3);
stroke(60);
noFill();
for (let i = 0; i < 12; i++) {
line(278, 0, 286, 0);
rotate(30);
}
strokeWeight(1);
for (let j = 0; j < 4; j++) {
rotate(6);
for (let i = 0; i < 12; i++) {
line(278, 0, 286, 0);
rotate(30);
}
}
pop();
}
noLoop(); // after an update, go back to sleep
}
function mouseClicked(){
showNum = !showNum;
loop();
}
function mouseMoved(){
loop();
}
windowResized=_=>{
side = min(windowWidth, windowHeight);
sf = side>=800?1.0:side/800.0;
resizeCanvas(windowWidth, windowHeight);
};
/*
potentially use the following in the future for season calc?
const today = new Date();
const dayOfYear = Math.floor((today - new Date(today.getFullYear(), 0, 0)) / 86400000);
console.log(dayOfYear);
*/