Когда вы измените animation-duration
, вы не просто измените, как будет проходить каждая итерация, но вы измените всю анимацию. Например, если у вас есть 3s
как длительность, поэтому первая итерация займет 3s
, а если в 3s
(iterationend) вы измените на 5s
, это похоже на создание другой анимации, где итерация будет длиться 5 с, и вы прыгаете в новое состояние этой новой анимации, которая 3s
из 5s
.
Вот пример, чтобы лучше проиллюстрировать проблему. Я буду продолжать увеличивать продолжительность, и вы заметите, что как только вы достигнете конца итерации, вы вернетесь в предыдущее состояние, потому что вы увеличили продолжительность, затем вы снова достигнете последнего состояния и вернетесь назад и так далее.
Это похоже на то, что кто-то бежит в состояние 100%
, и вы продолжаете увеличивать это состояние.
let square = document.getElementById('square');
let time = 1;
square.addEventListener('animationiteration', duration);
function duration() {
time*=2;
square.style.setProperty('--animation-time', time + 's');
console.log(time);
}
:root {
--animation-time: 1s;
}
@keyframes fire {
0% {
background-color: red;
}
50% {
background:yellow;
}
100% {
background-color: black;
}
}
#square {
width: 100px;
height: 100px;
animation: fire var(--animation-time) ease infinite alternate;
}
<div id="square"></div>
В приведенном выше примере я умножаю длительность на 2, поэтому каждый раз, когда я возвращаюсь назад, чтобы перейти из состояния 50%
, и как только я достигаю 100%
, я повторяю то же самое снова.
То же самое происходит с вашим кодом, но более сложным способом, так как вы увеличиваете / уменьшаете продолжительность. Уменьшение длительности заставит вас перейти к следующей итерации и альтернативному состоянию.
Другими словами, вы закончите со случайной мерцающей анимацией.
Чтобы наглядно проиллюстрировать, что здесь происходит, это анимация, в которой я буду анимировать временную шкалу вашей анимации
.box {
height:50px;
border:1px solid;
background:
/* This will illustrate the current state */
linear-gradient(green,green) left/2px 100% no-repeat,
/* This is our animation with a duration of 5s (50px) intially*/
linear-gradient(to right,yellow,red,red,yellow) left/100px 100%;
animation:
move 10s linear infinite, /* This is the current state*/
change 2s steps(3) infinite /* this is the change of the animation duration*/
; /**/
}
@keyframes move {
to {
background-position:right,left;
}
}
@keyframes change {
to {
background-size:2px 100%,40px 100%;
}
}
<div class="box">
</div>
Вы можете видеть, что мы не меняем текущее состояние (показано зеленой линией), но мы меняем всю анимацию, делая текущее состояние случайным образом переходящим в другой цвет.
Одна идея, чтобы получить то, что вы хотите, это рассмотреть переход и переключение классов:
let square = document.getElementById('square');
let time;
/* We intially add the class to trigger the transition*/
setTimeout(function(){square.classList.toggle('change')},10);
square.addEventListener('transitionend', duration);
/* When the transition is done we toggle the class to start another one*/
function duration() {
time = Math.random() + 1;
square.style.setProperty('--animation-time', time + 's');
square.classList.toggle('change');
console.log(time);
}
:root {
--animation-time: 1s;
--color-1: #ff0000;
--color-2: #ffee00;
}
#square {
width: 100px;
height: 100px;
transition: var(--animation-time) ease;
background-color: var(--color-1);
}
#square.change {
background-color: var(--color-2);
}
<div id="square"></div>