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

http://tympanus.net/codrops/2013/02/06/interactive-infographic-with-svg-and-css-animations/
  • Перевод
  • Tutorial
Одной из наименее обсуждаемых функций, все чаще появляющейся в последних браузерах, является поддержка файлов формата SVG. Этот формат характеризуется абсолютной свободой в отображении: легко изменяется в размере, может быть отображен в любом разрешении без потери качества. Во многих случаях SVG весят гораздо меньше, чем, например, PNG или JPG.

image

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

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

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


Существует множество способов создания графики SVG, начиная от знакомого вам Adobe Illustrator и заканчивая бесплатным Inkscape. Не зависимо от выбора софта, очень важно сгруппировать объекты вместе и дать этим группам имена. Это позволит нам превратить наш SVG в определенную иерархию, которую в дальнейшем мы будем использовать в CSS и/или JavaScript.

image

В нашем примере, когда мы сохраняем наш SVG и открываем его в текстовом редакторе, мы получим следующую структуру:

<g id="background">
    <g id="bg-lines-left"> <!-- левые фоновые линии  --> </g>
    <g id="bg-lines-right"> <!-- правые фоновые линии -->  </g>
</g>
<g id="logo"> <!-- логотип -->  </g>
<g id="quote">
    <g id="quote-left-brace"> <!-- левая скобки цитаты -->  </g>
    <g id="quote-right-brace"> <!-- правая скобка цитаты --> </g>
    <g id="quote-text"> <!-- цитата --> </g>
</g>
<g id="timeline">
    <g id="coffee">
        <rect id="coffee-bar" />
        <polyline id="coffee-arrow" />
        <g id="coffee-time"> <!-- время --> </g>
        <g id="coffee-badge">
            <circle id="coffee-circle" />
            <g id="coffee-title"> <!-- заголовок --> </g>
            <g id="coffee-details"> <!-- иконка, описание --> </g>
        </g>
    </g>
    <g id="design">
        <rect id="design-bar" />
        <polyline id="design-arrow" />
        <g id="design-time"> <!-- время--> </g>
        <g id="design-badge">
            <circle id="design-circle" />
            <g id="design-title"> <!-- заголовок --> </g>
            <g id="design-details"> <!-- иконка, описание --> </g>
        </g>
    </g>
    <g id="build">
        <rect id="build-bar" />
        <polyline id="build-arrow" />
        <g id="build-time"> <!-- время --> </g>
        <g id="build-badge">
            <circle id="build-circle" />
            <g id="build-title"> <!-- заголовок --> </g>
            <g id="build-details"> <!-- иконка, описание--> </g>
        </g>
    </g>
    <g id="complain">
        <rect id="complain-bar" />
        <polyline id="complain-arrow" />
        <g id="complain-time"> <!-- время --> </g>
        <g id="complain-badge">
            <circle id="complain-circle" />
            <g id="complain-title"> <!-- заголовок --> </g>
            <g id="complain-details"> <!-- иконка, описание --> </g>
        </g>
    </g>
    <g id="beer">
        <rect id="beer-bar" />
        <polyline id="beer-arrow" />
        <g id="beer-time"> <!-- время --> </g>
        <g id="beer-badge">
            <circle id="beer-circle" />
            <g id="beer-title"> <!-- заголовок --> </g>
            <g id="beer-details"> <!-- иконка, описание --> </g>
        </g>
    </g>
</g>


Код, указанный выше, был нарочно уменьшен для того, чтобы просто показать вам структуру, к которой мы идем. Вы наверняка заметите много знакомого от HTML, но и новые моменты тоже присутствуют.

Как мы можем видеть, каждый тег <g> содержит группу объектов, которая может быть помещена в другие группы. Конечно, во время создания SVG, не обязательно приписывать id каждому объекту или группе, это делается лишь для того, чтобы в дальнейшем при работе с CSS и JavaScript было легче использовать SVG.

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


HTML

Существуют множество способов вставить SVG внутрь HTML. Это возможно осуществить с помощью тега <img>, <embed> tag, или даже используя свойство CSS «background-image».

Во-первых, мы создадим div внутри нашего HTML документа:
<div id="stage"> <!-- Все текстовое содержимое находится здесь --> </div>


JavaScript

Затем, используя jQuery.load, мы загрузим SVG файл в див #stage и назначим ему класс svgLoaded, который позднее мы будем использовать для анимирования:
$(function(){
 
    $("#stage").load('interactive.svg',function(response){
 
        $(this).addClass("svgLoaded");
         
        if(!response){
            // Ошибка при загрузке SVG!
        }
 
    });
});


Важно: Мы загружаем SVG файл с помощью JavaScript, чтобы получить доступ к HTML содержимому файла. Chrome (и возможно другие браузеры) не позволят осуществить это локально; это сработает лишь при использовании протокола HTTP в целях безопасности. Таким образом, если у вас возникнут проблемы с загрузкой SVG файла, убедитесь, что вы тестирует с веб сервера или localhost

CSS


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

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

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


Стилизуем элементы SVG: назначаем параметр transform-origin

Ключ к анимированию элемента в рамках SVG лежит в параметре transform-origin. По умолчанию все трансформации начинаются в точке (0px, 0px). Для каждого элемента, который мы будет трансформировать (например, вращать или масштабировать) нам необходимо назначить параметр 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;
}


