I saw this a little while back so this week I coded it using p5:
A nice bit of modular JS too, so it was:
Clock.js
export class Clock { constructor(p5, x, y, width, multiplier) { this.degrees = 8 * multiplier this.ticker = false this.p5 = p5 this.x = x this.y = y this.width = width this.arm = 0.85 this.minute = 0 this.hour = 0 this.pg = p5.createGraphics(width, width) } update(minute, hour) { if(this.minute !== minute) { if(this.minute + 1 === this.degrees){ this.minute = 0 } else { this.minute++ } } if(this.hour !== hour) { if(this.hour - 1 < 0){ this.hour = this.degrees } else { this.hour-- } } return this.draw() } draw() { this.pg.noStroke() this.pg.fill(255) this.pg.rect(0, 0, this.width, this.width) this.pg.stroke(0) this.pg.strokeWeight(this.width * 0.1) let m = this.p5.map( this.minute, 0, this.degrees, 0, this.p5.TWO_PI ) - this.p5.HALF_PI let h = this.p5.map( this.hour, 0, this.degrees, 0, this.p5.TWO_PI ) - this.p5.HALF_PI this.pg.line( this.width / 2, this.width / 2, (this.width / 2) + this.p5.cos(m) * ((this.width / 2) * this.arm), (this.width / 2) + this.p5.sin(m) * ((this.width / 2) * this.arm) ) this.pg.line( this.width / 2, this.width / 2, (this.width / 2) + this.p5.cos(h) * ((this.width / 2) * this.arm), (this.width / 2) + this.p5.sin(h) * ((this.width / 2) * this.arm) ) return this.pg } }
Numeral.js
import { Clock } from "./Clock.js" export class Numeral { constructor(p5, x, y, unitWidth = 30, degreeMuliplier = 5) { this.num = 0 this.p5 = p5 this.x = x this.y = y this.unitWidth = unitWidth this.degreeMuliplier = degreeMuliplier this.Clocks = [ new Clock(p5, x, y, unitWidth, degreeMuliplier), new Clock(p5, x + unitWidth, y, unitWidth, degreeMuliplier), new Clock(p5, x, y + unitWidth, unitWidth, degreeMuliplier), new Clock(p5, x + unitWidth, y + unitWidth, unitWidth, degreeMuliplier), new Clock(p5, x, y + (unitWidth * 2), unitWidth, degreeMuliplier), new Clock(p5, x + unitWidth, y + (unitWidth * 2), unitWidth, degreeMuliplier) ] this.Numbers = [ [[2,4],[4,6],[0,4],[0,4],[0,2],[0,6]], [[5,5],[4,4],[5,5],[0,4],[5,5],[0,0]], [[2,2],[4,6],[2,4],[0,6],[0,2],[6,6]], [[2,2],[4,6],[2,2],[0,6],[2,2],[0,6]], [[4,4],[4,4],[0,2],[0,4],[5,5],[0,0]], [[2,4],[6,6],[0,2],[4,6],[2,2],[0,6]], [[2,4],[6,6],[0,4],[4,6],[0,2],[0,6]], [[2,2],[4,6],[5,5],[0,4],[5,5],[0,0]], [[2,4],[4,6],[0,2],[0,6],[0,2],[0,6]], [[2,4],[4,6],[0,2],[0,4],[2,2],[0,6]] ] } draw(){ this.Clocks.forEach((c, i) => this.p5.image(c.update(...this.Numbers[this.num][i].map(e => e * this.degreeMuliplier)), c.x, c.y)) } }
script.js
import { Numeral } from "./Numeral.js" new p5(p5 => { const style = window.getComputedStyle(document.querySelector("body"), null) const bodyWidth = parseInt(style.getPropertyValue("width"), 10) const Numerals = [] p5.setup = () => { p5.createCanvas(bodyWidth, bodyWidth) Numerals.push(new Numeral(p5, 0, 0, 50)) Numerals.push(new Numeral(p5, 100, 0, 50)) Numerals.push(new Numeral(p5, 200, 0, 50)) Numerals.push(new Numeral(p5, 300, 0, 50)) Numerals.push(new Numeral(p5, 400, 0, 50)) Numerals.push(new Numeral(p5, 500, 0, 50)) } p5.draw = () => { const date = new Date const hour = date.getHours().toString().split('') const minutes = date.getMinutes().toString().split('') const seconds = date.getSeconds().toString().split('') Numerals[0].num = hour.length === 1 ? 0 : hour[0] Numerals[1].num = hour.length === 1 ? hour[0] : hour[1] Numerals[2].num = minutes.length === 1 ? 0 :minutes[0] Numerals[3].num = minutes.length === 1 ? minutes[0] : minutes[1] Numerals[4].num = seconds.length === 1 ? 0 :seconds[0] Numerals[5].num = seconds.length === 1 ? seconds[0] : seconds[1] Numerals.forEach(numeral => numeral.draw()) } })