Руководство по CSS анимации: Принципы и примеры

alexei28/12/2022 - 17:56
Руководство по CSS анимации. Принципы и примеры

В этой статье мы сделаем наши первые шаги в CSS анимации и рассмотрим основные рекомендации по созданию анимации с помощью CSS. Мы будем все изучать на примерах, создавая анимацию, используя принципы традиционной анимации.

Поскольку CSS анимация теперь поддерживается как в браузерах Firefox, так и в Webkit, нет лучшего времени, чтобы попробовать ее на практике. Независимо от ее технической формы, будь то традиционная, компьютерная 3D, Flash или CSS, анимация всегда следует одним и тем же основным принципам.

В этой статье мы сделаем наши первые шаги в CSS анимации и рассмотрим основные рекомендации по ее созданию. Мы будем работать на примере, создавая анимацию, используя принципы традиционной анимации. Наконец, мы увидим некоторые примеры использования CSS анимации в реальном мире.

Иллюстрация, показывающая различные кадры традиционной анимации прыгающего мяча
Иллюстрация, показывающая различные кадры традиционной анимации прыгающего мяча

CSS свойство animation

Прежде, чем погрузиться в детали, давайте определимся с основами.

animation - это новое свойство CSS, которое позволяет анимировать большинство элементов HTML (таких как div, h1, span) без JavaScript или Flash. На данный момент оно поддерживается в большинстве браузерах. Неподдерживаемые браузеры просто проигнорируют ваш код анимации, поэтому убедитесь, что работоспособность вашей страницы от данного кода не зависит!

Для некоторых браузеров требуется указывать префиксы. Синтаксис абсолютно одинаков для всех браузеров, требуется только добавить соответствующий префикс.

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


/* Это код анимации. */
@keyframes example {
   from { transform: scale(2.0); }
   to   { transform: scale(1.0); }
}

/* Это элемент, к которому мы применяем анимацию. */
div {
   animation-name: example;
   animation-duration: 1s;
   animation-timing-function: ease;
   animation-delay: 1s;
   animation-iteration-count: 2;
   animation-direction: alternate;
}

Сначала мы создаем сам код анимации. Он может определяться в любом месте таблицы стилей. Главное, чтобы анимируемый элемент мог найти код, заданный в свойстве animation-name.

Также, для прикрепления анимации к элементу можно использовать короткую форму записи:


div {
   animation: example 1s ease 1s 2 alternate;
}

При этом нам не обязательно определять все значения. Для не заданных значений браузер будет использовать значения по умолчанию.

Это основы. Теперь рассмотрим все более подробно.

Применение принципов традиционной анимации

Компания Disney — на наш взгляд, мастера традиционной анимации — с самого начала разработала 12 принципов традиционной анимации и задокументировала их в своей знаменитой книге "Иллюзия жизни". Эти основные принципы могут быть применены ко всем видам анимации, и вам не нужно быть экспертом в анимации, чтобы следовать им. Мы рассмотрим пример CSS анимации, в которой используются эти 12 принципов, превращая базовую анимацию в более правдоподобную иллюзию.

Наш пример демонстрирует особенности CSS анимации. В приведенном ниже коде мы используем пустые элементы div, чтобы показать, как это работает; это не самый семантический способ кодирования, но смысл в том, чтобы показать, насколько просто теперь оживить страницу.

СЖАТИЕ И РАСТЯЖЕНИЕ

Эскиз мяча в преувеличенно сплющенном и растянутом состоянии
Эскиз мяча в преувеличенно сплющенном и растянутом состоянии

Прыгающий мяч - отличная демонстрация первого пункта. Если мяч падает с высокой скоростью и ударяется об пол, то вы увидите, как под воздействием сил он сначала сжимается, а затем, когда подпрыгивает, вытягивается обратно.

На базовом уровне это должно придать нашей анимации ощущение веса и гибкости. Если бы мы уронили шар для боулинга, мы бы вообще не ожидали, что он будет сплющиваться; скорее он пробьет пол.

Создать эффект сплющивания и растяжения мы можем при помощи CSS свойства transform:


@keyframes example {
   0% { transform: scaleY(1.0); }
   50% { transform: scaleY(1.2); }
   100% { transform: scaleY(1.0); }
}

Это масштабирует длину объекта (по оси y, вверх и вниз) в 1,2 раза от исходного размера, а затем возвращает к исходному размеру.

Мы также используем более сложный тайминг для этой анимации. Для базовой анимации вы можете использовать from и to. Также, в своей анимации вы можете определять несколько действий используя проценты, как это сделали мы.

Это охватывает сжатие мяча во время удара. Теперь нам нужно переместить объект с помощью translate. Мы можем объединять преобразования:


50% {
   transform: translateY(-300px) scaleY(1.2);
}

Свойство translate позволяет манипулировать объектом, не изменяя никаких его базовых свойств (таких как положение, ширина или высота), что делает его идеальным для CSS анимации. В данном случае создается впечатление, что мяч отскакивает от пола в середине анимации.

ПРЕДВКУШЕНИЕ

Предвкушение добавляет напряженность или ощущение мощи перед основным действием. Например, сгибание ног перед прыжком помогает зрителям предвидеть, что будет дальше. В случае с нашим прыгающим мячом простое добавление тени дает предположение, что что-то падает сверху.

Мы добавили еще один элемент div, который будет представлять тень. Его мы будем анимировать отдельно от мяча.

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


@keyframes example {
   0% { transform: translateY(-300px) scaleY(1.2); }
   35% { transform: translateY(-300px) scaleY(1.2); } /* Та же позиция, что и 0% */
   65% { transform: translateY(0px) scaleY(1.2); }    /* Начинает движение после 35% до этой позиции */
   67% { transform: translateY(10px) scaleY(0.8); }
   85% { transform: translateY(-100px) scaleY(1.2); }
   100% { transform: translateY(0px); }
}

В точке анимации 35% мяч все еще находится за пределами сцены и не двигается. Затем, между точками 35% и 65%, он внезапно выходит на сцену, и дальше воспроизводится остальная часть анимации.

Также, для создания момента ожидания можно использовать свойство animation-delay:


div {
   animation-delay: 1s;
}

Однако, это может иметь нежелательный эффект. Дело в том, что свойство animation-delay просто игнорирует любой код анимации на заданное временя. Таким образом, если ваша анимация начинается с позиции, отличающейся от анимируемого элемента, то объект рывком внезапно появится, как только начнется отложенная анимация.

Это свойство лучше всего работает с зацикленной анимацией, которая начинается и заканчивается в одной и той же позиции.

ПОСТАНОВКА ИЛИ СЦЕНИЧНОСТЬ

Попробуйте добавить своей сценке декорации: поместите анимацию внутри контекста. Вспомните знаменитые мультфильмы: чем бы они были без изумительных фонов? Это половина всей магии!

Сцена - это ключ к фокусированию внимания. Как и на театральной сцене, освещение будет акцентировать внимание на самой важной области. Сцена должна усиливать иллюзию. В случае с нашим прыгающем мячом можно добавить простой фон, чтобы сфокусироваться на том, куда приземлится мяч.

ПРЯМО ВПЕРЕД VS ОТ ПОЗЫ К ПОЗЕ

В традиционной анимации это способ построения анимации. Вариант "прямо вперед" – это, когда рисуется каждый кадр анимационной последовательности. Вариант "от позы к позе" – это, когда создается несколько ключевых кадров по всей анимационной последовательности, а затем заполняются промежутки между ними.

В CSS анимации обычно используется второй способ - "от позы к позе". То есть, мы добавляем ключевые кадры действия, а затем браузер автоматически "подставляет" промежуточные кадры. Тем не менее, прямолинейный вариант также можем оказаться полезным. Дело в том, что браузер может создавать не так много эффектов; иногда, чтобы получить желаемый результат, приходится идти по более сложному пути и добавлять больше анимаций.

ПРОДОЛЖЕНИЕ ДЕЙСТВИЯ И ПЕРЕКРЫТИЕ

Также известные как физика! Повторение и наложение действия чаще всего используются в анимации персонажей для демонстрации движения, например, чтобы показать, как покачиваются руки, когда персонаж их роняет, или падают длинные волосы. Представьте себе человека с большим животом, который быстро поворачивается: сначала поворачивается его тело, а вскоре за ним следует выпуклый живот.

В нашем случае это означает правильное понимание физики при падении мяча. В приведенных выше примерах мяч будет падать неестественно, как будто неподвластный гравитации. Мы же хотим, чтобы мяч сначала упал, а затем отпрыгнул. Однако это лучше всего достигается с помощью следующего принципа.

ПЛАВНЫЙ ВХОД И ПЛАВНЫЙ ВЫХОД

Этот принцип должен осуществляться с помощью ускорения и замедления. Представьте себе автомобиль, который мчится вперед и должен остановиться. Если бы он остановился мгновенно, то это бы было неправдоподобно. Мы знаем, что автомобилям требуется время, чтобы замедлиться, поэтому нам пришлось бы анимировать торможение и постепенную остановку автомобиля.

