Пауза и запуск: animation-play-state

animation-play-state ставит анимацию на паузу и снимает с неё паузу - по умолчанию running (анимация играет). paused замораживает анимацию ровно в текущей точке прогресса, а не сбрасывает её: возобновление продолжает с той же самой точки, а не с начала. Это же свойство можно переключать через :hover или через JavaScript.

Попробуй прямо сейчас: квадрат стоит на месте, пока курсор не наведён (animation-play-state: paused на базовом селекторе), и крутится, только пока курсор над ним (:hover переключает на running). Убери курсор ПОСРЕДИ вращения, подожди немного и наведи снова - вращение продолжится РОВНО с той точки, где остановилось, а не начнётся заново от 0 градусов, потому что имя анимации (spin) всё это время остаётся подключённым на базовом селекторе - меняется только play-state.

Пауза и возобновление: позиция сохраняется

По умолчанию animation-play-state равен running - анимация просто играет. Значение paused замораживает её РОВНО в той точке прогресса, где она была в момент паузы - собственная проверка подтвердила: currentTime практически не сдвигается, сколько бы реального времени ни прошло, пока стоит пауза. Когда снова ставится running, анимация продолжает С ТОЙ ЖЕ ТОЧКИ, а не перезапускается с начала. Менее очевидный момент, тоже проверенный: если поставить паузу ДО того, как активная фаза анимации вообще началась (то есть во время animation-delay), замораживается и сам ОТСЧЁТ ЗАДЕРЖКИ - анимация не "тайком" продолжает отсчитывать секунды задержки в фоне, пока стоит на паузе.

.loader { animation-name: spin; animation-duration: 1s; animation-iteration-count: infinite; animation-play-state: paused; } /* JS: loader.style.animationPlayState = 'running'; */ - анимация ждёт на месте, пока JS явно не запустит её.

Неправильное ожидание - что снятие паузы перезапускает анимацию:

/* поставили paused на 50% прогресса, потом вернули running, ожидая, что анимация начнётся заново с 0% */ - на самом деле она продолжит именно с 50%, а не с начала.

Практика: пауза при наведении курсора

Самый частый приём - анимация играет только пока на неё наведён курсор. Работает это так: animation-name (и вся анимация) остаётся на БАЗОВОМ селекторе, а :hover переключает только animation-play-state с paused на running. Собственная проверка подтвердила: на всём протяжении наведения-и-ухода курсора getAnimations() показывал РОВНО ОДИН и тот же объект анимации - она не пересоздаётся, поэтому и позиция не теряется. Это принципиально ОТЛИЧАЕТСЯ от ловушки урока про animation-fill-mode: там animation-name был назначен ТОЛЬКО внутри .el:hover, и при уходе курсора вся анимация снималась целиком вместе с forwards-состоянием. Здесь наоборот - именно то, что animation-name живёт на базовом селекторе, а меняется только play-state, и делает приём рабочим.

.icon { animation-name: spin; animation-duration: 2s; animation-iteration-count: infinite; animation-play-state: paused; } .icon:hover { animation-play-state: running; } - animation-name на базовом селекторе, на :hover меняется только play-state - позиция сохраняется между наведениями.

Ловушка предыдущего урока для сравнения (не делай так, если важна память позиции):

.icon:hover { animation-name: spin; animation-duration: 2s; animation-iteration-count: infinite; } - вся анимация только на :hover: при уходе курсора она снимается целиком, а не просто ставится на паузу.

Частые ошибки новичков

ОшибкаЧто происходитКак исправить
Забыть, что animation-play-state по умолчанию running Анимация просто крутится без паузы, если явно не указать paused Указывать paused на базовом селекторе, если анимация должна ждать запуска
Ожидать, что снятие паузы перезапускает анимацию с начала На самом деле она продолжает с ТОЙ ЖЕ точки прогресса, где была поставлена пауза Учитывать это при проектировании интерфейса - для перезапуска с нуля нужен другой приём (например смена animation-name)
Считать, что пауза во время animation-delay ничего не замораживает На самом деле замораживается и сам отсчёт задержки, а не только активная фаза Учитывать это, если задержка используется для тайминга нескольких анимаций
Вешать всю анимацию (animation-name) только на :hover ради эффекта паузы При уходе курсора анимация снимается ЦЕЛИКОМ (та же ловушка, что в уроке про animation-fill-mode), а не просто останавливается Держать animation-name на базовом селекторе, переключать через :hover только animation-play-state

Шпаргалка

ЗаписьЧто означает
animation-play-state: running; (по умолчанию)Анимация играет как обычно
animation-play-state: paused;Заморожена ровно в текущей точке прогресса
paused → runningПродолжает с той же точки, а не с начала
paused во время animation-delayЗамораживает и сам отсчёт задержки
.el{play-state:paused} .el:hover{play-state:running}Играет только при наведении, позиция сохраняется между наведениями
el.style.animationPlayState='paused';То же самое, но управление через JavaScript

Коротко: отвечаем на вопросы

Как вообще остановить CSS-анимацию?

Использовать свойство animation-play-state и установить ему значение paused - например через JS-класс, который добавляется по нужному событию. Анимация замрёт ровно в той точке, где была на момент остановки, а не сбросится в начало.

Можно ли поставить на паузу вообще ВСЕ анимации на странице сразу, например пока не загрузились ресурсы?

Да, это реальный приём с Хабра: пока на body висит служебный класс (например js-loading), общее правило вроде body.js-loading * { animation-play-state: paused !important; } замораживает абсолютно все анимации на странице, а JavaScript снимает этот класс, когда сработало событие load. Работает и с задержками - если у какой-то анимации ещё не кончился animation-delay, пауза заморозит и его тоже.

Категория
Поделиться в социальных сетях

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

0 Комментарии

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

#buttons=(Хорошо) #days=(20)

Мы используем файлы cookie для улучшения работы сайта. Подробнее
Хорошо
×