CSS спрайты – это не новинка. С того момента, как их популяризовали на «A List Apart» в 2004, простые спрайты стали основной техникой в наборе инструментов большинства веб-разработчиков. Но, несмотря на то, что преимущества скорости спрайтов вполне понятны, их использование в современной веб-разработке редко обсуждается. Принцип остается тем же: это комбинирование нескольких изображений в один «основной» графический элемент, из которого в каждый момент времени отображаются только определенные части.

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

Создание спрайта


Спрайты вышли из мира видеоигр, поэтому мы отдадим должное наследию и анимируем Рю из Street Fighter. Разумеется, оригинал принадлежит Capcom.

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

ImageMagick, «швейцарский нож» для обработки изображений, — это бесплатный общедоступный инструмент для управления изображениями, который отлично подходит для автоматизации задач, которые могут быть довольно трудоемкими, например, для комбинирования изображений. ImageMagick также доступен практически для каждой операционной системы. Пользователи Mac могут установить его через Homebrew, приверженцы Windows могут скачать инсталлятор с официального сайта, а фанаты Linux, наверное, и без меня знают, что надо делать.

Сохраните кадры вашей анимации, имеющие одинаковые размеры, в папку в виде последовательности PNG-файлов. Вызовите терминал командной строки, перейдите (cd) в директорию, где сохранены ваши изображения, и выполните следующую команду:

convert *.png -append result-sprite.png

Эта команда инструктирует ImageMagick связать вертикально все .PNG-файлы в нашей директории (так как «*» — это специальный знак) в один полный спрайт под названием «result-sprite.png». Это графический элемент, который будет использоваться в качестве фонового изображения (background-image) в CSS для элемента, который мы хотим анимировать, изменяя его положения для зацикливания всех кадров по порядку.

Чистая CSS-анимация


Мы начнем с простого и анимируем наш спрайт с помощью анимации ключевого кадра CSS3. Если вы не знакомы с базовым синтаксисом, статья Луи Лазариса на сайте Smashing Magazine представляет собой неплохое введение. Мы собираемся анимировать вертикальное позиционирование фона (background-position) нашего элемента от 0% до 100% (сверху вниз), используя по очереди каждый кадр.

Если позволить анимации выполняться в одной непрерывной последовательности в качестве стандартного поведения, наш спрайт будет использоваться между кадрами, что нарушит иллюзию. Тем не менее, используя функцию steps() мы можем контролировать количество отображаемых ключевых кадров. Ввиду того, что background-position действует при определении в процентном соотношении, нам нужно задать количество шагов на один меньше, чем общее количество кадров в нашей анимации.

Поэкспериментируйте с этим кодом в CodePen, чтобы понять смысл.

Обратите внимание, что мы определили ширину (width) и высоту (height) нашего элемента таким образом, чтобы они четко соответствовали общему кадру, и чтобы избежать выхода предыдущих или последующих кадров. Мы использовали сокращенные обозначения, чтобы задать количество итераций анимации (animation-iteration-count) как «бесконечное», а длительность анимации (animation-duration) – 3,5 секунд, и таким образом у нас получилось, что Рю выбрасывает свое комбо «удар-бросок ногой-хадокен» до истечения времени.

Да, он далек от идеала. Попробуйте изменить высоту нашего элемента «Рю» или применить background-size к нашему спрайту, и эффект нарушится. Наш анимированный элемент пока что не отзывчив и зависит от четких размеров, основанных на пикселях.

Делаем его отзывчивым


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

Первая опция – это установить размер фона нашего спрайта равным 100% ширины нашего элемента, конвертировать ширину и высоту нашего элемента из пикселей в em, после чего изменить базовый размер шрифта (font-size) соответствующим образом. Это поможет добиться желаемого эффекта и может сработать в большинстве случаев, но не даст настоящей текучести.

Наш второй вариант – это воспользоваться техникой фиксированного соотношения сторон на базе чистого CSS Марка Хинзе, в котором используется процентный отступ в псевдо-элементе, сохраняющий пропорции элемента при любом размере. Этот подход используется в демо, приведенном ниже, и дает нашему спрайту текучую ширину при 70%. Отзывчивый Рю.

