xxxxxxxxxx
150
//Study on a special large date complications
//from A. Lange & Sohne
//https://www.youtube.com/watch?v=YouzFPSD77o
//NEW: This version adds a cheap and cheerful animation related
//to PID control and Ben Fry's Integrator class
//TODO: figure out wrapping rotation for animation so wheels don't rewind
let dial,
ones,
tens
alphaDial = true;
//NEW: Variables store a rotation position and target for each disc
let onesR = 0.0,
tensR = 0.0,
onesTarget = 0.0,
tensTarget = 0.0;
let now = new Date();
//let day = now.getDate();
let day = 1;
function setup() {
createCanvas(600, 600);
createDial();
createDiscs();
}
function draw() {
background(32);
stroke(255,0,0);
strokeWeight(10);
imageMode(CENTER);
noTint();
let onesPlace = day % 10;
push();
translate(width/2, height/2);
//Calculate where we want the disc to be:
onesTarget = -(onesPlace-3) * TWO_PI/10.0;
//Then update the disc position to move towards that target, but no all the way at once:
onesR += (onesTarget - onesR) /10.0;
rotate(onesR);
image(ones, 0, 0);
pop();
let tensPlace = int(day/10);
push();
translate(240, 240);
tensTarget = -tensPlace * TWO_PI/4.0;
tensR += (tensTarget - tensR) /10.0;
rotate(tensR);
image(tens, 0, 0);
pop();
//Overlay the dial:
if (alphaDial) tint(255, 255, 255, 120);
image(dial, width/2, height/2);
//Some alignment/layout helper marks to toggle off when done
strokeWeight(1);
stroke(255, 255, 0, 120);
//line(width/2, 0, width/2, height);
//line(mouseX, 0, mouseX, height);
//line(0, mouseY, width, mouseY);
}
function createDial() {
dial = createGraphics(400,400);
dial.fill(200);
dial.rect(0,0,400,400);
dial.fill(180,150,130);
dial.noStroke();
dial.rectMode(CENTER);
dial.rect(200,65,220,120); //frame
dial.blendMode(REMOVE); //will "punch out" following shapes
dial.fill(255,255,255,255);
dial.rect(152,65, 80, 90); //holes
dial.rect(248,65, 80, 90); //holes
}
function createDiscs() {
let onesD = 400;
ones = createGraphics(onesD, onesD);
ones.fill(255);
ones.noStroke();
ones.ellipse(onesD/2, onesD/2, onesD, onesD);
ones.fill(0);
ones.textSize(120);
ones.textAlign(CENTER);
ones.textFont("Times New Roman");
ones.push();
ones.translate(onesD/2, onesD/2);
for (let i = 0; i<10; i++) {
ones.push();
ones.rotate(i*TWO_PI/10);
ones.translate(-onesD/2*0.71, 0);
ones.rotate(-1.89); //eyeballed!
ones.text(i, 0, 40);
//ones.rect(0,0,20,60); //I had trouble getting oriented in these transforms so added a little visual anchor
ones.pop();
}
ones.pop();
ones.blendMode(REMOVE); //will "punch out" following shapes
ones.fill(255,255,255,255);
ones.ellipse(onesD/2, onesD/2, onesD/2*0.9, onesD/2*0.9)
//Tens Cross
let tensD = 260;
tens = createGraphics(tensD,tensD);
tens.fill(255);
tens.noStroke();
tens.ellipse(tensD/2, tensD/2, tensD, tensD);
tens.textSize(120);
tens.textAlign(CENTER);
tens.textFont("Times New Roman");
tens.fill(0,0,0);
for (let i=0; i<4; i++) {
tens.push();
tens.translate(tensD/2, tensD/2);
tens.rotate(i * PI/2);
tens.blendMode(BLEND);
tens.text(i, 13, -36);
tens.blendMode(REMOVE);
tens.rect(60,-30,100,-100);
tens.pop();
}
//temp buffer for storing result so we can make a shadow
let top = createGraphics(tensD, tensD);
//save what we've done so far into top
top.copy(tens, 0, 0, tensD, tensD, 0, 0, tensD, tensD);
//blur what we've done - this blurs the text too but makes a kind of drop shadow
tens.filter(BLUR, 8);
//copy the original unblurred layer back
tens.copy(top, 0, 0, tensD, tensD, 0, 0, tensD, tensD);
}
function keyPressed() {
if (key=='d') {
day++;
if (day>31) day=1;
}
if (key=='a') alphaDial = !alphaDial;
}