DEV Community

Dominic Myers
Dominic Myers

Posted on • Originally published at drmsite.blogspot.com on

p5 Clock (HUMANS SINCE 1982)

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
  }
}
Enter fullscreen mode Exit fullscreen mode

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))
  }
}
Enter fullscreen mode Exit fullscreen mode

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())
  }
})
Enter fullscreen mode Exit fullscreen mode

Top comments (0)