Яндекс.Метрика

Дизайн-журнал №1. Актуальная информация для дизайнеров, веб дизайнеров, программистов и разработчиков сайтов.

Интерактивная инфографика с SVG и CSS анимацией

2 октября 2013 | Опубликовано в css | 5 Комментариев »

В данном уроке мы научимся строить интерактивную инфографику с помощью SVG, CSS и JavaScript. Одной из менее обсуждаемых тем является свойство новых браузеров в увеличении поддержки файлов в формате SVG. В отличие от растровых изображений, например, PNG, JPG или GIF, векторная графика в файлах SVG абсолютно масштабируемая к любому размеру и будет отображаться при любом разрешении или плотности экрана без потери качества. Во многих случаях файлы SVG намного меньше по размеру и быстрее загружаются. Но самое интересное, что некоторые разработчики не понимают то, что SVG основан на спецификации XML и может применяться подобным образом к HTML.

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


                          Демо                         Загрузить исходные файлы


Подготовка SVG файла

Есть много способов создания графики SVG. В то время, как есть возможность сделать SVG, кодируя вручную, мы захотим для более сложной графики иметь некоторый тип векторного программного обеспечения, которое может экспортировать в формате SVG. Популярным выбором среди большинства дизайнеров может быть знакомый нам Adobe Illustrator, но есть и другие общедоступные приложения, например, Inkscape, который может быть более подходящим для наших целей.

Независимо от программного обеспечения, которое вы выберите, существенной остается возможность группировать объекты вместе и иметь возможность назвать эти группы (прописывая id атрибуты). Это позволяет нам организовывать наш SVG в соответствующую иерархию, к которой мы позже сможем получить доступ, используя CSS и/или JavaScript. У Illustrator и у Inkscape есть возможность делать это, выбирая многократные графические элементы, идя в Object > Group (группировать) (или Ungroup — разгруппировать) с главного меню.

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

В Illustrator это можно сделать в панели слои (layers). Просто найдите в панели объект, который вы желаете назвать, дважды кликните на поле слоя и введите желаемое 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, каждый тег <g> указывает на новую группу объектов, которые могут располагаться внутри других групп. Конечно, создавая SVG, не обязательно прописывать id каждому объекту/группе, но это будет более удобно в дальнейшем для доступа через CSS или JavaScript, и более простым для распознавания в разметке.

Загрузка SVG в HTML с помощью JAVASCRIPT

HTML

Есть способы включить или поместить SVG в HTML. Это возможно через использование тега <img>, тега <embed>, или с использованием свойства CSS’ background-image. Для наших целей нужен доступ к DOM внутри SVG. Мы будем использовать HTML5. SVG загрузим прямо в страницу, используя jQuery.

Во-первых, создадим блок div в HTML документе: 

<div id="stage"> <!-- Fallback Text Content can go here --> </div> 

JavaScript

Теперь, используя jQuery загрузку, загрузим файл SVG в #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 из соображений безопасности. 

CSS

Обратите внимание на то, что CSS в этом уроке не будет содержать никаких спецификаций для браузеров, но в файлах они будут.

Первым делом указываем некоторые стили для блока div. При загрузке SVG файл должен соответствовать размеру блока, поэтому важно установить размер блока соответственно размеру холста SVG. 

#stage {
    width: 1024px;
    height: 1386px;
} 

Стилизация элементов SVG: установка «transform-origins»

Ключ к оживлению элементов в пределах холста находится в свойстве transform-origin. По умолчанию все преобразования к любому элементу в SVG происходят от (0px, 0px) холста SVG. Для любого элемента, который мы желаем преобразовать (например, масштабировать, повернуть), необходимо установить подходящий transform-origin относительно левой и верхней стороны холста SVG. Источник будет отличаться от каждого элемента в зависимости от желаемого эффекта/анимации, но в большинстве случаев будет равняться центральной точке, где элемент уже помещен. Это может быть довольно утомительно, но проще просто скопировать координатную информацию, которая представлена в нашем векторном редакторе.  

#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;
} 

Применение некоторых начальных преобразований

Нам необходимо установить начальные стили для изменения позиции некоторых объектов. А также необходимо скрыть определенные объекты, которые мы не хотим показывать до момента наведения на них курсора.

Для того, чтобы это сделать мы будем использовать селекторы CSS. В основном мы выбираем объекты с 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);
}

Добавление стиля для :hover и применение переходов

Мы выбираем элементы внутри группы hovered и превращаем их обратно в исходное положение. Затем устанавливаем переход 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);
    }
} 

Создание анимационной последовательности

Мы можем использовать селекторы, основанные на классе svgLoaded, который мы применяли ранее.

Для того, чтобы задать анимационную последовательность, зададим свойство animation-delay, и установим animation-fill-mode: backwards так, чтобы анимация была с паузами.

.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;
} 

WEB-шрифты

Так как мы использовали нестандартные шрифты в нашем файле SVG, нам необходимо включить их также в нашу веб-страницу. Важно указать правильно имя шрифта, который был использован при экспорте SVG. Мы открываем файл SVG в текстовом редакторе и просто находим текст, где использовался шрифт, и смотрим на свойство font-family: 

<!-- ... -->
<text font-family="'LeagueGothic'" font-size="28">12PM</text>
<!-- ... --> 

Как мы можем видеть, файл SVG был экспортирован с использованием шрифта font-family с именем ‘LeagueGothic’. Таким образом мы просто должны определить веб-шрифт в CSS, используя точно такое же имя.

@font-face {
    font-family: 'LeagueGothic';
    url("../fonts/league-gothic/league-gothic.eot.woff") format("woff");
 }

Это все! Надеемся, что вам понравился урок и вы нашли его полезным и информативным. Будем рады услышать ваши комментарии. 

Перевод — Дежурка.

Автор — Adam Coulombe.

Читайте также: Полезные jQuery плагины.




Комментарии

  1. илья
    Thumb up Thumb down +2

    четко. спасибо =)

  2. Роман
    Thumb up Thumb down +1

    Чётко, да чётко, но вот в последней Опере не работает...

  3. Александр
    Thumb up Thumb down +2

    Вынашиваю проект разработки интерактивной принципиальной схемы авто, ваша статья мне дала более чёткое представление что мне делать и как. Добавлю в закладки. Спасибо!