Переиспользование элементов

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


Символы и <use>

Snap.svg поддерживает создание символов (<symbol>) и их использование через <use> для многократного отображения одного и того же элемента.

var s = Snap(800, 600);

// Создание символа
var circleSymbol = s.symbol();
circleSymbol.add(s.circle(0, 0, 50).attr({ fill: "red" }));

// Использование символа через <use>
var instance1 = s.use(circleSymbol).transform("t100,100");
var instance2 = s.use(circleSymbol).transform("t300,200");

Особенности символов:

  • Символы хранятся в <defs> и не рендерятся напрямую, пока не используется <use>.
  • Все экземпляры <use> наследуют изменения атрибутов символа, если они не переопределены локально.
  • Можно применять трансформации к каждому экземпляру независимо.

Клонирование элементов

Snap.svg позволяет создавать копии элементов через метод clone(). В отличие от символов, клон создаёт отдельный элемент, полностью независимый от оригинала.

var rect = s.rect(50, 50, 100, 100).attr({ fill: "blue" });
var cloneRect = rect.clone();
cloneRect.transform("t200,0");
cloneRect.attr({ fill: "green" });

Ключевые моменты клонирования:

  • Клон наследует все атрибуты оригинала на момент создания.
  • Последующие изменения оригинала не затрагивают клон.
  • Полезно для динамического создания множества элементов с одинаковой базовой формой.

Группировка элементов

Группы (<g>) позволяют объединять несколько элементов в единое целое, что облегчает манипуляции и переиспользование.

var circle1 = s.circle(0, 0, 30).attr({ fill: "orange" });
var circle2 = s.circle(60, 0, 30).attr({ fill: "purple" });

var group = s.group(circle1, circle2);
group.transform("t100,100 r45");

Преимущества групп:

  • Трансформации применяются ко всей группе сразу.
  • Можно клонить всю группу целиком.
  • Можно хранить группы как символы и использовать их через <use>.

Динамическое переиспользование через функции

Для сложных проектов удобно создавать функции-конструкторы элементов. Это позволяет создавать новые экземпляры с индивидуальными свойствами, но с одинаковой структурой.

function createStar(x, y, radius, color) {
    var star = s.polygon([0, -radius, radius/2, radius/2, -radius/2, radius/2])
                .attr({ fill: color });
    return star.transform(`t${x},${y}`);
}

var star1 = createStar(100, 100, 50, "yellow");
var star2 = createStar(300, 150, 30, "red");

Преимущества такого подхода:

  • Легко генерировать сложные элементы с параметрами.
  • Код остаётся чистым, нет повторяющихся блоков.
  • Можно комбинировать с клонами или символами для максимальной оптимизации.

Комбинированное использование символов и групп

Символы и группы можно комбинировать для создания библиотек переиспользуемых компонентов:

// Создание группы
var houseGroup = s.group(
    s.rect(-50, 0, 100, 100).attr({ fill: "brown" }),
    s.polygon([-60,0, 0,-60, 60,0]).attr({ fill: "red" })
);

// Превращение группы в символ
var houseSymbol = s.symbol();
houseSymbol.add(houseGroup);

// Использование символа
s.use(houseSymbol).transform("t200,200 s0.5");
s.use(houseSymbol).transform("t400,100 s1");

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


Работа с атрибутами экземпляров

Даже при использовании символов и <use> можно задавать уникальные атрибуты каждому экземпляру:

var circleSymbol = s.symbol();
circleSymbol.add(s.circle(0, 0, 40));

var c1 = s.use(circleSymbol).attr({ fill: "blue" }).transform("t50,50");
var c2 = s.use(circleSymbol).attr({ fill: "green" }).transform("t150,150");
  • Атрибуты, установленные через attr(), переопределяют атрибуты символа только для конкретного экземпляра.
  • Трансформации также независимы для каждого <use>.

Практические советы

  • Для повторяющихся простых элементов лучше использовать символы и <use> — это экономит память.
  • Для динамических элементов с уникальными свойствами чаще используют clone() или функции-конструкторы.
  • Группы упрощают управление множеством связанных элементов и позволяют применять трансформации коллективно.
  • Комбинирование символов и групп идеально подходит для построения UI-компонентов и игровых сцен в SVG.

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