JSFiddle - React, Tailwind, and code Playground

by Alaksandar Jesus Gene

HTML

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Analog Clock</title>
    <link rel="stylesheet" href="index.css">
</head>
<body>
    <div class="app">
        <div class="frame">
            <div class="angle-0"></div>
            <div class="angle-0 rotate-30"></div>
            <div class="angle-0 rotate-60"></div>
            <div class="angle-0 rotate-m-30"></div>
            <div class="angle-0 rotate-m-60"></div>
            <div class="angle-0 rotate-90"></div>
          
            <div class="number number-12">12</div>
            <div class="number number-1">1</div>
            <div class="number number-2">2</div>
            <div class="number number-3">3</div>
            <div class="number number-4">4</div>
            <div class="number number-5">5</div>
            <div class="number number-6">6</div>
            <div class="number number-7">7</div>
            <div class="number number-8">8</div>
            <div class="number number-9">9</div>
            <div class="number number-10">10</div>
            <div class="number number-11">11</div>
            <div class="hand hour-hand"></div>
            <div class="hand minute-hand"></div>
            <div class="hand second-hand"></div>
            <div class="center-button"></div>
        </div>
        <div class="timestamp">
            <div><span class="hours"></span>:<span class="minutes"></span>:<span class="seconds"></span></div>
        </div>
    </div>

    <script src="index.js"></script>
</body>
</html>

CSS

body{
    margin:0;
    padding:0;
   
   
}
.app{
    width:100vw;
    height: 100vh;
    display: flex;
    justify-content: center;
    align-items: center;
    flex-direction: column;
}

.frame{
    width:350px;
    height: 350px;
    border:2px solid black;
    border-radius: 50%;
    position: relative;
}


.angle-0{
    width:400px;
    height: 2px;
    top:50%;
    left:-25px;
    position: absolute;
    background: red;
    display: none;
}
.rotate-30{
    transform: rotate(30deg);
}
.rotate-60{
    transform: rotate(60deg);
}
.rotate-m-30{
    transform: rotate(-30deg);
}
.rotate-m-60{
    transform: rotate(-60deg);
}
.rotate-90{
    transform: rotate(90deg);
}

.number{
    position:absolute;
    z-index: 100;
    font-size: 24px;
}
.frame .number-12{
    left: calc(50% - 11px);
    top: 5px;
}

.frame .number-3{
    right: 5px;
    top: calc(50% - 11px);
}
.frame .number-1{
    right: 85px;
    top: 6%;
}
.frame .number-2{
    right: 25px;
    top: 23%;
}
.frame .number-6{
    left: calc(50% - 5px);
    bottom: 5px;
}
.frame .number-4{
    right: 28px;
    bottom: 23%;
}
.frame .number-5{
    right: 88px;
    bottom: 21px;
}
.frame .number-7{
    left: 26%;
    bottom: 22px;
}
.frame .number-8{
    left: 9%;
    bottom: 80px;
}
.frame .number-9{
    top: calc(50% - 11px);
    left: 5px;
}

.frame .number-10{
    top: 23%;
    left: 25px;
}

.frame .number-11{
    top: 7%;
    left: 85px;
}

.hand{
    position:absolute;
    left: 175px;
    transform: rotate(0deg);
    transform-origin: bottom;
    
}

.hour-hand{
    width: 4px;
    background-color: blue;
    height: 70px;
    top:calc(175px - 70px);
   
}
.minute-hand{
    width: 2px;
    background-color: rgb(255, 0, 0);
    height: 120px;
    top:calc(175px - 120px);
}
.second-hand{
    width: 1px;
    background-color: rgb(8, 131, 49);
    height: 150px;
    top:calc(175px - 150px);
}

.center-button{
    width:10px;
    height: 10px;
    border-radius: 50%;
    background-color: black;
   ...

JavaScript

const secondHandElement = document.querySelector(".second-hand");
const minuteHandElement = document.querySelector(".minute-hand");
const hourHandElement = document.querySelector(".hour-hand");
const timestampElement = document.querySelector(".timestamp");
const hours = timestampElement.querySelector(".hours");
const minutes = timestampElement.querySelector(".minutes");
const seconds = timestampElement.querySelector(".seconds");
let secondHandAngle = 0;
let hourHandAngle = 0;
let minuteHandAngle = 0;

const now = new Date();
const hour = now.getHours();
const hourFormatted = hour < 12 ? hour : (hour - 12);
hourHandAngle = 30 * hourFormatted;

const minute = now.getMinutes();
minuteHandAngle = minute * 6;

const second = now.getSeconds();
secondHandAngle = second * 6;


hourHandElement.style.transform = `rotate(${hourHandAngle}deg)`
minuteHandElement.style.transform = `rotate(${minuteHandAngle}deg)`;
secondHandElement.style.transform = `rotate(${secondHandAngle}deg)`;

function updateTimestamp() {
    const now = new Date();
    const hour = now.getHours();
    const hourFormatted = hour < 12 ? hour : (hour - 12);
    hours.innerHTML = hourFormatted.toString().padStart(2, '0');
    const minute = now.getMinutes();
    minutes.innerHTML = minute.toString().padStart(2, '0');;
    const second = now.getSeconds();
    seconds.innerHTML = second.toString().padStart(2, '0');;

}

setInterval(() => {
    secondHandAngle = secondHandAngle + 6;
    if (secondHandAngle >= 360) {
        secondHandAngle = 0;
        updateMinuteHand();
    }
    secondHandElement.style.transform = `rotate(${secondHandAngle}deg)`;
    updateTimestamp();

}, 1000)

function updateMinuteHand() {
    minuteHandAngle = minuteHandAngle + 6;
    if (minuteHandAngle >= 360) {
        minuteHandAngle = 0;
        updateHourHand();
    }
    minuteHandElement.style.transform = `rotate(${minuteHandAngle}deg)`;
}
function updateHourHand() {
    hourHandAngle = hourHandAngle + 6;
    if (hourHandAngle >=...