Как легко изменить время выполнения бесконечной анимации (в CSS3) с помощью Javascript

Я просмотрел множество вопросов, связанных с моим вопросом в stackoverflow, но я еще не нашел один, который отвечает на мой вопрос простым JavaScript (не используя библиотеки любого типа).

Моя проблема в том, что у меня бесконечная анимация с CSS3 i.e.:

.clockwiseAnimation {
    top: 270px;
    left: 200px;
    position: absolute;

    -webkit-animation: clockwise 4s linear infinite; /* Chrome, Safari 5 */
    -moz-animation: clockwise 4s linear infinite; /* Firefox 5-15 */
    -o-animation: clockwise 4s linear infinite; /* Opera 12+ */
    animation: clockwise 4s linear infinite; /* Chrome, Firefox 16+, IE 10+, Safari 5 */
}
@-webkit-keyframes clockwise {
    from { -webkit-transform: rotate(0deg) translateX(150px) rotate(0deg); }
    to { -webkit-transform: rotate(360deg) translateX(150px) rotate(-360deg); }
}
@-moz-keyframes clockwise {
    from { -moz-transform: rotate(0deg) translateX(150px) rotate(0deg); }
    to { -moz-transform: rotate(360deg) translateX(150px) rotate(-360deg); }
}
@-o-keyframes clockwise {
    from { -o-transform: rotate(0deg) translateX(150px) rotate(0deg); }
    to { -o-transform: rotate(360deg) translateX(150px) rotate(-360deg); }
}
@keyframes clockwise {
    from { transform: rotate(0deg) translateX(150px) rotate(0deg); }
    to { transform: rotate(360deg) translateX(150px) rotate(-360deg); }
}

Эта анимация позволяет мне вращать (по часовой стрелке) любой тег, который имеет класс "clockwiseAnimation".

Что я хочу сделать, так это изменить время выполнения (я буду называть его скорость) анимации с помощью javascript, например:

HTML:

<span id="someID" class="clockwiseAnimation">sometext</span>

JavaScript:

var style = document.getElementById("someID").style,
speed = 6; 
//obviously the speed is dynamic within my site (through an `<input type="range">`)
//for the purposes of this example I set the speed to a different value(6seconds) than the original value(4seconds).
style.webkitAnimationDuration = style.mozAnimationDuration = style.oAnimationDuration = style.animationDuration = speed + "s";

Он работает, когда я приостанавливаюсь и затем играю (по воспроизведению я имею в виду UNPAUSE не перезапускать) анимацию, т.е.:

var style = document.getElementById("someID").style;
some = 6; //it is dynamic (as I pointed out before)

//pause
style.webkitAnimationPlayState = style.mozAnimationPlayState = style.oAnimationPlayState = style.animationPlayState = "paused";

//change speed
style.webkitAnimationDuration = style.mozAnimationDuration = style.oAnimationDuration = style.animationDuration = speed + "s";  

//play (== UNPAUSE) //UPDATE: Added the timeout because I can't get it to work any other way.
setTimeout(function(){
            style.webkitAnimationPlayState = style.mozAnimationPlayState = style.oAnimationPlayState = style.animationPlayState = "running";
        },1);

ОБНОВЛЕНО:

И это работает! НО, он имеет большой скачок RANDOM в анимации, а это означает, что когда я меняю "скорость" на "ползунок <input type="range">", элемент перескакивает в случайное местоположение (а не начало и конец анимации просто случайное местоположение).

ПРИМЕЧАНИЕ. Пауза и воспроизведение работают очень гладко, не изменяя "скорость" анимации.

Мой вопрос (ы): Могу ли я изменить "скорость" анимации плавно С JavaScript? (БЕЗ прыжков) Если ответ: "Нельзя сделать это плавно во время выполнения анимации", то: Есть ли способ изменить его в следующей итерации анимации бесконечной? Если так: Затем, как я могу сказать, чтобы начать с следующей итерации, и как узнать, какая следующая итерация, если я настрою анимацию на бесконечность (свойство анимация-итерация-счетчик элемента, который делает анимацию, всегда возвращает "бесконечный" ).

Здесь приведен пример. Я надеюсь, что это поможет.

Ответ 1

Что может произойти, так это то, что animation-duration "change" может "прыгать" в точку в animation, соответствующую "измененному" @keyframes - на основе общей "измененной" продолжительности анимации.

Если начало animation-duration from (или 0%) перешло к to (или 100%), можно также изменить соответствующую позицию @keyframes ".

Например, если исходный animation-duration был 4s (или, 4000ms) примерно с 2s (или, 2000ms), соответствующий keyframes может быть примерно 50% или

через 2 секунды до 4 секунд анимации 50% { -webkit-transform: rotate(180deg) translateX(150px) rotate(-180deg); }

когда animation-duration динамически изменяется, соответствующий keyframes может быть "изменен" на совпадающую точку % или более длинный интервал для того же эффекта. Анимированный элемент может выглядеть как вперед, так и назад, или "прыгать" из-за его повторного позиционирования в "измененных" соответствующих keyframes и animations.

Существует также функция 1s setTimeout, которая может иметь или не иметь длительность 1s.

Возможно, "плавно" "перейти" к новой "измененной" позиции в более длинном animation-duration предлагаемом эффекте transition или requestAnimationFrame (http://www.w3.org/TR/animation-timing/).

..

Попробуйте следующее:

HTML

<input type="range" id="speedSlider" min="2000" max="6000" value="4000">

CSS

    input {
    -webkit-transform: rotate(180deg);  
    top : 50px;
    position : absolute;
}

.clockwiseAnimation {
 /* top: 270px;
    left: 200px; */
    left : 50%;
    top : 50%;
    position:absolute;

   /* css animation (no change) */
}

JS

var speedSlider = document.getElementById("speedSlider");
    speedSlider.addEventListener("change", changeSpeed, false);
    function changeSpeed(e){
        var speed = Math.floor(speedSlider.value);
        var element = document.getElementById("span");
        var style = element.style;
        style.webkitAnimationPlayState = style.mozAnimationPlayState = style.oAnimationPlayState = style.animationPlayState = "paused";
        style.webkitAnimationDuration = style.mozAnimationDuration = style.oAnimationDuration = style.animationDuration = String(speed) + "ms";
            style.webkitAnimationPlayState = style.mozAnimationPlayState = style.oAnimationPlayState = style.animationPlayState = "running";
    }

Ответ 2

С CSS: http://jsbin.com/UsunIMa/1/

Переход и анимация свойств CSS позволяют вам выбрать функцию ослабления.

div {
  transition:         all 600ms cubic-bezier(0.77, 0, 0.175, 1); 
  /* or */
  animation: clockwise 4s cubic-bezier(0.77, 0, 0.175, 1) infinite;
}

Ответ 3

используйте setTimeout для добавления класса анимации в требуемый элемент с удалением класса анимации в качестве обратного вызова.

Ответ 4

Возможно, jQuery queue может вам помочь.

Здесь