Страницы

Поиск по вопросам

среда, 1 января 2020 г.

Как изменить текущую позицию (текущий кадр) CSS-анимации через JavaScript?

#javascript #css #анимация


Как известно, CSS-анимации создаются через @keyframes, и ключевые кадры там задаются
в процентах. Так вот, как установить элементу конкретный процент, который должен отображаться?
Сама анимация при этом должна быть приостановлена, просто должен отображаться выбранный
скриптом кадр.

Зачем это нужно: например, пользователь возюкает пальцем по экрану своего айфончика,
и в зависимости от положения пальца нужно изменить положение и вид какого-нибудь элемента
(свайп со сложной анимацией, например). Ну или произвольная анимация перелистывания
слайдов в слайдере тем же пальцем.
    


Ответы

Ответ 1



Проценты установить нельзя, но, если знать длительность анимации (animation-duration), можно пересчитать проценты в секунды и установить отрицательный animation-delay, так, чтобы анимация как бы начиналась с указанной секунды. Например, если длина анимации 3s и нам нужен кадр 50%, то ставим animation-delay: -1.5s (середина анимации). Чтобы это нормально работало, нужно соблюсти ещё несколько условий: animation-iteration-count: 1 и animation-fill-mode: forwards — это нужно для того, чтобы при >=100% отображался последний кадр анимации (если это не указать, то при 100% отобразится первый кадр) animation-play-state: paused, чтобы анимация полностью контролировалась скриптом и не воспроизводилась сама по себе. Всё это можно объединить в одном CSS-свойстве animation для краткости. Пример: var anim = document.getElementById('anim'); var rng = document.getElementById('rng'); function setAnimPercent(percent) { var duration = 2; // длительность знаем заранее var frac = parseFloat(percent) / 100.0; var seconds = duration * frac; anim.style.animationDelay = '-' + seconds + 's'; }; rng.onchange = rng.oninput = function() { setAnimPercent(rng.value); }; @keyframes anim { from { background: green; transform: translateX(0px) rotate(0deg); border-radius: 0%; } to { background: red; transform: translateX(300px) rotate(45deg); border-radius: 50%; } } #anim { display: inline-block; width: 50px; height: 50px; animation: anim 2s paused forwards linear; } #rng { width: 310px; margin: 0 20px; }

Укажите процент:


Комментариев нет:

Отправить комментарий