То же самое и с демонстрацией эффекта гравитации. Представьте ребенка на качелях. По мере приближения к наивысшей точке качели будут замедляться. Когда они возвращаются обратно вниз, то набирают скорость, - их самая быстрая точка будет в нижней части дуги. Затем они поднимутся в противоположную сторону, и все повторится.

Диаграмма, показывающая качание на качелях. В верхней части движения скорость снижается, в нижней и средней - увеличивается.
Диаграмма, показывающая качание на качелях. В верхней части движения скорость снижается, в нижней и средней - увеличивается.

Возвращаясь к нашему примеру, регулируя скорость входа и выхода, мы можем сделать движение мяча намного более правдоподобным.

Когда мяч ударится об пол, удар заставит его мгновенно отскочить назад. По мере того, как он приближается к высшей точке, он замедляется. Теперь будет похоже, что мяч действительно падает.

В CSS мы можем это контролировать при помощи свойства animation-timing-function. Например,


animation-timing-function: ease-out;

Это свойство принимает следующие значения:

  • ease-in - Вначале медленно, а затем ускоряется.
  • ease-out - Вначале быстро, а затем замедляется до остановки.
  • ease-in-out - Начинается медленно, ускоряется в середине, а затем замедляется до остановки.
  • linear - Движется с одинаковой скоростью от начала до конца.

Также, можно при помощи функции bezier-curve самому определить скорости смягчения движения.

ДУГИ

Диаграмма, показывающая дугообразную траекторию, по которой будет двигаться мяч при отскоке
Диаграмма, показывающая дугообразную траекторию, по которой будет двигаться мяч при отскоке

Подобно принципу "продолжение движения" в физике, дуги следуют основному принципу "то, что идет вверх, должно идти вниз". Дуги возникают, когда дело доходит до траектории объекта.

Давайте бросим мяч слева от сцены. Убедительная анимация предсказала бы дугу, по которой упадет мяч; и в нашем примере она должна будет предсказать следующую дугу, по которой упадет мяч после того, как отскочит от пола.

Такую анимацию может быть несколько сложнее построить в CSS. Мы должны анимировать движение мяча вверх и вниз и из стороны в сторону одновременно. То есть, нам нужно, чтобы наш мяч плавно двигался слева направо, при этом прыгая вверх вниз (анимация, над которой мы работали до сих пор). И здесь, вместо того, чтобы пытаться охватить оба действия в одной анимации, мы сделаем две отдельные анимации. Это значительно упростит нашу задачу. Для этого мы обернем наш мяч в еще один элемент div и анимируем его отдельно.

HTML:


<div class="ball-arc">
   <div class="ball"></div>
</div>

CSS:


.ball-arc {
   animation: ball-x 2.5s cubic-bezier(0, 0, 0.35, 1);
}

   /* Здесь cubic-bezier настраивает скорость animation-timing.
   В этом примере мячу требуется больше времени, чтобы замедлиться. */

@keyframes ball-x {
   0% { transform: translateX(-275px); }
   100% { transform: translateX(0px); }
}

Здесь у нас есть одна анимация для перемещения мяча вбок (ball-x) и другая анимация для отскока мяча (ball-y). Единственным недостатком такого подхода является то, что если вы захотите сделать что-то действительно сложное, то у вас может получиться настоящая мешанина из кода с плохой семантикой!

ВТОРОСТЕПЕННЫЕ ДЕЙСТВИЯ

Второстепенное действие – это та тонкость, которая делает анимацию более реалистичной. Они представляют детали. Например, если бы у нас был некий идущий персонаж с длинными волосами, то первичным действием была бы ходьба, а вторичным действием было бы движение волос или, возможно, развевание одежды на ветру.

В нашем примере с мячом все намного проще. Мы сделаем вторичным действием вращение мяча. Это создаст иллюзию, что мяч бросили.

Вместо того, чтобы для этой анимации добавлять еще один элемент div, мы добавим ее к элементу img, который мы используем для наложения текстуры на мяч.


.ball img {
   animation: spin 2.5s;
}

@keyframes spin {
   0% { transform: rotate(-180deg); }
   100% { transform: rotate(360deg); }
}

ТАЙМИНГИ

Диаграмма, показывающая разную скорость движения мяча за одно и то же время
Диаграмма, показывающая разную скорость движения мяча за одно и то же время

Это просто тайминг или длительность вашей анимации. Чем лучше подобран тайминг анимации, тем реалистичнее она будет выглядеть.

