JSFiddle - React, Tailwind, and code Playground

by Константин Дралюк

HTML

<div id = "clock-rim">
  <div id = "clock-base">
    <div id = "notch-container"></div>
    <div id = "hour"></div>
    <div id = "minute"></div>
    <div id = "second"></div>
    <div id = "center"></div>
  </div>
</div>

CSS

div { border: 1px solid transparent; }

#clock-rim {
  display: block;
  position: relative;
  width: 130px;
  height: 130px;
  background: linear-gradient(gray, black);
  border-radius: 50%;
}

#clock-base {
  display: block;
  position: relative;  
  width: 120px;
  height: 120px;
  margin: 19px auto;
  border-radius: 50%;
  background: white;
}

#notch-container { width: 120px; height: 120px }

#second { position: absolute; top: 123px; left: 128px; width: 100px; height: 2px; border: 1px solid transparent; border-radius: 5px; transform: unset; background: green; transform-origin: 1px 1px; }
#minute { position: absolute; top: 123px; left: 128px; width: 100px; height: 4px; border: 1px solid transparent; border-radius: 5px; transform: unset; background: red; transform-origin: 2px 2px; }
#hour { position: absolute; top: 123px; left: 128px; width: 50px; height: 4px; border: 1px solid transparent; border-radius: 5px; transform: unset; background: blue; transform-origin: 2px 2px; }
#center { position: absolute; top: 118px; left: 120px; width: 16px; height: 16px; background: white; border: 1px solid gray; border-radius: 16px; }
#brand { position: absolute; top: 110px; left: 165px; border: 1px solid gray; border-radius: 5px; width: 50px; height: 40px; font-family: Verdana; font-size: 11px; text-align: center; line-height: 20px; }
.notch { position: absolute; width: 6px; height: 6px; background: black; border-radius: 5px 5px 5px 5px; }
.thin { position: absolute; width: 1px; height: 1px; background: #000; border-radius: 50%; }

JavaScript

function deg2rad(d)
{
  return (2 * d / 360) * Math.PI;
}

let H = 0;
let M = 0;
let S = 0;
setInterval(()=>{
  let minute = document.getElementById("minute");
  let hour = document.getElementById("hour");
  let second = document.getElementById("second");
  
  S = new Date().getSeconds() * 6 - 90;
  M = new Date().getMinutes() * 6 - 90;
  H = new Date().getHours() * 30 - 90;
  
  second.style.transform = 'rotate(' + S + 'deg)';
  minute.style.transform = 'rotate(' + M + 'deg)';
  hour.style.transform = 'rotate(' + H + 'deg)';
  
}, 10);

function vec2ang(x, y) {
	angleInRadians = Math.atan2(y, x);
	angleInDegrees = (angleInRadians / Math.PI) * 180.0;
	return angleInDegrees;
}

function ang2vec(angle) {
	var radians = angle * (Math.PI / 180.0);
	var x = Math.cos(radians);
	var y = Math.sin(radians);	
	var a = new Segment(0, 0, x, y);
	var u = a.normal().unit();
	return [u.vecx, u.vecy];
}

let nc = document.getElementById("notch-container");
let angle = 0;
let rotate_x = 45;
let rotate_y = 0;

for (let i = 0; i < 60; i++) {
  let thin = document.createElement("div");
  let x = rotate_x * Math.cos(angle) - rotate_y * Math.cos(angle);
  let y = rotate_y * Math.cos(angle) + rotate_x * Math.sin(angle);
  let r = vec2ang(x, y);
  thin.className = "thin";
  thin.style.left = 122 + x + "px";
  thin.style.top = 127 + y + "px";
  thin.style.transform = "rotate(" + r + "deg)";
  nc.appendChild(thin);
  angle +=  (Math.PI / 300) * 10;
}

// reset
angle = 0;
rotate_x = 45;
rotate_y = 0;

for (let i = 0; i < 12; i++) {
  let notch = document.createElement("div");
  let x = rotate_x * Math.cos(angle) - rotate_y * Math.cos(angle);
  let y = rotate_y * Math.cos(angle) + rotate_x * Math.sin(angle);
  let r = vec2ang(x, y);
  notch.className = "notch";
  notch.style.left = 122 + x + "px";
  notch.style.top = 127 + y + "px";
  notch.style.transform = "rotate(" + r + "deg)";
  nc.appendChild(notch);
  angle +=  (Math.PI / 60) * 10;
}