<!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);