Применяем начальные трансформации


[id$=badge] { /* Каждый элемент с id, заканчивающимся на "badge" */
    transform: scale(0.5, 0.5);
}
[id$=title] { 
    transform: scale(1.8) translate(0px, 48px);
}
[id$=details] { 
    transform: scale(0, 0);
}


Добавляем :hover и применяем переходы (transitions)


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


Интро анимация


@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 #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:
<!-- ... -->
<text font-family="'LeagueGothic'" font-size="28">12PM</text>
<!-- ... -->

Как мы видим, файл SVG был создан при использованияя шрифта ‘LeagueGothic’, название которого мы просто скопируем в CSS.
@font-face {
    font-family: 'LeagueGothic';
    url("../fonts/league-gothic/league-gothic.eot.woff") format("woff");
 }

Ну вот и все! Я надеюсь вам понравился наш туториал, и он оказался для вас полезным и информативным. Пишите в комментариях о своих примерах использования SVG и делитесь с нами своим опытом!

СКАЧАТЬ ИСХОДНИКИ | ПОСМОТРЕТЬ ДЕМО

От переводчика. Со всеми пожеланиями и замечаниями по поводу перевода прошу обращаться ко мне в личку. Спасибо!
Поделиться публикацией
AdBlock похитил этот баннер, но баннеры не зубы — отрастут

Подробнее
Реклама
Комментарии 18
  • –8
    ПОЖАЛУЙСТА, УБЕРИТЕ КАПС ИЗ ЗАГОЛОВКОВ
    (простите, не прочитал примечания в конце)
    • +1
      А еще svg это популярный формат во многих системах digital-signage. В связке с JS очень мощный инструмент в руках профессионала.
      • +1
        Есть библиотеки, которые немного упрощают (вопрос привычки) работу с svg для javascript. Например, http://d3js.org/.
        • 0
          Вряд ли стоит использовать d3js для того что бы упростить работу с svg. Есть куча более специализированных библиотек для работы с графикой.
        • 0
          У меня Опера 12.14 под Ubuntu, к сожалению нет анимации в шкале. Сперва не понял в чём идея, пока не открыл в хромиуме.
          • +1
            Opera 12.14 под Windows 7 — тоже нет анимации.
            А ещё в Opera под Android не работает кнопки «Предпросмотр» и «Написать» на хабре.
          • 0
            1. Что-то этот интерактив не работает нигде кроме Хрома (даже в Сафари, проверял на 5-й версии), хотя префиксы вроде бы в стоят (включая ненужные -ms-).
            2. Почему используется animation, а не transition?
            3. Пример дурацкий, ему интерактив как пятая нога, без него лучше. Я бы ещё понял, если на графике можно было посмотреть детали в конкретных участках. Реагировать лучше по щелчку (тапу), это позволит избежать случайного мельтешения и улучшит опыт на сенсорных устройствах.
            4. И да, если пишите прописными буквами, то хотя бы добавьте разрядку, как это сделано в левой верхней части. Прописные буквы расчитаны на набор со строчными буквами, а не прописными в ряд. А лучше вообще не злоупотреблять ими.
            • +1
              Safari 6 все ок
              • 0
                «нигде, кроме Хрома» — неправда. Фаерфокс 18 под Убунту нормально и шустро всё показывает.
              • +1
                • –1
                  Но самое клевое свойство SVG, о котором многие разработчики не знают, это то, что этот формат построен на спецификации XML.


                  Что, правда? Многие не знают? О.

                  Мы загружаем SVG файл с помощью JavaScript, чтобы получить доступ к HTML содержимому файла.


                  Ничего не понял.
                  • НЛО прилетело и опубликовало эту надпись здесь
                    • 0
                      Долго думал над этим предложением, и не знал как лучше всего его преподнести… Предложите свой вариант!
                      • 0
                        Мы загружаем SVG файл с помощью JavaScript, чтобы получить доступ к его элементам с помощью DOM.

                        Как то так.
                        Следует заметить, что популрный jquery без плагинов работать со свойствами и параметрами svg не умеет. Use Jquery.svg.dom, Luke!
                        • 0
                          Если будет время — напишем статью как мы работаем с блоками на svg поверх google карты в нашем бета-проекте и почему мы перешли на svg с canvas
                        • НЛО прилетело и опубликовало эту надпись здесь
                    • 0
                      Замечательная идея для создания инфографики. Инфографика в так формате может еще и прибыль на рекламе давать
                      • 0
                        Вот отличный пример как не надо делать web графику, в том числе и инфографику.

                        Основная критика — не обеспечен принцип graceful degradation для недостаточно старых, но популярных браузеров.
                        Реализация «нет SVG — не печенек», подходит разве что для демок, для продакшена не подходит.

                        Ну и принцип «не плодить лишних сущностей без необходимости» автору видимо не знаком. Думаю вполне очевидно, что в этом примере можно вполне было бы обойтитсь только HTML и CSS стилями без использования SVG, JS и тем более jQuery.
                        Все таки это же не Duck Hunt на чистом СSS писать.

                        Если же это все-таки пример ради примера, чтобы показать связку CSS-SVG, то как минимум это надо озвучить, и предложить варианты попрактичнее.

                        Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.