I want to have a smooth transition of the second-hand from sec==59 to sec==0.
It's going well from 0 to 59 seconds but on sec==59 it doesn't go forward instead it rolls back to 0 position. I'm trying to have a smooth transition from 59 to 0 in clockwise direction (same in second, minute and hour hands). Here's is the full code of the clock -
let secHand = document.querySelector(".sec-hand")
let minHand = document.querySelector(".min-hand")
let hourHand = document.querySelector(".hour-hand")
let hands = document.querySelectorAll(".hand")
function setTime() {
const now = new Date();
const sec = now.getSeconds();
const secDegrees = ((sec / 60) * 360) + 90;
secHand.style.transform = `rotate(${secDegrees}deg)`;
const mint = now.getMinutes();
const mintDegrees = ((mint / 60) * 360) + 90;
minHand.style.transform = `rotate(${mintDegrees}deg)`;
const hour = now.getHours();
const hourDegrees = ((hour / 12) * 360) + 90;
hourHand.style.transform = `rotate(${hourDegrees}deg)`;
//console.log(`${hour} : ${mint} : ${sec}`)
}
setInterval(setTime, 1000)
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.clock {
background: transparent;
width: 400px;
height: 400px;
margin: auto;
margin-top: 100px;
border-radius: 50%;
border: 20px solid blue;
position: absolute;
left: 200px;
}
.center-dot {
width: 50px;
height: 50px;
border-radius: 50%;
background: rgb(195, 4, 4);
position: absolute;
top: calc(50% - 25px);
left: calc(50% - 25px);
z-index: 5;
}
.hand {
width: 45%;
height: 10px;
background: black;
position: absolute;
top: calc(50% - 5px);
left: 5%;
border-radius: 10px;
transform-origin: right;
transition: all 0.5s;
transform: rotate(90deg)
}
<div class="clock">
<div class="center-dot"></div>
<div class="hour-hand hand"></div>
<div class="min-hand hand"></div>
<div class="sec-hand hand"></div>
</div>
I was following a video on this and in that, tutor mentioned two solutions-
first was keep counting continuously after sec=59 and not going back to sec=0 (but I didn't like this solution).
Second was temporarily remove transition when on sec==59 through JS. I don't know how to do that. I tried this in setTime() but didn't work -
if(sec == 59) {
hands[2].setAttribute("transition", "");
}
Please help. Thank you!
Off Topic: (almost) CSS only.
You only have to set the current time once with JS.
document.body.style.setProperty("--time", Math.floor(Date.now() / 1000 - new Date().getTimezoneOffset() * 60) % (60 * 60 * 24));
@keyframes turn {
from {
transform: rotate(90deg);
}
to {
transform: rotate(450deg);
}
}
.sec-hand {
/*animation: turn 60s infinite steps(60);*/
animation: turn 60s infinite linear;
animation-delay: calc(var(--time) * -1s);
}
.min-hand {
/*animation: turn 3600s infinite steps(60);*/
animation: turn 3600s infinite linear;
animation-delay: calc(var(--time) * -1s);
}
.hour-hand {
/*animation: turn 43200s infinite steps(12);*/
animation: turn 43200s infinite linear;
animation-delay: calc(var(--time) * -1s);
}
downside: the lack of options regarding easing functions. You can let the clock-handles run continously, or stepped (once a second/minute/hour) but there is no stepped with easing between the steps.
document.body.style.setProperty("--time", Math.floor(Date.now() / 1000 - new Date().getTimezoneOffset() * 60) % (60 * 60 * 24));
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.clock {
background: transparent;
width: 400px;
height: 400px;
margin: auto;
margin-top: 100px;
border-radius: 50%;
border: 20px solid blue;
position: absolute;
left: 200px;
}
.center-dot {
width: 50px;
height: 50px;
border-radius: 50%;
background: rgb(195, 4, 4);
position: absolute;
top: calc(50% - 25px);
left: calc(50% - 25px);
z-index: 5;
}
.hand {
width: 45%;
height: 10px;
background: black;
position: absolute;
top: calc(50% - 5px);
left: 5%;
border-radius: 10px;
transform-origin: right;
}
@keyframes turn {
from {
transform: rotate(90deg)
}
to {
transform: rotate(450deg)
}
}
.sec-hand {
--animation: turn 60s infinite steps(60);
animation: turn 60s infinite linear;
animation-delay: calc(var(--time) * -1s);
}
.min-hand {
--animation: turn 3600s infinite steps(60);
animation: turn 3600s infinite linear;
animation-delay: calc(var(--time) * -1s);
}
.hour-hand {
--animation: turn 43200s infinite steps(12);
animation: turn 43200s infinite linear;
animation-delay: calc(var(--time) * -1s);
}
<div class="clock">
<div class="center-dot"></div>
<div class="hour-hand hand"></div>
<div class="min-hand hand"></div>
<div class="sec-hand hand"></div>
</div>
you need record secCount, mintCount, hourCount
let secHand = document.querySelector('.sec-hand') ;
let minHand = document.querySelector('.min-hand') ;
let hourHand = document.querySelector('.hour-hand') ;
let hands = document.querySelectorAll('.hand');
const delay = async (n = 0) => new Promise((res) => setTimeout(res, n));
(async () => {
let secCount = 0;
let mintCount = 0;
let hourCount = 0;
for (;;) {
const now = new Date();
const sec = now.getSeconds();
const mint = now.getMinutes();
const hour = now.getHours();
if (sec == 0) {
secCount++;
if (mint == 0) {
mintCount++;
if (hour == 0) {
hourCount++;
}
}
}
const secDegrees = (sec / 60 + secCount) * 360 + 90;
secHand.style.transform = `rotate(${secDegrees}deg)`;
const mintDegrees = (mint / 60 + mintCount) * 360 + 90;
minHand.style.transform = `rotate(${mintDegrees}deg)`;
const hourDegrees = (hour / 12 + hourCount) * 360 + 90;
hourHand.style.transform = `rotate(${hourDegrees}deg)`;
await delay(1000);
}
})();
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.clock {
background: transparent;
width: 400px;
height: 400px;
margin: auto;
margin-top: 100px;
border-radius: 50%;
border: 20px solid blue;
position: absolute;
left: 200px;
}
.center-dot {
width: 50px;
height: 50px;
border-radius: 50%;
background: rgb(195, 4, 4);
position: absolute;
top: calc(50% - 25px);
left: calc(50% - 25px);
z-index: 5;
}
.hand {
width: 45%;
height: 10px;
background: black;
position: absolute;
top: calc(50% - 5px);
left: 5%;
border-radius: 10px;
transform-origin: right;
transition: all 0.5s;
transform: rotate(90deg)
}
<div class="clock">
<div class="center-dot"></div>
<div class="hour-hand hand"></div>
<div class="min-hand hand"></div>
<div class="sec-hand hand"></div>
</div>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With