JSFiddle - React, Tailwind, and code Playground

by Sam Wray

HTML

<svg height="300" width="300">
  <!-- <circle cx="150" cy="150" r="130" class="circle"/> -->
  <!-- <circle cx="150" cy="150" r="100" class="circle"/> -->
  
  <line x1="150" y1="150" x2="150" y2="150" class="line" id="hour" />
  <line x1="150" y1="150" x2="150" y2="150" class="line" id="minute" />
  <line x1="150" y1="150" x2="150" y2="150" class="line" id="joiner" />
  
  <!-- <circle cx="150" cy="150" r="2" id="second"/> -->
  <svg id="second" width="60" height="60" x="150" y="150" viewBox="0 0 60 60">
    <g id="secondGroup">
      <line class="line" x1="20" y1="20" x2="20" y2="40"/>
	    <line class="line" x1="20" y1="20" x2="40" y2="30"/>
	    <line class="line" x1="20" y1="40" x2="40" y2="30"/>
    </g>
  </svg>
</svg>

CSS

svg {
  border: 1px solid;
}

.line {
  fill: black;
  stroke: black;
  stroke-width: 2;
}

.line.join {
  stroke-width: 1;
}

.triangle {
  fill: none;
  stroke: black;
}

.circle {
  fill: none;
  stroke: black;
}

JavaScript

const hourLine = document.querySelector('svg #hour');
const minuteLine = document.querySelector('svg #minute');
const joinerLine = document.querySelector('svg #joiner');
const secondPoint = document.querySelector('svg #second');
const secondGroup = document.getElementById('secondGroup');

const secRad = 140;
const minRad = 130;
const hourRad = 100;
const center = 150;

const correction = 270;

function degreesToRad(degrees) {
  return degrees * (Math.PI / 180);
}

function hoursToAngle(hours, minutes, seconds, mseconds) {
  const hourAngle = (360 / 12) * hours;
  const minAngle = (360 / 12 / 60) * minutes;
  const secondsAngle = (360 / 12 / 60 / 60) * seconds;
  const msecondsAngle = (360 / 12 / 60 / 60 / 1000) * mseconds;
  return hourAngle + minAngle + secondsAngle + msecondsAngle + correction
}

function minutesToAngle(minutes, seconds, mseconds) {
  const minAngle = (360 / 60) * minutes;
  const secondsAngle = (360 / 60 / 60) * seconds;
  const msecondsAngle = (360 / 60 / 60  / 1000) * mseconds;
  return minAngle + secondsAngle + msecondsAngle + correction;
}

function secondsToAngle(seconds, mseconds) {
  const secondsAngle = (360 /  60) * seconds;
  const msecondsAngle = (360 / 60 / 1000) * mseconds;
  return secondsAngle + msecondsAngle + correction;
}

function setLine(line, x1, y1, x2, y2) {
	line.setAttribute('x1', x1);
  line.setAttribute('y1', y1);
  line.setAttribute('x2', x2);
  line.setAttribute('y2', y2);
}

function render() {
  const today = new Date();
  const hours = today.getHours() % 12;
  const mins = today.getMinutes();
  const secs = today.getSeconds();
  const msecs = today.getMilliseconds();
  
  const secAngle = secondsToAngle(secs, msecs);
	const minAngle = minutesToAngle(mins, secs, msecs);
  const hourAngle = hoursToAngle(hours, mins, secs, msecs);
  
	const minX = Math.round(center + (Math.cos(degreesToRad(minAngle)) * minRad));
  const minY = Math.round(center + (Math.sin(degreesToRad(minAngle)) * minRad));
  
  const hourX =...