Это легкий и адаптированный под мобильные устройства способ достижения отзывчивого покадрового эффекта анимации. Браузеры отлично поддерживают CSS-анимацию, в результате чего единственным ограничивающим фактором является ключевой кадр CSS3. Включите соответствующий префикс поставщика -webkit-, и эффект будет работать во всех современных браузерах, включая IE10 и выше.

JavaScript-анимация


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

Чтобы это было возможным, нам нужно анимировать наши спрайты с помощью JavaScript, используя всю мощь платформы для анимации GreenSock и превосходную библиотеку Яна Пепке ScrollMagic. Для тех, кто не знаком с этой отличной комбинацией, отличным началом станут официальные демо ScrollMagic.

Это мощные инструменты, по которым написаны целые серии уроков. В качестве примера, чтобы не вдаваться в подробности, как работает ScrollMagic, мы продемонстрируем некоторые доступные нам функции времени. Основные принципы спрайтов остаются такими же, как и в нашей CSS-анимации.

Для начала, давайте вызовем 2-секундную анимацию при определенном положении прокрутки. Она должна закончиться последним кадром и проигрываться в обратном порядке при обратной прокрутке (даже если при этом она будет проигрываться на полпути). Мы будем и дальше придерживаться темы видеоигр и используем спрайт из классической стратегии Westwood Studios — Red Alert, которая теперь выпускается бесплатно.

Демонстрация.

Обратите внимание, что мы используем вышеупомянутый способ указания размеров, основанный на em; попробуйте изменять размер шрифта, уменьшая или увеличивая спрайт. Мы определили двойника TweenMax.to, задав значение вертикального положения фона нашего элемента как 100%, и использовали метод SteppedEase для достижения требуемого покадрового эффекта.

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

Демонстрация.

Спрайт остается в фиксированном положении на протяжении действия анимации, которая теперь контролируется поведением прокрутки пользователя. Чтобы добиться такого эффекта, мы задали нашему свойству ScrollMagic.Scene значение продолжительности 1500 пикселей и использовали метод setPin для фиксации родительского элемента для полноты картины. Более подробное описание этих техник изложено в документации на сайте ScrollMagic.

Поддержка браузерами спрайт-анимации на базе JavaScript даже лучше, чем нашей версии только на CSS. ScrollMagic и GreenSock поддерживаются всеми современными браузерами, включая IE 9+, с автоматической обработкой префиксов и недостатков браузеров. Мобильная поддержка тоже неплохая; эти техники работают на iOS 8+ без специальных обходных решений, включая перерисовывание на ходу, и без потери скорости прокрутки.

Заключение


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

И в конце концов, как сказала Рейчел Наборс, «анимируйте ответственно». Если что-то можно анимировать, его не обязательно нужно анимировать. И если вы действительно выбрали анимацию, делайте это сознательно, красиво и рационально.

Комментарии (6)


  1. inook
    08.04.2015 08:38

    У вас много тем посвященных CSS. Но одну тему вы забыли — Производительность CSS! Вы свой сайт пробовали скролить в OS X?


    1. Coffin
      08.04.2015 09:32
      +3

      Я зашел, покрутил и что?
      Не лагает, в отличии от тех, где параллакс кривой или еще что-нить типа «крутое» по мнению дизайнеров, а на самом деле не удобное гавно :)


  1. Spichka
    08.04.2015 12:24

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

    Отказался.


    1. Irina_Ua Автор
      08.04.2015 19:06

      Base64 неплохо увеличивает объем, передаваемый пользователю + они не кэшируются. Хотя спрайты и нагружают хард, они уменьшают количество запросов.


  1. Spichka
    08.04.2015 21:10

    Что не кэшируется? css файл не кэшируется? Ну тогда спрайты тоже не кэшируются.


    1. Irina_Ua Автор
      09.04.2015 06:28

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