Анимация
Рассмотрим основы анимации на CSS. Нам предстоит пройти путь развития цивилизации и покорить космический простор. Мы будем двигать, поворачивать и видоизменять объекты, попутно осваивая приёмы работы анимации в CSS.
Привет, animation![1/31]
С помощью CSS можно создавать сложные анимации и очень гибко управлять ими. Описание CSS-анимации состоит из двух частей: набора ключевых кадровkeyframesи параметров самой анимации.
Вот пример описания ключевых кадров анимации:
@keyframes stretching {
0% {
width: 100px;
}
100% {
width: 200px;
}
}
Анимация в примере имеет названиеstretching, и в ней описывается, как будет меняться стиль блока от начальной до конечной точки. Эту анимацию можно применить к любому элементу, для этого достаточно добавить в CSS два свойства —animation-name(название анимации) иanimation-duration(длительность) — и задать им нужные значения. Например:
.button {
animation-name: stretching;
animation-duration: 1s;
}
Этот код назначит анимациюstretchingэлементам с классомbutton. В результате работы анимации элемент плавно увеличит ширину со100pxдо200pxза1секунду.
@keyframes: раскадровка[2/31]
Для каждой анимации нужно задать имя, описать начальный и конечный ключевые кадры, которые задаются с помощью зарезервированных словfromиtoили значений0%и100%.
Также можно описать промежуточные ключевые кадры, которые задаются с помощью процентов.
Если не задан начальный ключевой кадр, то анимация будет проигрываться из исходного стилевого состояния элемента к ближайшему шагу из перечисленных вkeyframesи далее.
Если не задан конечный кадр, то после достижения последнего промежуточного шага, анимация проиграется в обратном направлении до достижения изначального состояния элемента.
Ключевые кадры внутриkeyframesмогут быть написаны в произвольном порядке, но лучше их перечислять по хронологии от меньшего к большему.
Длительность анимацииanimation-durationзадаётся в секундах или миллисекундах, например:10s,100ms.
А теперь давайте попробуем создать анимацию без описания начального кадра, используя шаги в50%и100%.
@keyframes: from и to[3/31]
Как уже говорилось впредыдущем задании, начальный и конечный ключевые кадры задаются с помощью словfromиtoили значений0%и100%.
А промежуточные ключевые кадры задаются с помощью процентов. Вот пример анимации из 4 кадров:
@keyframes coloring {
from { background-color: red; }
33% { background-color: yellow; }
66% { background-color: green; }
to { background-color: blue; }
}
Опробуемfrom,toи промежуточные кадры в деле!
@keyframes: группировка кадров[4/31]
Ключевые кадры вkeyframesможно группировать, для этого нужно перечислить их через запятую. Рассмотрим пример:
@keyframes stretching {
0%, 50% {
width: 100px;
}
100% {
width: 200px;
}
}
В этом примере первые два кадра сгруппированы. Анимируемый элемент сначала изменит свою ширину до100pxи останется в этом состоянии половину времени анимации. А за вторую половину времени он растянется от100pxдо200px.
Множественная анимация, шаг 1[5/31]
Одному элементу могут быть одновременно назначены несколько анимаций.
Если в этих анимациях меняются разные свойства элемента, то они будут проигрываться одновременно.
В этом и следующем задании попробуем создать множественную анимацию одного объекта. Сначала давайте создадим и назначим первую анимацию.
Множественная анимация, шаг 2[6/31]
Теперь разберём, как добавить элементу вторую параллельную анимацию.
Допустим, у нас есть две анимации:
@keyframes move {
to { left: 100px; }
}
@keyframes stretch {
to { width: 100px; }
}
Чтобы назначить элементу вторую анимацию, нужно добавить её название и длительность через запятую в свойствахanimation-nameиanimation-duration. Вот так:
.element {
animation-name: move, stretch;
animation-duration: 5s, 5s;
}
В этом примере две анимации запустятся одновременно, элемент будет параллельно двигаться и удлиняться в течение 5-ти секунд.
Множественные анимации задаются так же, как и множественные фоны и тени — с помощью перечисления свойств через запятую.
Добавим к элементу изпрошлого шагавторую анимацию.
Количество проигрываний анимации: animation-iteration-count[8/31]
Во всех предыдущих примерах мы создавали анимации, которые проигрывались один раз, а потом элемент возвращался в исходное состояние. Мы можем определять сколько раз будет повторяться анимация. Для этого используется свойствоanimation-iteration-count.
В качестве значения оно принимает положительные числа и ноль: при нуле анимация не будет выполнена, в остальных случаях она повторится указанное число раз.
Также в качестве значенияanimation-iteration-countможет быть использовано служебное словоinfinite. Оно означает, что анимация будет выполняться бесконечно и никогда не завершится.
Попробуем задавать разное число проигрываний анимации.
Направление анимации: animation-direction, шаг 1[9/31]
Помимо количества проигрываний анимации, мы можем определить её направление с помощью свойстваanimation-direction. По умолчанию анимация имеет прямое направлениеnormal.
Но можно назначить и обратный порядок анимации, чтобы проигрывание начиналось с конца и шло к началу (то есть за начальную точку считался кадрto, а за конечную —from). Для этого используется значениеreverseсвойстваanimation-direction.
Попробуем сравнить два направления анимации на примере.
В браузере Safari 8 и ниже направление анимацииreverseработает некорректно. Задание можно выполнить в другом браузере.
Направление анимации: animation-direction, шаг 2[10/31]
У свойстваanimation-directionесть ещё два значения. Они используются, когда количество проигрываний анимацииanimation-iteration-countбольше одного. И оба они определяют чередующееся направление анимации.
Если задано значениеalternate, то нечётные проигрывания будут выполняться в прямом направлении, а чётные — в обратном.
.element {
animation-name: move;
animation-duration: 1s;
animation-iteration-count: 2;
animation-direction: alternate;
}
В примере анимацияmoveвыполнится два раза: в первый (нечётный) раз направление будет прямым, а во второй (чётный) — обратным.
Если задано значениеalternate-reverse, то нечётные проигрывания наоборот будут выполняться в обратном направлении, а чётные — в прямом.
Рассмотрим это на наглядном примере.
В браузере Safari 8 и ниже направление анимацииalternate-reverseработает некорректно. Задание можно выполнить в другом браузере.
Задержка начала анимации: animation-delay, шаг 1[11/31]
Кроме длительности анимации, мы можем управлять задержкой перед началом её выполнения.
В этом и двух следующих заданиях мы создадим две анимации, которые в итоге будут выполняться последовательно с помощью задержки. Сначала давайте создадим и назначим первую анимацию.
Задержка начала анимации: animation-delay, шаг 3[13/31]
Синтаксис свойстваanimation-delay, с помощью которого и назначается задержка начала, идентичен синтаксису свойстваanimation-duration.
Например, при задании значенияanimation-delay: 10sанимация начнётся не сразу, а только через десять секунд.
Давайте завершим нашу сцену с часами, чтобы колокольчик звонил только после прохождения стрелкой полного круга.
Состояние до и после анимации: animation-fill-mode, шаг 1[15/31]
В предыдущих примерах элементы после проигрывания анимации возвращались в исходное состояние. Но есть свойство, которое определяет, будет ли видимым эффект от анимации, когда сама анимация уже закончилась — этоanimation-fill-mode. При задании свойству значенияforwardsэлемент будет сохранять состояние после завершения анимации.
Рассмотрим, как работает это свойство, на примере: к двум идентичным объектам применим одинаковую анимацию, а потом у одного изменим значение свойстваanimation-fill-modeи посмотрим, что будет.
Состояние до и после анимации: animation-fill-mode, шаг 3[17/31]
Другое значение свойстваanimation-fill-mode—backwards. Это значение определяет состояние элемента до начала анимации.
Если элементу назначена анимация с задержкой начала проигрывания иanimation-fill-mode: backwards, то стили, описанные в первом ключевом кадреfromили0%, будут применены сразу, ещё до начала проигрывания анимации.
Состояние до и после анимации: animation-fill-mode, шаг 5[19/31]
Третье значение свойстваanimation-fill-mode—both.
Оно объединяет действияforwardsиbackwards. То есть до начала анимации элементу присваивается состояние первого ключевого кадра, а после завершения — конечное состояние анимации сохраняется.
Действиеanimation-fill-mode: bothраспространяется и на многоразовую, и на чередующуюся анимацию.
Проведём финальный эксперимент!
Остановка и запуск анимации: animation-play-state[22/31]
Ещё одно управляющее свойство CSS-анимаций —animation-play-state. С его помощью можно поставить анимацию «на паузу», а потом возобновить с места остановки.
Свойство принимает два значенияrunningиpaused. Как видно из названий,pausedприостанавливает анимацию, аrunningначинает или возобновляет анимацию, поставленную на паузу. Значениеrunningзадано по умолчанию.
Попробуем создать анимацию и управлять процессом её проигрывания.
«Форма» анимации, animation-timing-function[23/31]
И, наконец, самое интересное свойство —animation-timing-function. Оно определяет, как именно будет происходить анимация: с какой скоростью и ускорением будут меняться свойства, задействованные в ней.
В предыдущих примерах анимация проигрывалась с одинаковой динамикой, мы меняли лишь её длительность, но не «форму». Эта «форма» по умолчанию соответствует первому графику, из которого видно, что анимация начинается медленно, затем ускоряется и к концу движения опять замедляется.
Так ведёт себя значениеeaseсвойстваanimation-timing-function.
ease
linear
Но мы можем сделать проигрывание анимации равномерным, без ускорений и замедлений. Для этого нужно использовать значениеlinear. Как видно на втором графике, анимация будет проигрываться с неизменной скоростью.
animation-timing-function, шаг 2[24/31]
Вот ещё несколько форм анимации:ease-in,ease-outиease-in-out.
ease-in
ease-out
ease-in-out
Из графиков видно, что при значенииease-inанимация медленно начинается, а к концу ускоряется; приease-out— начинается быстро, а к концу замедляется. Значениеease-in-outпохоже наease, то есть анимация начинается и заканчивается медленно, но происходит это чуть-чуть интенсивнее.
Испробуем эти значения свойстваanimation-timing-function.
animation-timing-function, шаг 3[25/31]
Что же скрывается за названиямиlinear,easeи других функций? Довольно сложная математика кубическихкривых Безье.
По сути, именованные функцииease-in,ease-outи другие являются псевдонимами для универсального описания кривых, например:
cubic-bezier(0, 0, 1, 1) // это linear
cubic-bezier(0.42, 0, 1, 1) // это ease-in
В общем представленииcubic-bezier(x1, y1, x2, y2)значенияxиy— это координаты точек кривых на графике. При этом верным считается значениеxтолько в диапазоне от0до1.
Существуетотличный сервис, помогающий разобраться в функциональном представлении кривых Безье без необходимости штудировать учебники по математике.
А вот по этойссылкеможно найти целую коллекцию разных easing-функций на основе кривых Безье.
animation-timing-function, шаг 4[26/31]
Давайте разберёмся с ещё одним возможным классом значенийanimation-timing-function— этоsteps.
Они позволяют задать «ступеньки», по которым будет идти анимация. Синтаксисstepsследующий:
animation-timing-function: steps(число_шагов, направление);
Тут всё просто: число шагов — это целое число, за которое будет выполнена вся анимация; направление может принимать значениеstartилиend.
При заданномstartпервый шаг выполняется одновременно с началом анимации, а в случае cendпоследний шаг будет выполнен вместе с завершением анимации. То есть приstartпошаговая анимация идёт как бы с опережением, а приend— вдогонку.