It's a proper clock! The hands fill up to one end, then empty, then it all starts again.

The period is 60 seconds for the small hand, and 60 minutes for the big hand, so it matches a standard clock.
This commit is contained in:
Christian Lawson-Perfect 2025-03-17 09:51:42 +00:00
parent 6ddcc2f893
commit 2c7badf010
2 changed files with 23 additions and 17 deletions

View file

@ -7,6 +7,8 @@ const rules = {
"B": "-AF+BFB+FA-",
};
steps = Math.min(steps,5); // make sure I don't type a huge number that crashes my PC
let s = "A";
for(let i=0;i<steps;i++) {
let ns = "";
@ -52,7 +54,7 @@ for(let curve of curves) {
curve.setAttribute('stroke-dasharray',`${length} ${length}`);
curve.setAttribute('d',d);
}
document.getElementById('dots').setAttribute('stroke-width',width*0.4);
document.getElementById('dots').setAttribute('stroke-width',width*0.3);
document.getElementById('dots').setAttribute('d',d);
document.getElementById('dots').setAttribute('stroke-dasharray',`0 ${m}`);
@ -65,21 +67,25 @@ function easeLinear(t) {
}
function frame() {
const period = 1000;
const pips = 2**(2*steps)-1;
let scale = 1;
const segments = 2**(2*steps)-1; // number of segments in the curve
const period = 1000*60/segments; // One period of the small hand is 60 seconds
let scale = segments**(curves.length-1);
curves.forEach((curve,i) => {
const dt = (new Date() - 0) / scale / period;
const m = dt % (pips);
const t = dt;
const l = (Math.floor(m) + easeInOutSine(m % 1))*length/pips;
const n = Math.max(0,easeInOutSine(t))*l;
//document.getElementById('debug').textContent = `${m.toFixed(4)} ${length} ${pips}`
curve.setAttribute('stroke-dasharray',`${l-n} ${length}`);
curve.setAttribute('stroke-dashoffset',-n);
curve.setAttribute('stroke-width',width*(easeInOutSine(t)*0.1+0.9)/2**(i+1));
const now = new Date();
const midnight = new Date(now.getFullYear(),now.getMonth(),now.getDate());
const dt = (new Date() - midnight) / scale / period;
const m = dt % (2*segments);
const t = i == 0 ? m : (Math.floor(m) + easeInOutSine(m % 1)); // linear for big hand, eased for small hand
const a = t/segments; // between 0 and 2
const b = 2*(1-Math.abs(1-a/2));
const end = Math.min(b,1)*length;
const start = Math.max(0,b-1)*length;
//document.getElementById('debug').textContent = `${m.toFixed(4)} ${length} ${segments}`
curve.setAttribute('stroke-dasharray',`${end-start} ${2*length}`);
curve.setAttribute('stroke-dashoffset',-start);
curve.setAttribute('stroke-width',width/2**(i));
scale *= pips;
scale /= segments;
})
requestAnimationFrame(frame);