Использование defs

В Snap.svg <defs> используется для хранения элементов, которые не отображаются напрямую на холсте, но могут быть многократно применены в графике через ссылки. Это аналог стандарта SVG, где <defs> содержит определения градиентов, паттернов, фильтров, символов и других повторно используемых элементов. В Snap.svg работа с <defs> обеспечивает удобное управление сложными композициями и снижает дублирование кода.

var s = Snap(800, 600);
var defs = s.defs;

Здесь s.defs возвращает объект <defs> документа SVG, куда можно добавлять элементы для последующего использования.


Градиенты

Градиенты являются одним из основных элементов, размещаемых в <defs>. Snap.svg поддерживает линейные и радиальные градиенты с удобным синтаксисом.

Линейный градиент:

var gradient = s.gradient("l(0, 0, 1, 0)#f00-#00f");
defs.append(gradient);

var rect = s.rect(50, 50, 200, 100);
rect.attr({ fill: gradient });
  • "l(0, 0, 1, 0)" указывает на линейный градиент слева направо.
  • #f00-#00f задаёт плавный переход от красного к синему.
  • defs.append(gradient) помещает градиент в <defs> для многократного использования.

Радиальный градиент:

var radial = s.gradient("r(0.5, 0.5, 0.5)#ff0-#0f0");
defs.append(radial);

var circle = s.circle(400, 100, 50);
circle.attr({ fill: radial });
  • "r(cx, cy, r)" задаёт центр и радиус радиального градиента.
  • Градиенты из <defs> можно ссылать на любое количество элементов.

Паттерны

Паттерны позволяют повторять определённую графику как текстуру. Они создаются с помощью <pattern> внутри <defs>:

var pattern = s.pattern(0, 0, 20, 20, function(p) {
    p.rect(0, 0, 10, 10).attr({ fill: "#0ff" });
    p.circle(15, 15, 5).attr({ fill: "#f0f" });
});
defs.append(pattern);

var rectPattern = s.rect(50, 200, 300, 150);
rectPattern.attr({ fill: pattern });
  • Функция s.pattern(x, y, width, height, callback) создаёт контейнер с повторяющейся графикой.
  • Паттерн помещается в <defs>, что позволяет использовать его на разных объектах без дублирования элементов.

Символы и использование <use>

Для многократного воспроизведения сложных объектов применяется <symbol> и <use>.

var symbol = s.symbol();
var star = s.polygon([0,10, 5,0, 10,10]).attr({ fill: "#ff0" });
symbol.add(star);
defs.append(symbol);

var instance1 = s.use(symbol, 100, 350);
var instance2 = s.use(symbol, 200, 400);
  • s.symbol() создаёт объект <symbol> для повторного использования.
  • s.use(symbol, x, y) создаёт копию символа в указанных координатах.
  • Символы могут быть масштабированы, окрашены и трансформированы независимо.

Фильтры и эффекты

Фильтры позволяют применять визуальные эффекты к элементам SVG, определяя их в <defs>:

var blurFilter = s.filter(Snap.filter.blur(5, 5));
defs.append(blurFilter);

var circle = s.circle(600, 150, 50);
circle.attr({ fill: "#f00", filter: blurFilter });
  • Snap.filter.blur(rx, ry) создаёт гауссово размытие.
  • Фильтр из <defs> можно применять к любому числу объектов с помощью атрибута filter.

Организация и оптимизация

  • Размещение повторно используемых объектов в <defs> снижает нагрузку на DOM и упрощает управление элементами.
  • Градиенты, паттерны, символы и фильтры должны быть определены один раз и ссылаться через атрибуты fill, filter или use.
  • Snap.svg автоматически управляет идентификаторами элементов в <defs>, предотвращая конфликты при многократном использовании.

Примеры сложного использования

Комбинация градиента и фильтра:

var gradient = s.gradient("l(0, 0, 1, 1)#ff0-#f00");
defs.append(gradient);

var blur = s.filter(Snap.filter.blur(3, 3));
defs.append(blur);

var rect = s.rect(400, 300, 150, 100);
rect.attr({
    fill: gradient,
    filter: blur
});
  • Использование <defs> позволяет комбинировать визуальные эффекты без дублирования кода.
  • Любые изменения в градиенте или фильтре автоматически применяются ко всем элементам, которые на них ссылаются.

Snap.svg через <defs> обеспечивает мощный механизм повторного использования и управления сложными SVG-структурами, упрощает создание динамических визуализаций и повышает производительность при работе с большим количеством элементов.