Как манипулировать и анимировать SVG через Snap.svg
Оригинал: http://webdesign.tutsplus.com/articles/how-to-manipulate-and-animate-svg-with-snapsvg--cms-21323
Перевод: Влад Мержевич
В этом уроке мы расскажем о Snap.svg — библиотеке JavaScript, которая помогает при анимации и манипуляции содержимым SVG. Для демонстрации некоторых доступных возможностей мы сделаем анимацию глаза на SVG.
Что такое Snap.svg?
Snap.svg — это JavaScript-библиотека, которая позволяет легко создавать и управлять SVG графикой в современных браузерах. Это преемник Raphaël Дмитрия Барановского — самой популярной JavaScript-библиотеки для работы с SVG.
Raphäel
Raphäel.js — великолепная библиотека выпущенная в 2008 году, самой большой победой которой стала поддержка браузера IE5.5 и выше. Однако поддержка большинства браузеров вносит ограничения и означает, что нельзя реализовать последние разработки, вместо этого приходится полагаться на общий набор функций SVG.
Через некоторое время сообщество Raphäel.js разделилось на две части: одна группа опиралась на кроссбраузерную совместимость, а другая использовала библиотеку для создания SVG. Последней группе понадобились изменения для поддержки большинства возможностей SVG, с которыми Raphäel.js не мог справиться.
Поэтому был создан Snap.svg полностью написанный с нуля Дмитрием Барановским (в команде Adobe Web Platform) для того чтобы работать с SVG стало легче, с использованием последних возможностей, которые SVG может предложить, такие как: маскирование, шаблоны, градиенты, группирование, анимация и многое другое.
Что вы можете делать со Snap.svg?
Взгляните на документацию по API и вы увидите функции вроде mask, group, gradient, filter, animate и pattern, все они могут применяться к SVG.
Snap.svg поможет вам создать графику, но он также может работать с существующим SVG. Это значит, что ваше содержимое SVG не обязательно должно быть сделано через Snap.svg, вы также можете свободно манипулировать графикой полученной через такие инструменты как Adobe Illustrator, Inkscape или Sketch.
Начало работы со Snap.svg
Скачивание
Для начала вам нужно скачать Snap.svg. После этого вы обнаружите следующие файлы в архиве.
- demos — здесь находятся некоторые примеры, которые вы также найдёте в разделе Demo на их сайте.
- dist — уменьшенный и несжатый (для разработки) скрипт snap.svg.
- doc — здесь вы обнаружите документацию по API, которая также доступна на snapsvg.io
- src — компоненты, инструменты и плагины для работы Snap.svg вроде анимации, рисования, запуска задач для Grunt и др.
- test — папка содержит модульные тесты для Snap.svg.
Настройка проекта
После скачивания ресурсов Snap.svg начните новый веб-проект, который должен включать следующее:
- index.html — главный HTML-документ;
- js/snap.svg.js — подключение snap.svg;
- js/main.js — наш основной рабочий файл.
Создайте шаблон HTML и подключите скрипты scripts/snap.svg.js и scripts/main.js где-нибудь на вашей странице.
После этого вставьте контейнер <svg> внутрь <body> и дайте ему идентификатор. У вас должно получиться что-то типа этого.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Introducing Snap.svg</title>
<script src="js/snap.svg-min.js"></script>
<script src="js/main.js"></script>
<style>
#svg {
width: 600px; height: 300px;
}
</style>
</head>
<body>
<svg id="svg"></svg>
</body>
</html>
Работа с SVG
Давайте переместимся непосредственно к коду. Дальше вам понадобятся базовые знания JavaScript и понимание как он работает. Но это не особо важно, потому что мы не собираемся в этом уроке погружаться слишком глубоко.
Для начала инициализируем Snap указывающий на <svg> через создание и назначение переменной. В нашем случае она называется s.
var s = Snap("#svg");
Отсюда, через переменную s, мы получаем доступ ко всем методам Snap.svg. К примеру, мы хотим создать круг или прямоугольник.
- Круг может принимать три значения: x, y и радиус (проверьте Circle API);
- Прямоугольник может принимать шесть значений: x, y, ширина, высота, радиус по горизонтали и радиус по вертикали (проверьте Rect API);
- Эллипс может принимать четыре значения: x, y, радиус по горизонтали и радиус по вертикали (проверьте ellipse API).
// Круг с радиусом 80px
var circle = s.circle(90,120,80);
// Квадрат с размером стороны 160px
var square = s.rect(210,40,160,160);
// Эллипс с радиусом по вертикали 80px и радиусом по горизонтали 50px
var ellipse = s.ellipse(460,120,50,80);
Код выше покажет следующий результат.
Как вы можете видеть из прилагаемого скриншота, фигуры по умолчанию имеют цвет заливки #000 (чёрный) без какого-либо стиля. Давайте поиграем с ними и добавим несколько стилевых атрибутов, вроде цвета заливки, её прозрачности, а также цвета, толщины и прозрачности контура. Вы можете проверить SVG Attributes для подробной информации.
circle.attr({
fill: 'coral',
stroke: 'coral',
strokeOpacity: .3,
strokeWidth: 10
});
square.attr({
fill: 'lightblue',
stroke: 'lightblue',
strokeOpacity: .3,
strokeWidth: 10
});
ellipse.attr({
fill: 'mediumturquoise',
stroke: 'mediumturquoise',
strokeOpacity: .2,
strokeWidth: 10
});
Эти атрибуты сделали наши фигуры на SVG гораздо симпатичнее!
Дополнительная манипуляция SVG
Давайте возьмем наш пример и выйдем за рамки основ.
Группирование фигур
Snap.svg использует мощное оружие под именем group, которое, как следует из названия, группирует векторы вместе, делая их одной фигурой. Вы можете группировать сколько угодно фигур, добавляя их в виде списка. Давайте создадим два круга, сгруппируем их и уменьшим заливку каждого круга, чтобы было ясно видно, что происходит.
var circle_1 = s.circle(200, 200, 140);
var circle_2 = s.circle(150, 200, 140);
var circles = s.group(circle_1, circle_2);
circles.attr({
fill: 'coral',
fillOpacity: .6
});
Маскирование одних фигур другими
Теперь скажем, что мы хотим создать воображаемый глаз с помощью сгруппированных элементов, которые мы уже сделали. Для этого мы можем использовать mask. Для начала мы должны создать дополнительный эллипс и поместить его в середину группы.
var circle_1 = s.circle(300, 200, 140);
var circle_2 = s.circle(250, 200, 140);
var circles = s.group(circle_1, circle_2);
var ellipse = s.ellipse(275, 220, 170, 90);
circles.attr({
fill: 'coral',
fillOpacity: .6,
});
ellipse.attr({
opacity: .4
});
Теперь нам нужно маскировать круги нашим эллипсом, добавив к нему другой цвет заливки.
circles.attr({
fill: 'coral',
fillOpacity: .6,
mask: ellipse
});
ellipse.attr({
fill: '#fff',
opacity: .8
});
Анимация фигур
Продолжая наш пример мы можем сделать глаз мигающим, добавляя метод animate. Чтобы анимировать только что созданный эллипс, изменим у него радиус по вертикали с 1 до 90 (это текущее значение), а затем обратно. Сделаем анимацию и вставим её внутрь функции с именем blink.
function blink(){
ellipse.animate({ry:1}, 220, function(){
ellipse.animate({ry: 90}, 300);
});
};
В ней говорится, что мы собираемся анимировать с ry: 90 до ry: 1, и с ry: 1 до ry: 90 с разным временем. Теперь создайте setInterval для вызова метода blink каждые три секунды для эффекта мигания.
setInterval(blink, 3000);
Окончательный код должен выглядеть следующим образом:
var circle_1 = s.circle(300, 200, 140);
var circle_2 = s.circle(250, 200, 140);
// Группируем круги вместе
var circles = s.group(circle_1, circle_2);
var ellipse = s.ellipse(275, 220, 170, 90);
// Затем добавляем заливку цвета и прозрачости
// к кругу и применяем маску
circles.attr({
fill: 'coral',
fillOpacity: .6,
mask: ellipse
});
ellipse.attr({
fill: '#fff',
opacity: .8
});
// Создание эффекта мигания путём изменения значения
// rx для эллипса с 90px до 1px и обратно
function blink(){
ellipse.animate({ry:1}, 220, function(){
ellipse.animate({ry: 90}, 300);
});
};
// Вызываем метод blink каждые 3 секунды
setInterval(blink, 3000);
Поддержка браузеров
Как упоминалось ранее эти функции поддерживаются в современных браузерах: IE9+, Safari, Chrome, Firefox и Opera.
Бесплатно и с открытым исходным кодом
Snap.svg доступна под лицензией Apache 2, это значит, что библиотека совершенно бесплатна и с полностью открытым исходным кодом.
Выводы
Snap.svg понижает барьер для некоторых довольно удивительных манипуляций с SVG. Надеюсь, вам понравилось увиденное и это вдохновило вас иметь дело с SVG и дальше!