Но действительно большое преимущество, которое следует учесть разработчикам, заключается в том, что SVG основан на XML-спецификации, разметке, которая на сегодняшний день считается слегка устаревший, а это означает, что работать она будет примерно так же, как и HTML. Это также означает, что мы можем осуществлять доступ и управлять графикой и элементами внутри SVG-файла при помощи таких технологий как CSS и javascript, с которыми сегодня знаком каждый разработчик.
С подходящей техникой исполнения и поддержкой в современных браузерах, разработчики сегодня могут создавать действительно привлекательные анимации, эффекты и взаимодействия используя SVG. Сегодня мы расскажем вам о возможностях SVG, а также протестируем совместимость современных браузеров, разработав интерактивную векторную инфографику для веб-страницы.
Подготавливаем SVG-файл
Существует множество способов создать SVG-графику, и хотя у нас есть возможность разработать SVG-код «вручную», для более комплексных графических элементов лучше все-таки использовать ПО для редактирования векторной графики, а затем экспортировать результат в SVG-формат. Конечно же, среди дизайнеров самым популярным выбором является Adobe Illustrator, но также можно найти и бесплатные/open source-приложения вроде Inkscape, которое, в некоторых случаях, подходит даже лучше остальных.
Какое бы ПО вы ни выбрали, важно иметь возможность группировать объекты вместе, а также давать имена этим группам (задавать атрибут ID). Это позволит нам организовать наш SVG в правильной иерархии, чтобы позже у нас был соответствующий доступ к настройкам в CSS и/или javascript. Как в Illustrator, так и в Inkscape это можно сделать путем выделения нескольких графических элементов и последующим нажатием Object > Group (или Ungroup) в верхнем меню.
Любому объекту или группе позже можно задать имя. Оно становится id группы или объекта при экспортировании, поэтому избегайте пробелов и спецсимволов. Также старайтесь не дублировать имена.
В Illustrator это можно сделать при помощи панели слоев. Просто перейдите к объекту, которому вы хотите задать имя, на панели, дважды кликните по нему, и введите нужный вам id. В Inkscape воспользуйтесь панелью Object > Object Properties, чтобы задать id группы или объекта. Кроме того, вы можете сделать это при помощи панели Edit > XML Editor, которая даст вам больший контроль над результатом, и даже возможность присваивать классы, а не только id.
В нашем примере, когда мы сохраняем наш SVG, и открываем его в текстовом редакторе, он будет иметь следующий тип структуры:
<g id="background">
<g id="bg-lines-left"> <!-- left background lines --> </g>
<g id="bg-lines-right"> <!-- right background lines --> </g>
</g>
<g id="logo"> <!-- logo graphics --> </g>
<g id="quote">
<g id="quote-left-brace"> <!-- left quote brace --> </g>
<g id="quote-right-brace"> <!-- right quote brace --> </g>
<g id="quote-text"> <!-- quote text --> </g>
</g>
<g id="timeline">
<g id="coffee">
<rect id="coffee-bar" />
<polyline id="coffee-arrow" />
<g id="coffee-time"> <!-- time text --> </g>
<g id="coffee-badge">
<circle id="coffee-circle" />
<g id="coffee-title"> <!-- title text --> </g>
<g id="coffee-details"> <!-- icon, description --> </g>
</g>
</g>
<g id="design">
<rect id="design-bar" />
<polyline id="design-arrow" />
<g id="design-time"> <!-- time text --> </g>
<g id="design-badge">
<circle id="design-circle" />
<g id="design-title"> <!-- title text --> </g>
<g id="design-details"> <!-- icon, description --> </g>
</g>
</g>
<g id="build">
<rect id="build-bar" />
<polyline id="build-arrow" />
<g id="build-time"> <!-- time text --> </g>
<g id="build-badge">
<circle id="build-circle" />
<g id="build-title"> <!-- title text --> </g>
<g id="build-details"> <!-- icon, description --> </g>
</g>
</g>
<g id="complain">
<rect id="complain-bar" />
<polyline id="complain-arrow" />
<g id="complain-time"> <!-- time text --> </g>
<g id="complain-badge">
<circle id="complain-circle" />
<g id="complain-title"> <!-- title text --> </g>
<g id="complain-details"> <!-- icon, description --> </g>
</g>
</g>
<g id="beer">
<rect id="beer-bar" />
<polyline id="beer-arrow" />
<g id="beer-time"> <!-- time text --> </g>
<g id="beer-badge">
<circle id="beer-circle" />
<g id="beer-title"> <!-- title text --> </g>
<g id="beer-details"> <!-- icon, description --> </g>
</g>
</g>
</g>
Вышеприведенная разметка была разделена таким образом, чтобы вам было легче понять структуру. Будет лучше, если мы подробно проанализируем некоторые моменты в SVG-результате. Это позволит лучше познакомиться с разметкой. Вы увидите многие знакомые вещи, похожие на HTML, а также и кое-что новое.
Как видно из нашей SVG-разметки, каждый тег 'g' указывает на новую группу объектов, которые могут быть вложены внутрь других групп. Конечно же, при создании SVG, не так важно задавать id каждому объекту/группе, это лишь повышает уровень удобства при дальнейшем обращении к ним посредством CSS или javascript, и позволяет распознавать их в разметке.
Подгружаем SVG в HTML при помощи javascript
HTML-код
Существует несколько методов встроить или поместить SVG в HTML. Вы можете сделать это при помощи тега 'img', тега 'embed' или даже при помощи CSS-параметра background-image. В нашей задаче нам нужно осуществить доступ к самому DOM в нашем SVG, поэтому мы воспользуемся строчными SVG-возможностями в HTML5, и подгрузим файл на нашу страницу при помощи jQuery.
Прежде всего, нам нужно создать 'div' в нашем HTML-документе:
<div id="stage"> <!-- Fallback Text Content can go here --> </div>
javascript-код
Затем, используя jQuery.load мы подгружаем SVG-файл в наш div #stage и задаем ему класс svgLoaded, который мы позднее сможем использовать для запуска нашей вступительной анимации:
$(function(){
$("#stage").load('interactive.svg',function(response){
$(this).addClass("svgLoaded");
if(!response){
// Error loading SVG!
// Make absolutely sure you are running this on a web server or localhost!
}
});
});
Важно: мы загружаем SVG при помощи javascript, чтобы получить доступ к его DOM. Chrome (и возможно другие браузеры) не позволит вам сделать это локально; он работает только при запуске с HTTP-протокола ввиду мер предосторожности. Так что, если вам возникают проблемы при получении SVG для загрузки, будьте уверены в том, что вы тестируете с веб-сервера или запускаете на localhost.
CSS-код
Учтите, что CSS по всему руководству не будет содержать браузерные префиксы, но они присутствуют в файлах.
Первое, что нам нужно сделать, это выставить некоторые стили div container. Стандартный образ действия SVG после загрузки заключается в том, чтобы адаптироваться под размер контейнера, поэтому важно выставить габариты контейнера в соответствии с размерами холста SVG.
#stage {
width: 1024px;
height: 1386px;
}
Стилизуем SVG-элементы: настраиваем transform-origin
Ключ анимации элементов нашего SVG-холста заключается в параметре transform-origin. По умолчанию, все трансформации любого элемента в нашем SVG происходят от (0px, 0px) SVG-холста. Для любого элемента, который мы хотим анимировать (например, увеличить или повернуть), нам нужно выставить соответствующее значение transform-origin относительно левого верхнего угла холста SVG. Origin будет отличаться у каждого элемента в зависимости от предпочитаемого эффекта/анимации, но в большинстве случае он будет равен центральной точке позиционирования элемента. Это может показаться утомительным, но все это довольно просто сделать за счет копирования информации координат, которые нам дает ПО для редактирования векторной графики.
#coffee {
transform-origin: 517px 484px;
}
#coffee-badge {
transform-origin: 445px 488px;
}
#coffee-title {
transform-origin: 310px 396px;
}
#coffee-details {
transform-origin: 311px 489px;
}
#design {
transform-origin: 514px 603px;
}
#design-badge {
transform-origin: 580px 606px;
}
#design-title {
transform-origin: 712px 513px;
}
#design-details {
transform-origin: 710px 620px;
}
#build {
transform-origin: 511px 769px;
}
#build-badge {
transform-origin: 445px 775px;
}
#build-title {
transform-origin: 312px 680px;
}
#build-details {
transform-origin: 310px 790px;
}
#complain {
transform-origin: 512px 1002px;
}
#complain-badge {
transform-origin: 586px 1000px;
}
#complain-title {
transform-origin: 718px 921px;
}
#complain-details {
transform-origin: 717px 1021px;
}
#beer {
transform-origin: 513px 1199px;
}
#beer-badge {
transform-origin: 444px 1193px;
}
#beer-title {
transform-origin: 313px 1097px;
}
#beer-details {
transform-origin: 316px 1202px;
}
Применяем исходные трансформации
В рисунке, который мы создали в программе, мы расположили его таким образом, чтобы отобразить состояние «hover» на каждом разделе временной шкалы. Поэтому нам нужно выставить некоторые исходные стили, которые иначе расположат некоторые вещи, и скроют конкретные объекты, которые мы не хотим отображать до того момента, пока не произойдет наведение курсора.
Для этого мы воспользуемся несколькими CSS-селекторами. В общем, мы выбираем объекты на основе их id «суффикса» (то, чем заканчивается id).
[id$=badge] { /* Any element with an id that ends in "badge" */
transform: scale(0.5, 0.5);
}
[id$=title] {
transform: scale(1.8) translate(0px, 48px);
}
[id$=details] {
transform: scale(0, 0);
}
Примечание: В Inkscape вы также можете задать класс, который позволит вам производить css-выбор на основе класса. Хотя у нас всегда есть возможность вручную добавлять классы в SVG, Illustrator будет подчищать эти чужеродные атрибуты при сохранении, а значит в дальнейшем у нас не будет возможности их изменить.
Добавляем стили :hover и применяем переходы
Мы выбираем элементы группы, предназначенной для состояния при наведенном курсоре, на временной шкале, у которых есть суффиксы badge, details и title, и преобразуем обратно в исходное состояние. Затем мы выставляем милый переход 0.25s для получения прикольного эффекта анимации.
#timeline > g:hover [id$=badge], #timeline > g:hover [id$=details] {
transform: scale(1, 1);
}
#timeline > g:hover [id$=title] {
transform: scale(1) translate(0px, 0px);
}
[id$=badge], [id$=title], [id$=details] {
transition: transform 0.25s ease-in-out;
}
Вступительная анимация
Чтобы создать привлекательное вступительное интро, мы воспользуемся несколькими CSS-анимациями. Чтобы сделать это, нам сначала нужно создать несколько ключевых кадров, которые позволят нам анимировать различные CSS-параметры:
@keyframes left-brace-intro {
0% {
transform: translateX(220px);
opacity: 0;
}
50% {
opacity: 1;
transform: translateX(220px);
}
100% {
transform: translateX(0px);
}
}
@keyframes right-brace-intro {
0% {
transform: translateX(-220px);
opacity: 0;
}
50% {
opacity: 1;
transform: translateX(-220px);
}
100% {
transform: translateX(0px);
}
}
@keyframes fade-in {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
@keyframes grow-y {
0% {
transform: scaleY(0);
}
100% {
transform: scaleY(1);
}
}
@keyframes grow-x {
0% {
transform: scaleX(0);
}
100% {
transform: scaleX(1);
}
}
@keyframes grow {
0% {
transform: scale(0, 0);
}
100% {
transform: scale(1, 1);
}
}
Создаем анимированное интро
При помощи нашей только что созданной пошаговой анимации, мы можем создать привлекательное вступление, просто применив анимации к различным элементам. Так как нам нужно, чтобы вступительная анимация проигрывалась только при первой загрузке SVG, мы можем воспользоваться потомственными селекторами на основе класса svgLoaded, который мы применяли ранее.
Чтобы вывести красивую анимацию, мы настраиваем параметры animation-delay, и выставляем animation-fill-mode: backwards, чтобы анимации оставались неподвижными на 0% в момент активности animation-delay.
.svgLoaded #logo {
animation: fade-in 0.5s ease-in-out;
}
.svgLoaded #quote-text {
animation: fade-in 0.5s ease-in-out 0.75s;
animation-fill-mode: backwards;
}
.svgLoaded #quote-left-brace {
animation: left-brace-intro 1s ease-in-out 0.25s;
animation-fill-mode: backwards;
}
.svgLoaded #quote-right-brace {
animation: right-brace-intro 1s ease-in-out 0.25s;
animation-fill-mode: backwards;
}
.svgLoaded #background {
animation: grow-y 0.5s ease-in-out 1.25s;
transform-origin: 512px 300px;
animation-fill-mode: backwards;
}
.svgLoaded #background > g {
animation: grow-x 0.25s ease-in-out 1.75s;
animation-fill-mode: backwards;
}
.svgLoaded #background > g:last-of-type {
transform-origin: 458px 877px;
}
.svgLoaded #background > g:first-of-type {
transform-origin: 563px 877px;
}
.svgLoaded #coffee, .svgLoaded #design, .svgLoaded #build, .svgLoaded #complain, .svgLoaded #beer {
animation: grow 0.25s ease-in-out;
animation-fill-mode: backwards;
}
.svgLoaded #coffee {
animation-delay: 2s;
}
.svgLoaded #design {
animation-delay: 2.25s;
}
.svgLoaded #build {
animation-delay: 2.5s;
}
.svgLoaded #complain {
animation-delay: 2.75s;
}
.svgLoaded #beer {
animation-delay: 3s;
}
Веб-шрифты
Так как мы воспользовались нестандартными шрифтами в нашем SVG, нам нужно включить их в веб-страницу, чтобы они правильно отображались. Работая над этим, важно правильно указывать имя шрифта, использованного при экспорте SVG. Мы открываем наш SVG-файл в текстовом редакторе и просто находим отрывок текста, где был использован наш шрифт, и находим там параметр font-family:
<!-- ... -->
<text font-family="'LeagueGothic'" font-size="28">12PM</text>
<!-- ... -->
Как видно, SVG был экспортирован с использованием font-family под названием 'LeagueGothic'. Так что, нам просто нужно указать веб-шрифт в нашем CSS при помощи того же названия. Тот же процесс, как и использование веб-шрифтов в обычном HTML.
@font-face {
font-family: 'LeagueGothic';
url("../fonts/league-gothic/league-gothic.eot.woff") format("woff");
}
И на этом все! Надеемся, что вам понравилось данное руководство, и вы найдете применение полученным знаниям! Нам хотелось бы услышать ваше мнение о SVG!
Посмотреть демо | Скачать исходный код
Внимание! У вас нет прав для просмотра скрытого текста.