<!doctype html>

<html>
  <head>
    <link rel="stylesheet" href="lib/style.css">
  </head>

  <body>
    <div class="wrapper">
	<div id="clock1" class="clock" ></div>
	<span>Toronto</span>
</div>

<div class="wrapper">
  <div id="clock2" class="clock"></div>
  <span>Tehran</span>
</div>

<div class="wrapper">
  <div id="clock3" class="clock"></div>
  <span>Phoenix</span>
</div>

<div class="wrapper">
  <div id="clock4" class="clock" ></div>
  <span>Berlin</span>
</div>

<script src="lib/script.js"></script>
  </body>
</html>
{
  "plnkr": {
    "runtime": "system"
  }
}
/* App */
.wrapper{
  display: inline-block;
  text-align:center;
  margin: 5px;
}

.clock{
  width: 210px;
  height: 210px;
}

.wrapper span {
  display: inline-block;
  font-weight: bold;
  user-select: none;
}


/* Clock */
.clockFace{
  fill: whitesmoke;
  stroke: #888;
}

.dateRect,.dateText{
  font: arial;
  stroke: red;
  stroke-width: 1;
  fill: transparent;
}
.faceGroup{
  stroke: red;
  stroke-width: 1;
}

.hourHand{
  stroke: #555;
}

.minuteHand{
  stroke: #999;
}

.secondHand{
  stroke: #a00;
}
.updateGroup {
  stroke-linecap: round;
}
class Clock {
  timeOffset;
  dateHand;
  secondHand;
  minuteHand;
  hourHand;

  constructor(container, timeOffset) {
    this.timeOffset = timeOffset;
    this.initial(container);
  }


  initial(container) {
    let rect = container.getBoundingClientRect();
    let size = Math.min(rect.height, rect.width);
    let midPoint = size / 2;

    let svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
    svg.setAttribute("width", size.toString());
    svg.setAttribute("height", size.toString());

    let clockFace = this.renderFace(midPoint);
    svg.appendChild(clockFace);

    let updateGroup = this.renderStaticElement(midPoint);
    svg.appendChild(updateGroup);


    container.appendChild(svg);

    this.update(midPoint);
    setInterval( this.update.bind(this, midPoint), 1000);
  }

  renderFace(midPoint) {

    let faceGroup = document.createElementNS("http://www.w3.org/2000/svg", "g");
    faceGroup.classList.add("faceGroup");

    let strokeWidth = (midPoint / 20);
    let clockFace = document.createElementNS("http://www.w3.org/2000/svg", "circle");
    clockFace.classList.add("clockFace");
    clockFace.setAttribute("cx", midPoint.toString());
    clockFace.setAttribute("cy", midPoint.toString());
    clockFace.setAttribute("r", (midPoint - strokeWidth / 2).toString());
    clockFace.setAttribute("stroke-width", strokeWidth.toString());
    faceGroup.appendChild(clockFace);

    this.addTicks(faceGroup, midPoint);

    return faceGroup;
  }
  addTicks(faceGroup, midPoint) {

    let minuteAngle = (2 * Math.PI) / 60;

    let j = 0;
    for (let i = 0; i < (Math.PI * 2); i = i + minuteAngle) {

      let h = i;
      let cos = Math.cos(h);
      let sin = Math.sin(h);

      let x = midPoint + midPoint / 1.1 * cos;
      let y = midPoint + midPoint / 1.1 * sin;

      let x1 = midPoint + midPoint / 1.15 * cos;
      let y1 = midPoint + midPoint / 1.15 * sin;

      let x2 = midPoint + midPoint / 1.20 * cos;
      let y2 = midPoint + midPoint / 1.20 * sin;

      let tick = document.createElementNS("http://www.w3.org/2000/svg", "line");
      tick.setAttribute("x1", x.toString());
      tick.setAttribute("y1", y.toString());

      if (j % 5 == 0) {
        tick.setAttribute("x2", x2.toString());
        tick.setAttribute("y2", y2.toString());


        let tp = (j * minuteAngle) - 15 * minuteAngle;
        let x3 = midPoint + midPoint / 1.4 * Math.cos(tp);
        let y3 = midPoint + 5 + midPoint / 1.4 * Math.sin(tp);
        if (j) {
          let text = document.createElementNS("http://www.w3.org/2000/svg", "text");
          text.classList.add("hourNumber");
          text.setAttribute("y", y3.toString());
          text.setAttribute("x", x3.toString());
          text.setAttribute("font-size", (midPoint / 6.8).toString());
          text.setAttribute("text-anchor", "middle");
          text.innerHTML = (j / 5).toString();
          faceGroup.appendChild(text);
        }

      } else {
        tick.setAttribute("x2", x1.toString());
        tick.setAttribute("y2", y1.toString());
      }

      faceGroup.appendChild(tick);
      j++;
    }
  }

  renderStaticElement(midPoint) {
    let updateGroup = document.createElementNS("http://www.w3.org/2000/svg", "g");
    updateGroup.classList.add("updateGroup");

    this.renderHourHand(updateGroup, midPoint);
    this.renderMinuteHand(updateGroup, midPoint);
    this.renderSecondHand(updateGroup, midPoint);
    this.renderDateHand(updateGroup, midPoint);

    let circle = document.createElementNS("http://www.w3.org/2000/svg", "circle");
    circle.setAttribute("cx", midPoint.toString());
    circle.setAttribute("cy", midPoint.toString());
    circle.setAttribute("r", (midPoint / 18.3).toString());
    circle.setAttribute("fill", "#444");

    updateGroup.appendChild(circle);

    return updateGroup;
  }

  updateDate(day) {
    let sDay = (day < 10) ? ("0" + day) : day.toString();
    this.dateHand.innerHTML = sDay;
  }

  renderDateHand(updateGroup, midPoint) {

    let rectSize = midPoint / 6.9;
    let rect = document.createElementNS("http://www.w3.org/2000/svg", "rect");
    rect.setAttribute("x", (midPoint * 1.5 - rectSize).toString());
    rect.setAttribute("y", (midPoint - rectSize / 2).toString());
    rect.setAttribute("width", rectSize.toString());
    rect.setAttribute("height", rectSize.toString());
    rect.classList.add("dateRect");
    updateGroup.appendChild(rect);

    let text = document.createElementNS("http://www.w3.org/2000/svg", "text");
    text.setAttribute("x", (midPoint * 1.5 - rectSize + 1).toString());
    text.setAttribute("y", (midPoint + rectSize / 4).toString());
    text.setAttribute("font-size", (midPoint / 10).toString());
    text.classList.add("dateText");
    updateGroup.appendChild(text);
    this.dateHand = text;
  }

  renderHourHand(updateGroup, midPoint) {

    let lineWidth = midPoint / 15;

    let line = document.createElementNS("http://www.w3.org/2000/svg", "line");
    line.classList.add("hourHand");
    line.setAttribute("x1", (midPoint).toString());
    line.setAttribute("y1", (midPoint).toString());
    line.setAttribute("stroke-width", (lineWidth).toString());
    updateGroup.appendChild(line);
    this.hourHand = line;
  }

  renderMinuteHand(updateGroup, midPoint) {
    let lineWidth = midPoint / 22;

    let line = document.createElementNS("http://www.w3.org/2000/svg", "line");
    line.classList.add("minuteHand");
    line.setAttribute("x1", (midPoint).toString());
    line.setAttribute("y1", (midPoint).toString());
    line.setAttribute("stroke-width", (lineWidth).toString());
    updateGroup.appendChild(line);
    this.minuteHand = line;
  }

  renderSecondHand(updateGroup, midPoint) {
    let lineWidth = midPoint / 36.6;

    let line = document.createElementNS("http://www.w3.org/2000/svg", "line");
    line.classList.add("secondHand");
    line.setAttribute("x1", (midPoint).toString());
    line.setAttribute("y1", (midPoint).toString());
    line.setAttribute("stroke-width", (lineWidth).toString());
    updateGroup.appendChild(line);
    this.secondHand = line;
  }
  updateHour(midPoint, hour) {
    this.hourHand.setAttribute("x2", (midPoint + midPoint / 2 * Math.cos(hour)).toString());
    this.hourHand.setAttribute("y2", (midPoint + midPoint / 2 * Math.sin(hour)).toString());
  }

  updateMinute(midPoint, min) {
    this.minuteHand.setAttribute("x2", (midPoint + midPoint / 1.5 * Math.cos(min)).toString());
    this.minuteHand.setAttribute("y2", (midPoint + midPoint / 1.6 * Math.sin(min)).toString());
  }

  updateSecond(midPoint, sec) {
    this.secondHand.setAttribute("x2", (midPoint + midPoint / 1.28 * Math.cos(sec)).toString());
    this.secondHand.setAttribute("y2", (midPoint + midPoint / 1.28 * Math.sin(sec)).toString());
  }

  update(midPoint) {

    let d = new Date();
    let date = new Date(d.getUTCFullYear(), d.getUTCMonth(), d.getUTCDate(), d.getUTCHours(), d.getUTCMinutes(), d.getUTCSeconds(), d.getUTCMilliseconds());
    date.setMilliseconds(d.getUTCMilliseconds() + (this.timeOffset * 60 * 60 * 1000));

    let day = date.getDate();
    let rawMs = date.getMilliseconds();
    let rawSec = date.getSeconds();
    let rawMin = date.getMinutes();
    let rawHour = date.getHours();

    let hourAngle = (2 * Math.PI) / 12;
    let minuteAngle = hourAngle / 5;
    let secondAngle = minuteAngle;
    let msAngle = secondAngle / 1000;

    let currection = Math.PI / 2;
    let ms = (rawMs * msAngle);
    let sec = (rawSec * secondAngle) - currection;// + ((rawMs * msAngle));
    let min = (rawMin * minuteAngle) + ((rawSec * secondAngle) / 60) - currection;
    let hour = (rawHour * hourAngle) + ((rawMin * minuteAngle) / 12) - currection;

    this.updateDate(day);
    this.updateHour(midPoint, hour);
    this.updateMinute(midPoint, min);
    this.updateSecond(midPoint, sec);


  }
}

new Clock(document.getElementById('clock1'), -4);
new Clock(document.getElementById('clock2'), 3.5);
new Clock(document.getElementById('clock3'), -7);
new Clock(document.getElementById('clock4'), +2);