Home | Math art in code | Spinning Clock
Page by Murray Bourne, IntMath.com. Last updated: 28 Jan 2019Spinning Clock
Last updated: 28 January 2019.
This mesmerising rotating clock is made with CSS and javascript.
Code outline
Numbers for the hours, minutes and seconds are contained in DIV elements which are rotated around the center of the circle.
There are various classes assigned to the DIVs, and these do the heavy lifting as far as the rotations and opacity is concerned. Here's a typical example:
.spinner_m2_1{transform:rotate( 324deg )}
and
.num div{transition: transform 500ms ease-out, color 500ms ease-out, font-size 500ms ease-out}
In the javascript, the classes are swapped in and out appropriately using code such as:
case "spinner_h1_2": rem_class("spinner_h1", "spinner_h1_2"); add_class("spinner_h1", "spinner_h1_switch");
The complete javascript
var today = new Date(); var sRem = today.getSeconds(); //These functions help add, remove or toggle css classes function tog_class(id, cl) { var elem = document.getElementById(id); if (elem == null) { return 0; } if (elem.classList.contains(cl) === true) { elem.classList.remove(cl); } else { elem.classList.add(cl); } } function add_class(id, cl) { var elem = document.getElementById(id); if (elem == null) { return 0; } if (elem.classList.contains(cl) !== true) { elem.classList.add(cl); } } function rem_class(id, cl) { var elem = document.getElementById(id); if (elem == null) { return 0; } if (elem.classList.contains(cl) === true) { elem.classList.remove(cl); } } //This function gets the date and does operations using H/M/S function startTime() { today = new Date(); var s = today.getSeconds(); if( sRem != s) { var h = today.getHours(); var m = today.getMinutes(); var h1 = (h - h % 10) / 10; var h2 = h % 10; var m1 = (m - m % 10) / 10; var m2 = m % 10; var s1 = (s - s % 10) / 10; var s2 = s % 10; set_spin_class("s1", s1); set_spin_class("s2", s2); set_spin_class("m1", m1); set_spin_class("m2", m2); set_spin_class("h1", h1); set_spin_class("h2", h2); } window.requestAnimationFrame(startTime); sRem = s; } //This function calls the appropriate class changes // It receives the type of spinner to change (m1 for example) and changes classes based on the current time function set_spin_class(target, val) { for (i = 0; 10 > i; i++) { if (i != val) { rem_class("spinner_" + target, "spinner_" + target + "_" + i); rem_class("num_" + i + "_" + target, "lit"); } } add_class("spinner_" + target, "spinner_" + target + "_" + val); add_class("num_" + val + "_" + target, "lit"); if (val === 0) { deswitcher(target, val); } } function switcher(target, val) { switch ("spinner_" + target + "_" + val) { case "spinner_h1_2": rem_class("spinner_h1", "spinner_h1_2"); add_class("spinner_h1", "spinner_h1_switch"); break; case "spinner_h2_9": rem_class("spinner_h2", "spinner_h1_2"); add_class("spinner_h2", "spinner_h2_switch"); break; case "spinner_m1_5": rem_class("spinner_m1", "spinner_m1_5"); add_class("spinner_m1", "spinner_m1_switch"); break; case "spinner_m2_9": rem_class("spinner_m2", "spinner_m2_9"); add_class("spinner_m2", "spinner_m2_switch"); break; case "spinner_s1_5": rem_class("spinner_s1", "spinner_s1_5"); add_class("spinner_s1", "spinner_s1_switch"); break; case "spinner_s2_9": rem_class("spinner_s2", "spinner_s2_9"); add_class("spinner_s2", "spinner_s2_switch"); break; } } function deswitcher(target, val) { rem_class("spinner_" + target, "spinner_" + target + "_switch"); } //Kicks it off window.onload = function() { startTime(); };
Credit
The original script is by Stefanescu Lucian, source: CodePen. I made small changes to the CSS so that it would work within a DIV element, rather than within an entire HTML page, as per the original design, and to change colors.
There was an occasional jerky motion where the clock paused then had to "catch up", so I changed the use of setInterval
to window.requestAnimationFrame
.