HTML5 и CSS3. Разработка сайтов для любых браузеров и устройств. 2-е изд. - Фрэйн .
Шрифт:
Интервал:
Закладка:
Анимация SVG-графики с помощью JavaScript
Когда SVG-графика вставлена в страницу посредством тега object или непосредственно в код самой страницы, появляется возможность работать с SVG-графикой напрямую или опосредованно с помощью JavaScript.
Под опосредованностью подразумевается возможность средствами JavaScript изменить класс самого SVG-элемента или элемента, в который заключена SVG-графика, что должно инициировать запуск CSS-анимации, например:
svg {
/* нет анимации */
}
.added-with-js svg {
/* есть анимация */
}
Но также возможно применить эффект анимации к SVG-графике с помощью JavaScript непосредственным образом.
Если анимации подвергаются один или два элемента независимо друг от друга, то, возможно, написанный вручную код JavaScript будет рациональнее, что существенно облегчит задачу. Но если нужно подвергнуть эффектам анимации большое количество элементов или синхронизировать анимацию элементов, как с применением шкалы времени, то реальную помощь в этом могут оказать библиотеки JavaScript. В конечном счете вам решать, насколько оправданным окажется утяжеление страницы за счет включения в нее библиотеки для достижения цели.
Для придания эффектов анимации SVG-графике посредством JavaScript хочу порекомендовать анимационную платформу GreenSock (http://greensock.com), Velocity.js (http://julian.com/research/velocity/) или Snap.svg (http://snapsvg.io/). Далее мы рассмотрим очень простой пример использования GreenSock.
Простой пример анимации SVG-графики с помощью GreenSock. Предположим, что нам нужно создать интерфейс с круглой шкалой, подвергаемой анимации по щелчку на кнопке от нулевой позиции до позиции, задаваемой вводимым значением. Нам нужно не только подвергнуть анимации продвижение по круглой шкале как по длине, так и по цвету, но и вывести число от нуля до вводимого значения. Полный код реализации можно найти в файле каталога example_07-08.
Если будет введено значение 75 и нажата кнопка запуска анимации, круглая шкала будет заполнена и возникнет следующая картина.
Вместо демонстрации распечатки всего файла JavaScript, в котором имеется много комментариев, чтобы стимулировать его отдельное изучение, для краткости мы рассмотрим только ряд ключевых моментов.
Основной замысел состоит в том, что окружность создана в виде SVG-тега <path>, а не элемента <circle>. То, что используется путь, означает, что его можно подвергнуть анимации, как будто он прорисовывается с использованием технологии stroke-dashoffset. Краткое изложение этой технологии представлено на следующей вкладке. Мы используем JavaScript для измерения длины пути, а затем применим атрибут stroke-dasharray для указания длины выводимой на экран части окружности и длины пустого промежутка. Затем stroke-dashoffset используется для изменения места старта этого dasharray. Это означает, что можно фактически запустить обвод по контуру вне пути и анимировать этот обвод. Это создает иллюзию, что путь прорисовывается.
Если бы значение для анимации dasharray было известным статичным значением, такого же эффекта можно было бы относительно легко достичь с помощью CSS-анимации и некоторого количества проб и ошибок (более подробно CSS-анимация будет рассмотрена в следующей главе).
Но вдобавок к динамическому значению одновременно с прорисовкой линии нам нужны постепенное повышение яркости цвета от одного значения к другому и визуальный подсчет до введенного значения, выполняемый в текстовом узле. Эта анимация сродни одновременному похлопыванию по голове, поглаживанию живота и обратному отсчету от 10 000. Средство GreenSock существенно облегчает задачу — в анимационной части оно не будет похлопывать вас по голове или поглаживать по животу, хотя может при необходимости выполнить обратный отсчет от 10 000. Вот строки кода JavaScript, необходимые, чтобы заставить GreenSock выполнить все три задачи:
// анимация прорисовки линии и изменения цвета
TweenLite.to(circlePath, 1.5, {'stroke-dashoffset': "-"+amount,
stroke: strokeEndColour});
// установка счетчика в нуль и его анимация до введенного значения
var counter = { var: 0 };
TweenLite.to(counter, 1.5, {
var: inputValue,
onUpdate: function () {
text.textContent = Math.ceil(counter.var) + "%";
},
ease:Circ.easeOut
});
По сути, функции TweenLite.to() передаются: то, что нужно подвергнуть анимации, время, за которое эта анимация должна осуществиться, а затем значения, которые нужно изменить (и то, что в них нужно изменить).
Сайт GreenSock содержит отличную документацию и поддерживает форумы, и если вам понадобится одновременно синхронизировать целый ряд анимаций, выкроите денек в своем рабочем расписании и ознакомьтесь с GreenSock.
совет
Если вам еще не приходилось сталкиваться с SVG-технологией прорисовки линий, она была изложена в доступной форме журналом Polygon, когда Vox Media анимировала несколько прорисовок линий в игровых консолях Xbox One и Playstation 4. Исходную статью можно прочитать по адресу http://product.voxmedia.com/2013/11/25/54 26880/polygon-feature-design-svg-animations-for-fun-and-profit.
Есть еще великолепное и более основательное объяснение этой технологии, изложенное Джейком Арчибальдом (Jake Archibald) по адресу http://jakearchibald.com/2013/animated-line-drawing-svg/.
Оптимизация SVG
Как добросовестные разработчики, мы хотим обеспечить наименьший возможный объем своих ресурсов. Проще всего это сделать с SVG-графикой, воспользовавшись средствами анимации, способными оптимизировать различные реквизиты SVG-документов. Кроме очевидной экономии, такой как удаление элементов (например, удаление элементов заголовков и описаний), можно также выполнить целую кучу микрооптимизаций, которые в сумме делают SVG-активы намного компактнее.
В настоящее время для решения данной задачи можно порекомендовать средство SVGO (https://github.com/svg/svgo). Если вам еще не приходилось пользоваться SVGO, рекомендую начать с SVGOMG (https://jakearchibald.github.io/svgomg/). Это версия SVGO, основанная на применении браузера и позволяющая переключать различные дополнительные модули оптимизации, получая немедленную реакцию в виде сохраненного файла.
Помните пример SVG-разметки для получения звезды, приведенный в начале главы? В исходном виде этот простой SVG-документ занимает 489 байт. Пропустив его через SVGO, можно уменьшить размер до 218 байт, оставив на месте viewBox. Тем самым будет сэкономлено 55,42 % объема. Если используется множество SVG-изображений, такая экономия может вылиться в весьма солидный результат. Оптимизированная SVG-разметка имеет следующий вид:
<svg width="198" height="188" viewBox="00198188" xmlns="http://
www.w3.org/2000/svg"><path stroke="#979797" stroke-width="3"
fill="#F8E81C" d="M99154l-58.7830.90211.227-65.45L3.89473.097l65.717-9.55L994l29.3959.5565.7169.548-47.55346.35311.22665.454z"/></svg>
Прежде чем потратить уйму времени на освоение SVGO, следует узнать, что благодаря популярности SVGO этим средством пользуются и другие SVG-средства. Например, ранее упомянутое средство Iconizr (http://iconizr.com/) перед созданием ваших ресурсов по умолчанию прогоняет SVG-файлы через SVGO, избавляя вас от ненужной двойной оптимизации.
Использование SVG в качестве фильтров
В главе 6 рассматривались эффекты, создаваемые фильтрами CSS. Но в настоящее время в Internet Explorer 10 или 11 они не поддерживаются. Если вы собирались воспользоваться в этих браузерах эффектами фильтров, то ничего, кроме досады, не испытаете. К счастью, с помощью SVG можно создавать фильтры, работающие и в Internet Explorer 10 и 11, но, как всегда, все не настолько просто, как можно было бы себе представить. Например, в файле каталога example_07-05 имеется страница, в теле которой содержится следующая разметка:
<img class="HRH" src="[email protected]"/>
Это фотография королевы Великобритании. Изначально она имеет следующий вид.
В этом же каталоге примера содержится SVG-документ с фильтром, определенным в элементах defs. Разметка SVG имеет следующий вид:
<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
<defs>
<filter id="myfilter" x="0" y="0">
<feColorMatrix in="SourceGraphic" type="hueRotate"
values="90" result="A"/>
<feGaussianBlur in="A" stdDeviation="6"/>
</filter>
</defs>
</svg>
Внутри фильтра сначала задается вращение тона на 90° с помощью feColorMatrix, а затем этот эффект через атрибут result передается следующему фильтру (feGaussianBlur) со значением размытия, равным 6. Сразу предупреждаю, что задал слишком жесткие параметры в ущерб эстетическому восприятию намеренно, чтобы у нас не осталось никаких сомнений в том, что эффект работает!
Теперь вместо добавления этой SVG-разметки к HTML мы можем оставить ее там, где она находится, и сослаться на нее, используя тот же синтаксис CSS-фильтра, который уже видели в предыдущей главе:
.HRH {
filter: url('filter.svg#myfilter');
}
В самых популярных браузерах (Chrome, Safari, Firefox) будет получен следующий эффект.
К сожалению, этот метод не работает в Internet Explorer 10 или 11. Но есть и другой способ достижения нашей цели, заключающийся в использовании собственного тега image SVG-документа, предназначенного для включения изображения в этот документ. В файле каталога example_07-06 содержится следующая разметка: