Я хочу иметь плавный переход секундной стрелки от сек==59 до сек==0.
Он идет хорошо от 0 до 59 секунд, но на sec == 59 он не идет вперед, а откатывается в 0 позицию. Я пытаюсь сделать плавный переход от 59 до 0 по часовой стрелке (то же самое для секундной, минутной и часовой стрелок). Вот полный код часов -
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.info(`${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>Я следил за видео об этом и в этом, репетитор упомянул два решения:
сначала продолжался непрерывный подсчет после sec = 59 и не возвращался к sec = 0 (но мне это решение не понравилось).
Во-вторых, был временно удален переход, когда на sec==59 через JS. Я не знаю, как это сделать. Я пробовал это в setTime(), но не сработало -
if (sec == 59) {
hands[2].setAttribute("transition", "");
}
Пожалуйста помоги. Спасибо!



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Возможно, вам придется сделать немного больше, чтобы сгладить переход, но настройка перехода, как вы пытались, — это CSS вещь, а не HTML attribute
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();
if (sec === 59) {
secHand.style.transition = "0.5s";
} else {
secHand.style.transition = "0s";
}
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.info(`${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>Нет проблем, просто не забудьте выполнить ту же логику для минут и часов.
нужна запись 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>Именно так, как я хочу, но я не понимаю, как это работает, потому что я не знаком с async и promise. Мне нужно прочитать о них. Большое спасибо.
Не по теме: (почти) только CSS.
Вам нужно только один раз установить текущее время с помощью 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);
}
Минус: отсутствие опций, касающихся функций смягчения. Вы можете сделать так, чтобы стрелки часов работали непрерывно или пошагово (раз в секунду/минуту/час), но между шагами нет пошагового выполнения с замедлением.
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>Спасибо! Мне очень нравится применять анимацию CSS, как это делали вы. Это действительно работает с упомянутым вами недостатком. Вы облегчили понимание.
Спасибо! это реально работает. Узнал что-то новое сегодня благодаря этому ответу.