Спрайтовая анимация — одна из тех вещей, которые при всей своей примитивности успешно работают и применяются в компьютерной графике и играх уже больше четверти века. Даже в трехмерных играх есть спрайты — например, билборды взрывов. Во многих браузерных и флеш-играх применяют именно спрайтовую анимацию, так как она очень проста и не требует высокой производительности — просто переключай кадры и все! А с появлением анимации в CSS 3 стало возможным использовать спрайты на своих страницах без яваскриптов.
Сразу хочу оговориться, что нижеописанный способ работает пока что только для webkit-браузеров.
Итак, возьмем простой спрайт из трех кадров:

Все, что нам надо с ним сделать, это поставить фоном в div и менять у него со временем background-position. Вроде бы все просто:
Но увы! В результате мы видим лишь одну порнографию. Картинка движется плавно, а не рывками длиной в кадр. Попробуем улучшить ситуацию, делая длинные интервалы и быстро переключая кадры:
Код получился довольно объемный, но результат нас почти устраивает, если бы не одно «но»: при маленьких интервалах можно наблюдать рывки.
Для полностью правильной анимации надо прибегнуть к другой хитрой возможности CSS 3: увеличению размера. Для этого установим ширину и высоту кадра в 1 пиксель и при помощи свойства transform увеличим спрайт до наших 32 пикселей. Так как transform влияет не только на размер самого элемента, но и на его фон, его размер установим в 3 пикселя по ширине и 1 по высоте, и в самой анимации сдвигать будем так же по 1 пикселю. Вместе с увеличением оно как раз и будет равно 32 пикселям.
Теперь результат полностью соответствует нашим ожиданиям. Анимация нормальная, без рывков и прочего.
Для генерации ключевых кадров можно воспользоваться этой функцией:
Увы, этот способ пока что малоприменим на практике, так как работает только в Webkit-браузерах типа Chrome или Safari. В Firefox анимация так и останется плавной, в Opera показывается только первый кадр, а в IE оно вообще не работает. Так что анимация с использованием Javascript и Flash будет держать свои позиции еще довольно долго.
Сразу хочу оговориться, что нижеописанный способ работает пока что только для webkit-браузеров.
Итак, возьмем простой спрайт из трех кадров:

Все, что нам надо с ним сделать, это поставить фоном в div и менять у него со временем background-position. Вроде бы все просто:
Copy Source | Copy HTML
- .sprite
- {
- position: absolute;
-
- left: 50%; /* положение спрайта */
- top: 33%;
- width: 32px; /* его размер */
- height: 32px;
-
- margin: -16px 0 0 -16px; /* просто чтобы он был по центру :-) */
-
- background: url(sprite.png) no-repeat 0 0; /* фон */
-
- -webkit-animation-name: sprite; /* название анимации */
- -webkit-animation-duration: .3s; /* интервал в 300 миллисекунд */
- -webkit-animation-iteration-count: infinite; /* повторять бесконечно */
- -webkit-animation-timing-function: linear; /* использовать линейную функцию */
- }
-
- /* анимация sprite */
- @-webkit-keyframes sprite
- {
- /* перемещаем фон спрайта три раза, на четвертый возвращаем обратно в 0 */
- 0%
- {
- background-position: -0px 0;
- }
- 33%
- {
- background-position: -32px 0;
- }
- 66%
- {
- background-position: -64px 0;
- }
- 100%
- {
- background-position: -0px 0;
- }
- }
Но увы! В результате мы видим лишь одну порнографию. Картинка движется плавно, а не рывками длиной в кадр. Попробуем улучшить ситуацию, делая длинные интервалы и быстро переключая кадры:
Copy Source | Copy HTML
-
- @-webkit-keyframes sprite
- {
- 0%
- {
- background-position: -0px 0;
- }
- 33.332%
- {
- background-position: -0px 0;
- }
- 33.334%
- {
- background-position: -32px 0;
- }
- 66.665%
- {
- background-position: -32px 0;
- }
- 66.667%
- {
- background-position: -64px 0;
- }
- 99.999%
- {
- background-position: -64px 0;
- }
- 100%
- {
- background-position: -0px 0;
- }
- }
-
Код получился довольно объемный, но результат нас почти устраивает, если бы не одно «но»: при маленьких интервалах можно наблюдать рывки.
Для полностью правильной анимации надо прибегнуть к другой хитрой возможности CSS 3: увеличению размера. Для этого установим ширину и высоту кадра в 1 пиксель и при помощи свойства transform увеличим спрайт до наших 32 пикселей. Так как transform влияет не только на размер самого элемента, но и на его фон, его размер установим в 3 пикселя по ширине и 1 по высоте, и в самой анимации сдвигать будем так же по 1 пикселю. Вместе с увеличением оно как раз и будет равно 32 пикселям.
Copy Source | Copy HTML
-
- .sprite
- {
- position: absolute;
-
- left: 50%;
- top: 33%;
- width: 1px; /* размеры элемента ставим в 1 пиксель */
- height: 1px;
-
- margin: -16px 0 0 -16px; /* на отступы увеличение через transform не влияет */
-
- background: url(sprite.png) no-repeat 0 0;
- background-size: 3px 1px; /* размер фона также уменьшаем */
-
- -webkit-animation-name: sprite;
- -webkit-animation-duration: .3s;
- -webkit-animation-iteration-count: infinite;
- -webkit-animation-timing-function: linear;
- -webkit-transform: scaleX(32) scaleY(32); /* увеличим размер элемента */
- -webkit-transform-origin: top left;
- }
-
- @-webkit-keyframes sprite
- {
- /* сдвигаем фон по 1 пикселю */
- 0.000%
- {
- background-position: -0px 0;
- }
- 25.000%
- {
- background-position: -1px 0;
- }
- 50.000%
- {
- background-position: -2px 0;
- }
- /* честно говоря, сам не понял, зачем надо сдвигать */
- /* еще на один пиксель (ведь это должен быть */
- /* пустой кадр). но иначе оно не покажет все */
- /* кадры анимации. */
- 75.000%
- {
- background-position: -3px 0;
- }
- 100.000%
- {
- background-position: -0px 0;
- }
- }
-
Теперь результат полностью соответствует нашим ожиданиям. Анимация нормальная, без рывков и прочего.
Для генерации ключевых кадров можно воспользоваться этой функцией:
Copy Source | Copy HTML
- function generateKeyframes($count, $sprite_width)
- {
- $result = '';
- $count++;
- for ($i = 0; $i <= $count; $i++)
- {
- $result .= sprintf("\t%.3f%%\n\t{\n\t\tbackground-position: -%dpx 0;\n\t}\n", $i * 100. 0 / $count, ($i % $count) * $sprite_width);
- }
- return $result;
- }
Увы, этот способ пока что малоприменим на практике, так как работает только в Webkit-браузерах типа Chrome или Safari. В Firefox анимация так и останется плавной, в Opera показывается только первый кадр, а в IE оно вообще не работает. Так что анимация с использованием Javascript и Flash будет держать свои позиции еще довольно долго.