Как сделать покадровую анимацию

Оцените материал
(0 голосов)

Проблема

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

Возможно, вы сейчас задаетесь вопросом, почему бы просто не прибегнуть к помощи анимированных изображений в формате GIF. Разумеется, анимиро-ванные GIF-изображения прекрасно подходят во многих ситуациях, но у них есть несколько недостатков, которые в определенных сценариях делают их нежелательным решением:
‰ они ограничены палитрой из 256 цветов, одной и той же для всех кадров;
‰ они не поддерживают прозрачность альфа-канала, что может стать большой проблемой, если мы не знаем, что будет находиться под нашим анимированным GIF-изображением. Например, так часто бывает, когда изображение представляет собой индикатор прогресса;
‰ нет никакой возможности управлять из CSS-кода определенными аспектами, такими как продолжительность, количество повторений, приостановкаанимации и т. д. Генерируя изображение в формате GIF, вы пакуете в один файл все данные, и изменить их можно, лишь отредактировав изображение и создав новый файл.

Это прекрасно для обеспечения переносимости, но не когда вы хотите поэкспериментировать. Давным-давно, в 2004 году, разработчики браузера Mozilla предприняли попытку справиться с первыми двумя проблемами, разрешив покадровую анимацию в файлах формата PNG, аналогично тому, как мы можем использовать и статичные, и анимированные GIF-файлы. Формат носил название APNG и предусматривал обратную совместимость с утилитами просмотра изображений, не поддерживающими PNG с анимацией: первый кадр кодировался точно так же, как в традиционных PNG-файлах, поэтому старые утилиты могли как минимум отобразить один этот кадр. Несмотря на многообещающее начало, формат APNG так и не завоевал популярность, и по сей день поддержка этого формата браузерами и графическими редакторами крайне ограниченна. Разработчики даже используют JavaScript для реализации гибкой покадровой анимации в браузере, анимируя с помощью сценариев свойство background-position спрайта. Более того, в Сети можно найти небольшие библиотеки, предназначенные для помощи в этом деле! Но существует ли простой и понятный способ создания подобной анимации средствами приятного и читабельного CSS-кода?

Решение

Предположим, что у нас есть спрайт в формате PNG, содержащий все кадры нашей анимации, как показано на рисунке.



Также у нас есть элемент, который будет содержать этот индикатор (не забудьте для обеспечения доступности добавить описательный текст!), и мы определили для него размеры, совпадающие с размерами одного кадра:
HTML
<div class="loader">Loading…</div>
.loader {
width: 100px; height: 100px;
background: url(img/loader.png) 0 0;
/* Скрыть текст */
text-indent: 200%;
white-space: nowrap;
overflow: hidden;
}
Пока результат выглядит так:  первый кадр отображается, но никакой анимации не видно. Однако если мы воспроизведем код с разными значениями background-position, то заметим, что  -100px 0 дает нам второй кадр,  -200px 0 — третий кадр и т. д. Первой мыслью в связи с этим может быть такой вариант анимации:

@keyframes loader {
to { background-position: -800px 0; }
}
.loader {
width: 100px; height: 100px;
background: url(img/loader.png) 0 0;
animation: loader 1s infinite linear;
/* Скрыть текст */
text-indent: 200%;
white-space: nowrap;
overflow: hidden;
}
Однако, как вы можете видеть на следующих снимках экрана (сделанных с интервалом 167 мс), это решение не работает. Вам может казаться, что мы зашли в тупик, но в действительности мы очень близки к решению. Секрет здесь заключается в использовании функции расчета времени  steps() вместо функции, основанной на кривых Безье. «Какой-какой функции расчета времени?!» — спросите вы. Как мы узнали в предыдущем разделе, все функции расчета времени на основе кривых Безье интерполируют содержимое ключевых кадров, для того чтобы обеспечить плавный переход одного изображения в другое. Это великолепно; чаще всего плавное перетекание и есть та причина, по которой мы прибегаем к переходам и анимации CSS. Однако в нашей ситуации плавность разрушает нашу анимацию спрайта.


В отличие от функций расчета времени Безье, функция  steps() делит всю анимацию на кадры по количеству указанных вами шагов и резко перескакивает с одного на другой безо всякой интерполяции. Обычно такая резкая смена картинки нежелательна, поэтому о  steps() вспоминают крайне редко. В мире функций расчета времени CSS функции на основе кривых Безье — это популярные ребята, которых приглашают на все вечеринки, а  steps() , к сожалению, — гадкий утенок, с которым никто не хочет даже пообедать. Но в нашей задаче требуется именно такое поведение. Как только мы переформулируем определение анимации показанным далее способом, индикатор загрузки сразу же начнет работать так, как и планировалось с самого начала:

animation: loader 1s infinite steps(8);

Помните, что  steps() также принимает необязательный второй параметр,  start или  end (значение по умолчанию), определяющий, когда в каждом интервале.

происходит переключение (поведение по умолчанию для варианта  end показано на рисунке, но необходимость в нем возникает крайне редко. Если вам нужен только один шаг, то можно воспользоваться одним из сокращений —  step-start или  step-end , которые эквивалентны  steps(1, start) и steps(1, end) соответственно.

ПОПРОБУЙТЕ САМИ!

http://play.csssecrets.io/frame-by-frame

Десерт на сегодня - реклама новой Ferrari. Умеют в Италии красиво представлять свои автомобили!

Прочитано 251 раз Последнее изменение Суббота, 17 июня 2017 13:51
Другие материалы в этой категории:
Понравилась запись? Подпишитесь на обновления по почте:

Нетология

TemplateMonster

Поиск по сайту

Связной трэвел

Google+