Анимация в CSS3. Часть I
Чаще всего масштабные анимации на сайтах делаются с помощью технологии Flash. Для более мелких эффектов, например таких, как эффект выпадающего окошка, используется JavaScript. Я использую для этого любимую библиотеку jQuery и ее функцию animate. Ее работа меня вполне устраивает.
Но новое время предоставляет новые возможности. Safari 4+ и Chrome 3+ уже сейчас поддерживают возможность задать анимационные эффекты на странице с помощью CSS3. Рано или поздно остальные браузеры тоже поддержат эту инициативу. Чтобы не отстать от жизни, верстальщик должен знать CSS3 свойства, которые отвечают за CSS анимацию, и уметь задавать разнообразные анимационные эффекты элементам, не используя JavaScript.
Итак, начнем.
Теоретические сведения
Для задания CSS3 анимации элементу используется CSS3 свойство animation. Это свойство — сокращенная запись различных свойств анимации:
- animation-name — задает имя анимации
- animation-duration — задает время проигрывания анимации
- animation-timing-function — описывает метод расчета промежуточных значений свойств для анимации
- animation-delay — задает задержку анимации
- animation-iteration-count — задает количество циклов анимации
- animation-direction — задает направление анимации
- animation-play-state — определяет, проигрывается ли анимация или стоит на паузе
В прямом виде эти CSS3 свойства не поддерживает ни один из распространенных браузеров, но Safari 4+ и Chrome 3+ уже сейчас поддерживают эти свойства с вендорным префиксом -webkit-:
- -webkit-animation-name — задает имя анимации
- -webkit-animation-duration — задает время проигрывания анимации
- -webkit-animation-timing-function — описывает метод расчета промежуточных значений свойств для анимации
- -webkit-animation-delay — задает задержку анимации
- -webkit-animation-iteration-count — задает количество циклов анимации
- -webkit-animation-direction — задает направление анимации
- -webkit-animation-play-state — определяет, проигрывается ли анимация или стоит на паузе
Имя анимации и список анимированных переходов для этого имени задается с помощью CSS3 правила @keyframes. Для Safari 4+ и Chrome 3+ используется @-webkit-keyframes.
Как это выглядит на практике
Анимация в CSS3 представляет собой плавное изменение значения какого-либо свойства. Рассмотрим простейший анимационный эффект: перемещение блока. Здесь и далее используем помимо CSS3 также рабочий вариант свойств с префиксом -webkit-.
div { position: relative; top: 50px; left: 0px; -webkit-animation-name: 'movement'; -webkit-animation-duration: 10s; animation-name: 'movement'; animation-duration: 10s; } @-webkit-keyframes 'movement' { from { top: 50px; left: 0px; } 50% { top: 150px; left: 100px; } to { top: 400px; left: 300px; } } @keyframes 'movement' { from { top: 50px; left: 0px; } 50% { top: 150px; left: 100px; } to { top: 400px; left: 300px; } }
Счастливые обладатели Safari 4+ и Chrome 3+ могут увидеть это на демо-примере. Для остальных поясняю, что произойдет.
Тут описана анимация перемещения (изменение координат блока с течением времени). В данном примере анимация состоит из 3-х кадров, но количество ключевых кадров может быть любым. В первый момент анимации, описываемый селектором кадра from, координаты блока top: 50px, left: 0px. Следующий ключевой кадр описывает значения свойств через 50% времени анимации, задаваемой свойством animation-duration (-webkit-animation-duration). В данном примере 50% от 10с это 5 секунд. Т.е. через 5с координаты блока станут top: 150px, left: 100px. В последний момент времени, описываемый селектором кадра to (через 10с), блок получит абсолютные координаты top: 400px, left: 300px.
Замечание! Анимация происходит не в три рывка, а плавно.
Каким образом достигается плавность анимации?
Для достижения этой плавности рассчитываются промежуточные значения между ключевыми кадрами. Значения интерполируются в зависимости, описанной некоторой кривой Безье третьего порядка. Выбрать наиболее подходящий вариант кривой для интерполяции можно с помощью свойства animation-timing-function (-webkit-animation-timing-function).
Значение свойства animation-timing-function (-webkit-animation-timing-function) может быть как одинаковым для всех переходов анимации, так и разным для разных переходов между разными ключевыми кадрами. В первом случае свойство и значение указываются для элемента вместе с остальными свойствами анимации, а во втором случае они указываются при описании того ключевого кадра, вслед за которым будет идти описываемый переход. Можно также задать их одновременно:
div { position:relative; top: 50px; left: 0px; -webkit-animation-name: 'movement'; -webkit-animation-duration: 10s; -webkit-animation-timing-function: easy-out; animation-name: 'movement'; animation-duration: 10s; animation-timing-function: easy-out; } @-webkit-keyframes 'movement' { from { top: 50px; left: 0px; -webkit-animation-timing-function: easy-in-out; } 50% { top: 150px; left: 100px; } to { top: 400px; left: 300px; } } @keyframes 'movement' { from { top: 50px; left: 0px; -webkit-animation-timing-function: easy-in-out; } 50% { top: 150px; left: 100px; } to { top: 400px; left: 300px; } }
Между первым и вторым ключевым кадром будет применено значение easy-in-out, а к оставшемуся промежутку между вторым и третьим кадром будет применено значение easy-out.
Обязательно ли совпадение начальных значений анимируемых свойств и значений анимируемых свойств для первого кадра анимации?
Нет, не обязательно. Если начальные значения и значения первого кадра не совпадают, то начальных значений можно и не увидеть, если у анимации нет задержки. Если задержка есть, то во время задержки будет видно начальные значения, а потом произойдет резкий рывок к первому кадру анимации. Чтобы в течение задержки было видно первый кадр, а не начальные значения, можно использовать -webkit-animation-fill-mode со значением backwards. Это свойство поддерживает Safari 5 и Chrome 4. Это же свойство со значением forwards дает возможность видеть эффект от анимации, когда та уже закончила проигрываться (после завершения анимации элемент получает не начальные значения, а какие-то промежуточные из анимации). Наглядно разницу можно посмотреть в демо-примере (смотреть Safari 5+, Chrome 4+).
Может ли какое-то свойство элемента отсутствовать в CSS правиле для этого элемента, но появляться в момент описания анимации?
Может, но только при условии, что значение по умолчанию этого свойства можно анимировать (т.е. в принципе существует несколько промежуточных значений между начальным и конечным значением). Рассмотрим пример:
div { position: relative; -webkit-animation-name: 'movement'; -webkit-animation-duration: 10s; animation-name: 'movement'; animation-duration: 10s; } @-webkit-keyframes 'movement' { from { top: 50px; left: 0px; } 50% { top: 150px; left: 100px; } to { top: 400px; left: 300px; } } @keyframes 'movement' { from { top: 50px; left: 0px; } 50% { top: 150px; left: 100px; } to { top: 400px; left: 300px; } }
Так можно делать, поскольку координаты элемента в этом случае по умолчанию заданы top: 0px; left: 0px.
А так делать нельзя:
div { -webkit-animation-name: 'bordered'; -webkit-animation-duration: 10s; animation-name: 'bordered'; animation-duration: 10s; } @-webkit-keyframes 'bordered' { from { border: 1px dashed #0f0; } to { border: 5px dashed #f00; } } @keyframes 'bordered' { from { border: 1px dashed #0f0; } to { border: 5px dashed #f00; } }
Свойство border-style анимировать нельзя (какое, например, значение border-style может быть промежуточным между solid и dashed?), а в этом примере получается, что оно меняет свое значение со значения по умолчанию none на значение анимации dashed.
Правильно будет сначала описать border-style для самого элемента:
div { border-style: dashed; border-width: 0px; -webkit-animation-name: 'bordered'; -webkit-animation-duration: 10s; animation-name: 'bordered'; animation-duration: 10s; } @-webkit-keyframes 'bordered' { from { border-width: 1px; border-color: #0f0; } to { border-width: 5px; border-color: #f00; } } @keyframes 'bordered' { from { border-width: 1px; border-color: #0f0; } to { border-width: 5px; border-color: #f00; } }
Также можно сделать так:
div { border-style: dashed; border-width: 0px; -webkit-animation-name: 'bordered'; -webkit-animation-duration: 10s; animation-name: 'bordered'; animation-duration: 10s; } @-webkit-keyframes 'bordered' { from { border: 1px dashed #0f0; } to { border: 5px dashed #f00; } } @keyframes 'bordered' { from { border: 1px dashed #0f0; } to { border: 5px dashed #f00; } }
Сравнить все 3 примера вживую можно в демонстрационном примере.
Продолжение читайте в статье Анимация в CSS3. Часть II.
Материалы
- W3C :: CSS Animations Module Level 3
- :: Supported CSS Properties: Visual Effects