Наш мяч - прекрасный пример этого. Текущая скорость примерно подходит для мяча подобного размера. Если бы это был шар для боулинга, мы бы ожидали, что он будет двигаться намного быстрее. При этом, если бы скорость анимации была несколько меньше, то это выглядело бы так, как будто мы играем в теннис в космосе. Правильный выбор времени выполнения анимации помогает ей выглядеть реалистично.

Тайминги можно настроить при помощи свойства animation-duration. При этом, можно определять индивидуальные тайминги вашей анимации, используя процентные значения.

ПРЕУВЕЛИЧЕНИЕ

Мультфильмы известны преувеличением или невозможной физикой. Мультяшный персонаж может принять любую форму и при этом вернуться в нормальное состояние. Однако в большинстве случаев преувеличение используется для акцентирования внимания, чтобы оживить действие, которое в противном случае в анимации выглядело бы плоским.

Тем не менее, не стоит злоупотреблять преувеличениями. У Диснея было правило основывать свои анимации на реальности, но двигать их немного дальше. Представьте персонажа, врезающегося в стену; чтобы подчеркнуть силу удара, его тело вдавливается в стену сильнее, чем ожидалось.

Мы используем преувеличение с сжатием и растяжением (в фазе удар/отскок), чтобы сделать момент соприкосновения мяча с полом более очевидным. Мы также добавили в анимацию легкое подрагивание. Наконец, мы также растягиваем и сплющиваем мяч, когда он подпрыгивает вверх и вниз, чтобы подчеркнуть скорость.

Так же, как мы уже делали ранее, добавляя одну анимацию к другой, здесь мы добавим еще один элемент div, который будет дрожать одновременно с ударом мяча об пол:


@keyframes wobble {

0%, 24%, 54%, 74%, 86%, 96%, 100% {
   transform: scaleX(1.0);
/* В этой точке делаем мяч нормального размера */
}

25%, 55%, 75% {
   transform: scaleX(1.3) scaleY(0.8) translateY(10px);
/* Обозначает удар об пол: эффект сплющивания */
}

30%, 60%, 80% {
   transform: scaleX(0.8) scaleY(1.2);
/* Подрагивание после удара об пол */
}

75%, 87% {
   transform: scaleX(1.2);
/* Маленькое сплющивание для последних нескольких отпрыгиваний */
}

97% {
   transform: scaleX(1.1);
/* Еще меньшее сплющивание для последнего отпрыгивания */
}

}

Код выглядит более сложным, чем он есть на самом деле. Здесь действует простой метод проб и ошибок. Продолжайте пробовать, пока не получите нужный эффект!

ЧЕТКИЙ РИСУНОК И ПРИВЛЕКАТЕЛЬНОСТЬ

Ну вот вы и научились всему… по крайней мере, что касается кода. Данные два последних принципа анимации нельзя продемонстрировать кодом. Это навыки, которые вам нужно усовершенствовать самостоятельно, чтобы создавать действительно потрясающие анимации.

Когда Уолт Дисней начал производство своей "Белоснежки", он вновь посадил своих аниматоров за парту и заставил заново изучать человеческий облик. И это внимание к деталям заметно в фильме, который явно показывает, что хорошая анимация требует основательных навыков рисования и глубоких знаний анимируемых форм.

Безусловно большинство CSS анимаций, скорее всего, не будут такими же сложными, как персонажи мультфильма, но базовый принцип все же остается тем же. Независимо от того, открывается ли дверь, чтобы показать содержимое, или запечатывается и доставляется конверт с надписью "свяжитесь с нами", анимация должна быть правдоподобной, а не роботизированной... если вы, конечно, не анимируете робота.

Привлекательность или харизма каждого персонажа будет уникальной. Но, как всегда показывал Уолт Дисней, все может иметь характер: чайник, дерево и даже ложки. Но с CSS следует продумывать то, как ваша анимация будет способствовать дизайну и сделает общее впечатление более приятным.

Действуйте и анимируйте!

CSS анимация может быть использована для того, чтобы действительно оживить веб-сайт. Хотя код для нашего прыгающего мяча и не самый семантически продуманный, мы надеемся, что он демонстрирует, насколько просто с помощью CSS можно оживить практически все на странице.

CSS анимация способна привнести столь необходимую интерактивность вашим элементам, добавить увлекательности странице, а в сочетании с JavaScript она даже может стать альтернативным способом анимации в играх. Взяв на вооружение 12 принципов, описанных выше, и поработав над анимацией, вы сможете сделать свои сайты более убедительными, привлекательными и захватывающими, что приведет к улучшению общего впечатления.