Свойства - Keyframes, animation-timing-function, animation-delay
Статья Рейчел Коуп с моими дополнениями (2014-2016). Несмотря на давность - актуальная во все времена. Человеческий мозг всегда обращает внимание на движущиеся объекты. Из-за этого естественного рефлекса добавление анимации на ваш сайт или приложение является мощным способом привлечения внимания пользователей к важным областям вашего продукта.Если анимация на сайте реализована правильно, то это добавляет ценное взаимодействие и обратную связь, а также увеличить эмоциональный опыт, принести восхищение и добавить индивидуальность к Вашему интерфейсу. Фактически, оживить означает оживить.
Основной целью эмоционального дизайна является содействие коммуникации между людьми. Если мы хорошо справляемся со своей работой, компьютер отступает на задний план, и персонажи поднимаются на поверхность.
Ааррон Уолтер
В этом посте описаны основы CSS- анимации. Здесь вы можете перейти и просматривать код CSS для анимации (страница открывается в отдельном окне) всех приведенных примеров.
Два основных блока анимации.
CSS-анимация основывается на двух основных блоках:
- Keyframes - этапы и стили анимации
- Свойства анимации - присвойте @keyframes определенному элементу CSS и определите, как он анимируется.
Давайте, рассмотрим каждый блок подробнее.
Keyframes - первый блок
Keyframes являются основой анимации CSS. Они определяют, как выглядит анимация на каждом этапе. Каждый из @keyframes
состоит из:
- Названия анимации: имя, которое описывает анимацию, например
bounceIn
.
- Этапы анимации: каждый этап анимации представлен в процентах.
0% -
начальное состояние анимации.100% -
конечное состояние анимации. Между промежуточными состояниями могут быть добавлены промежуточные состояния.
- Свойства CSS: свойства CSS, определенные для каждого этапа временной шкалы анимации.
Давайте рассмотрим простой, @keyframes
который называется «bounceIn». Он получается в три этапа.
- на первом этапе
(0%) -
элемент имеет непрозрачность 0 и уменьшен до 10 процентов от его размера по умолчанию, используя масштаб преобразования CSS. - на втором этапе
(60%)
элемент исчезает до полной непрозрачности и увеличивается до 120 процентов от его размера по умолчанию. - на заключительном этапе
(100%)
он немного уменьшится и вернется к размеру по умолчанию.
Вот как это выглядит в файле CSS:
@keyframes bounceIn { 0% { transform: scale(0.1); opacity: 0; } 60% { transform: scale(1.2); opacity: 1; } 100% { transform: scale(1); } }
Если вы не знакомы с CSS Transforms, то вам нужно ознакомиться с этим свойством здесь. Комбинации transform и остальных свойств в CSS-анимации действительно похоже на волшебство. :-)
Свойства анимации - второй блок
После того, как @keyframes
определены, должны быть добавлены свойства анимации для того, чтобы ваша анимация функционировала.
Свойства анимации делают две вещи:
- Они присваивают
@keyframes
элементам, которые вы хотите оживить. - Они определяют, как эти элементы анимируется.
Свойства анимации добавляются в CSS-селектор (или элемент), который вы хотите оживить. Чтобы анимация начала действовать, необходимо добавить следующие два свойства анимации:
animation-name
: имя анимации, определенное в@keyframes
.animation-duration
: продолжительность анимации, в секундах (например, 5 секунд) или миллисекундах (например, 200 мс).
Продолжая приведенный выше bounceIn
пример, мы добавим animation-name
и animation-duration
в div, которые хотим оживить.
div { animation-duration: 2s; animation-name: bounceIn; }
Сокращенный синтаксис:
div { animation: bounceIn 2s; }
Добавляя @keyframes и свойства анимации, мы имеем простую анимацию только при помощи CSS:
Bouce In
В целом у меня получился вот такой CSS. За количество показов нашего эффекта отвечает свойство animation-iteration-count (о нем будет рассказано ниже). Я поставила бесконечное количество (infinite).
.bounceIn { color: darkturquoise; font-family: lato; font-weight: 500; font-size: 60px; text-align: center; text-transform: uppercase; -webkit-animation: bounceIn 3.5s both 3s; animation-iteration-count: infinite; margin-top: 20px; } @-webkit-keyframes bounceIn{ 0% { transform: scale(0.1); -webkit-transform: scale(0.1); opacity: 0; } 60% { transform: scale(1.2); -webkit-transform: scale(1.2); opacity: 1; } 100% { transform: scale(1); -webkit-transform: scale(1); } } @keyframes bounceIn{ 0% { transform: scale(0.1); -webkit-transform: scale(0.1); opacity: 0; } 60% { transform: scale(1.2); -webkit-transform: scale(1.2); opacity: 1; } 100% { transform: scale(1); -webkit-transform: scale(1); } }
Animation
Каждое свойство анимации можно определить индивидуально, но для более чистого и быстрого кода рекомендуется использовать сокращенную анимацию. Все свойства анимации добавляются к одному и тому же animation:
свойству в следующем порядке:
animation: [animation-name] [animation-duration] [animation-timing-function] [animation-delay] [animation-iteration-count] [animation-direction] [animation-fill-mode] [animation-play-state];
Просто помните, чтобы анимация функционировала правильно, вам нужно следовать правильному порядку (при сокращении) и указать, по крайней мере, первые два значения.
Примечания о префиксах
По состоянию на конец 2014 года многие браузеры, основанные на Webkit, по- прежнему используют версию -webkit-prefixed как анимаций ключевых кадров, так и для переходов.
Ключевые фреймы и анимации с префиксами WebKit:
div { -webkit-animation-duration: 2s; animation-duration: 2s; -webkit-animation-name: bounceIn; animation-name: bounceIn; }
И
@-webkit-keyframes bounceIn { /* styles */ } @keyframes bounceIn { /* styles */ }
Чтобы сделать вашу жизнь проще, рассмотрите возможность использования Bourbon , библиотеки Sass mixin, которая содержит современные префиксы поставщиков для всех современных браузеров. Вот как это просто создать анимацию и ключевые кадры с использованием префикса с использованием Bourbon:
div { @include animation(bounceIn 2s); }
И
@include keyframes(bouncein) { /* styles */}
Дополнительные свойства анимации
Помимо требуемых для анимации - имени и продолжительности, вы можете настроить и создать сложные анимации , используя следующие свойства:
- animation-timing-function
- animation-delay
- animation-iteration-count
- animation-direction
- animation-fill-mode
- animation-play-state
Animation-timing-function
Animation-timing-function: определяет скорость или темп анимации. Работает со следующими заранее определенными параметрами: ease, linear, ease-in, ease-out, ease-in-out, initial, inherit. (Или для более сложных вариантов - создание собственных функций анимации с использованием кривой кубика Безье.)
.
.
.
.
.
.
Мой код для этих прыгающих шариков следующий:
.container_bezie { margin: 50px 0 0 200px; display: inline-block; } .circle_bezie { border-radius: 50%; height: 30px; width: 30px; margin: 10px; float: left; animation-name: bounceInDown; -webkit-animation-name: bounceInDown; animation-duration: 2s; -webkit-animation-duration: 2s; animation-iteration-count: infinite; -webkit-animation-iteration-count: infinite; animation-direction: alternate; -webkit-animation-direction: alternate; } .circle0__bezie { border-radius: 50%; height: 30px; width: 30px; margin: 10px; float: left; animation-name: bounceInDown; -webkit-animation-name: bounceInDown; animation-duration: 2s; -webkit-animation-duration: 2s; animation-iteration-count: infinite; -webkit-animation-iteration-count: infinite; animation-direction: alternate; -webkit-animation-direction: alternate; background: PaleTurquoise; animation-timing-function: ease; -webkit-animation-timing-function: ease; } .circle1_bezie { border-radius: 50%; height: 30px; width: 30px; margin: 10px; float: left; animation-name: bounceInDown; -webkit-animation-name: bounceInDown; animation-duration: 2s; -webkit-animation-duration: 2s; animation-iteration-count: infinite; -webkit-animation-iteration-count: infinite; animation-direction: alternate; -webkit-animation-direction: alternate; background: salmon; animation-timing-function: linear; -webkit-animation-timing-function: linear; } .circle2_bezie { border-radius: 50%; height: 30px; width: 30px; margin: 10px; float: left; animation-name: bounceInDown; -webkit-animation-name: bounceInDown; animation-duration: 2s; -webkit-animation-duration: 2s; animation-iteration-count: infinite; -webkit-animation-iteration-count: infinite; animation-direction: alternate; -webkit-animation-direction: alternate; background: lightskyblue; animation-timing-function: ease-in; -webkit-animation-timing-function: ease-in; } .circle3_bezie { border-radius: 50%; height: 30px; width: 30px; margin: 10px; float: left; animation-name: bounceInDown; -webkit-animation-name: bounceInDown; animation-duration: 2s; -webkit-animation-duration: 2s; animation-iteration-count: infinite; -webkit-animation-iteration-count: infinite; animation-direction: alternate; -webkit-animation-direction: alternate; background: khaki; animation-timing-function: ease-out; -webkit-animation-timing-function: ease-out; } .circle4_bezie { border-radius: 50%; height: 30px; width: 30px; margin: 10px; float: left; animation-name: bounceInDown; -webkit-animation-name: bounceInDown; animation-duration: 2s; -webkit-animation-duration: 2s; animation-iteration-count: infinite; -webkit-animation-iteration-count: infinite; animation-direction: alternate; -webkit-animation-direction: alternate; background: mediumturquoise; animation-timing-function: ease-in-out; -webkit-animation-timing-function: ease-in-out; } .circle5_bezie { border-radius: 50%; height: 30px; width: 30px; margin: 10px; float: left; animation-name: bounceInDown; -webkit-animation-name: bounceInDown; animation-duration: 2s; -webkit-animation-duration: 2s; animation-iteration-count: infinite; -webkit-animation-iteration-count: infinite; animation-direction: alternate; -webkit-animation-direction: alternate; background: thistle; animation-timing-function: cubic-bezier(0,1,.98,0); -webkit-animation-timing-function: cubic-bezier(0,1,.98,0); } @-webkit-keyframes bounceInDown { 0%, 60%, 75%, 90%, 100% { -webkit-transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); } 0% { opacity: 0; -webkit-transform: translate3d(0, -200px, 0); transform: translate3d(0, -200px, 0); } 60% { opacity: 1; -webkit-transform: translate3d(0, 25px, 0); transform: translate3d(0, 25px, 0); } 75% { -webkit-transform: translate3d(0, -10px, 0); transform: translate3d(0, -10px, 0); } 100% { -webkit-transform: none; transform: none; } } @keyframes bounceInDown { 0%, 60%, 75%, 90%, 100% { -webkit-transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); } 0% { opacity: 0; -webkit-transform: translate3d(0, -200px, 0); transform: translate3d(0, -200px, 0); } 60% { opacity: 1; -webkit-transform: translate3d(0, 25px, 0); transform: translate3d(0, 25px, 0); } 75% { -webkit-transform: translate3d(0, -10px, 0); transform: translate3d(0, -10px, 0); } 100% { -webkit-transform: none; transform: none; } }
Значение по умолчанию, если не назначено никакое другое значение ease
, начинается медленно, ускоряется, а затем замедляется. Вы можете прочитать описание каждой функции синхронизации здесь .
Синтаксис CSS:
animation-timing-function: ease-in-out;
Синтаксис сокращения анимации (рекомендуется):
animation: [animation-name] [animation-duration] [animation-timing-function]; animation: bounceIn 2s ease-in-out;
Animation-delay
Animation-delay:
позволяет определить, когда начнется анимация (или часть анимации). Положительное значение (например, 2s) начнет анимацию через 2 секунды после ее запуска. Элемент останется без изменений до этого времени. Отрицательное значение (например, -2s) начнет анимацию сразу, но данный элемент заработает через 2 секунды относительно всех элементов анимации. Значение определяется в секундах или миллисекундах.
.
. . . . .
. . . . . . .
У меня получился вот такой код CSS. Время появления элементов в данном коде быстрее, чем у меня в примере и нет бесконечного количества появлений (то есть последовательность - появлятся солнце, затем облака, потом дождь. Всё - цикл закончен):
.wrapper_delay { width: 300px; margin: 0px 0 200px 200px; position: relative; } .sun { background: gold; border-radius: 50%; height: 90px; left: -20px; position: absolute; /*top: 120px;*/ width: 90px; animation: pulse .75s ease-in-out 2s both; -webkit-animation: pulse .75s ease-in-out 2s both; } .clouds-wrapper { position: absolute; top: 50px; animation: pulse .75s ease-in-out 3s both ; -webkit-animation: pulse .75s ease-in-out 3s both; } .clouds1 { position: absolute; background: Gainsboro; z-index: 20; } .clouds1:nth-child(1) { border-radius: 30px; height: 50px; width: 150px; box-shadow: -10px -5px 10px -2px rgba(255,255,255,1.0); } .clouds1:nth-child(2) { border-radius: 50%; height: 80px; margin-top: -40px; margin-left: 23px; width: 80px; box-shadow: -6px -10px 5px 0px rgba(255,255,255,1.0); } .clouds1:nth-child(3) { border-radius: 50%; height: 50px; margin-top: -25px; margin-left: 80px; width: 50px; } .rain { background: darkturquoise; border-radius: 5px; height: 10px; width: 40px; } .rain-wrapper { margin-left: 40px; position: absolute; top: 120px; } .rain-container { display: inline-block; transform: rotate(220deg); -webkit-transform: rotate(220deg); width: 10px; } .rain1 { background: darkturquoise; border-radius: 5px; height: 10px; width: 40px; animation: pulse .75s ease-in-out 3.5s both; -webkit-animation: pulse .75s ease-in-out 3.5s both; margin-left: -15px; } .rain2 { background: darkturquoise; border-radius: 5px; height: 10px; width: 40px; margin-left: -15px; animation: pulse .75s ease-in-out 3.9s both; -webkit-animation: pulse .75s ease-in-out 3.9s both; } .rain3 { background: darkturquoise; border-radius: 5px; height: 10px; width: 40px; margin-left: -15px; animation: pulse .75s ease-in-out 4.3s both; -webkit-animation: pulse .75s ease-in-out 4.3s both; } @keyframes pulse { 0%, 20%, 40%, 60%, 80%, 100% { -webkit-transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); } 0% { opacity: 0; -webkit-transform: scale3d(.3, .3, .3); transform: scale3d(.3, .3, .3); } 20% { -webkit-transform: scale3d(1.1, 1.1, 1.1); transform: scale3d(1.1, 1.1, 1.1); } 40% { -webkit-transform: scale3d(.9, .9, .9); transform: scale3d(.9, .9, .9); } 60% { opacity: 1; -webkit-transform: scale3d(1.03, 1.03, 1.03); transform: scale3d(1.03, 1.03, 1.03); } 100% { opacity: 1; -webkit-transform: scale3d(1, 1, 1); transform: scale3d(1, 1, 1); } } @-webkit-keyframes pulse { 0%, 20%, 40%, 60%, 80%, 100% { -webkit-transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); } 0% { opacity: 0; -webkit-transform: scale3d(.3, .3, .3); transform: scale3d(.3, .3, .3); } 20% { -webkit-transform: scale3d(1.1, 1.1, 1.1); transform: scale3d(1.1, 1.1, 1.1); } 40% { -webkit-transform: scale3d(.9, .9, .9); transform: scale3d(.9, .9, .9); } 60% { opacity: 1; -webkit-transform: scale3d(1.03, 1.03, 1.03); transform: scale3d(1.03, 1.03, 1.03); } 100% { opacity: 1; -webkit-transform: scale3d(1, 1, 1); transform: scale3d(1, 1, 1); } }