.clock {
  border: 3px solid grey;
  height: 20em;
  width: 20em;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1em;
}
.needle {
  width: 120px;
  border-top: 2px solid grey;
  position: absolute;
  left: 0;
}
.needle {
  transform-origin: left;
}
.second-needle {
  width: 9em;
}
.hour-needle {
  width: 7em;
}
.minute-needle {
  width: 8em;
}
.dot {
  width: 8.8em;
  border-right: 0.2em solid grey;
  height: 2px;
  position: absolute;
  left: 0;
  transform-origin: left;
}
.dot.highlight {
  width: 8.6em;
  border-right: 0.4em solid grey;
}

.clock-center {
  position: relative;
  height: 1px;
  width: 1px;
  box-sizing: content-box;
  border: 20px solid grey;
  border-radius: 50%;
  background-color: grey;
}
const template = `
<template id="clock-template">
<div class="clock-wrapper">
  <div class="clock">
    <div class="clock-center">
      <div class="hour-needle needle"></div>
      <div class="minute-needle needle"></div>
      <div class="second-needle needle"></div>
    </div>
  </div>
</div>
</template>
`;

class Clock {
  constructor(wrapper, size) {
    this.wrapper = wrapper || document;
    this.size = size || "medium";
    this.sizeMap = {
      large: "1.5em",
      medium: "1em",
      small: ".8em"
    };
    this.fragment = document.createRange().createContextualFragment(template);
    document.body.appendChild(this.fragment);
    this.fragment = document.querySelector("#clock-template") || this.fragment;
    //  document.body.append(template);
    this.render();
  }
  addButtons() {
    const btnWrapper = document.createElement("div");
    const ele = document.createElement("button");
    ele.classList.add("buton");
    for (const key of Object.keys(this.sizeMap)) {
      let b = ele.cloneNode();
      b.innerHTML = key;
      btnWrapper.appendChild(b);
      b.addEventListener("click", () => {
        this.updateSize(key);
      });
    }
    this.wrapper.prepend(btnWrapper);
  }
  updateSize(size) {
    const sizeMap = this.sizeMap;
    const clockWrapper = this.wrapper.querySelector(".clock-wrapper");
    clockWrapper.style.fontSize = sizeMap[size] || sizeMap[this.size] || "1em";
  }

  render() {
    this.addDots();
    this.startClock();
    this.addButtons();
    this.updateSize();
  }
  startClock() {
    const hourNeedle = this.wrapper.querySelector(".hour-needle");
    const secondNeedle = this.wrapper.querySelector(".second-needle");
    const minuteNeedle = this.wrapper.querySelector(".minute-needle");
    const time = document.createElement("div");
    this.wrapper.append(time);
    setInterval(() => {
      const date = new Date();
      const seconds = date.getSeconds();
      const minutes = date.getMinutes();
      const hours = date.getHours() % 12;
      secondNeedle.style.transform = `rotate(${
        Math.floor((seconds * 360) / 60) - 90
      }deg)`;
      minuteNeedle.style.transform = `rotate(${
        Math.floor(((minutes * 60 + seconds) * 360) / 3600) - 90
      }deg)`;
      const hourAngle = Math.floor(((hours * 60 + minutes) * 360) / 720) - 90;
      hourNeedle.style.transform = `rotate(${hourAngle}deg)`;
      time.innerHTML = `Time is ${hours}:${minutes}:${seconds}`;
    }, 500);
  }
  addDots() {
    let template = this.fragment.content.cloneNode(true);
    const center = template.querySelector(".clock-center");
    const fragment = document.createDocumentFragment();
    const dot = document.createElement("div");
    dot.classList.add("dot");
    for (let i = 0; i < 60; i++) {
      let d = dot.cloneNode(true);
      let turnAngle = i * 6 - 90;
      if (i % 5 === 0) d.classList.add("highlight");
      d.style.transform = `rotate(${turnAngle}deg)`;
      fragment.append(d);
    }
    center.appendChild(fragment);
    this.wrapper.appendChild(template);
  }
}

//export default Clock;

/** */
let clock = new Clock(document.body);

// setTimeout(() => {
//   clock.updateSize("small");
// }, 2000);
//console.log(clock);
View Compiled
Run Pen

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.