Библиотеки символов

Библиотеки символов позволяют организовывать и повторно использовать графические элементы без дублирования кода. В контексте SVG это реализуется через элементы <symbol> и <use>, а в SVG.js — через удобные абстракции, упрощающие создание, хранение и повторное применение графики.

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


Создание символов

В SVG.js символ создаётся с помощью метода symbol(). Внутри него описывается графика, которая затем может быть использована повторно.

const draw = SVG().addTo('#app').size(600, 400)

const star = draw.symbol()

star.polygon('50,0 61,35 98,35 68,57 79,91 50,70 21,91 32,57 2,35 39,35')
    .fill('#f06')

Особенности:

  • Символ не отображается напрямую на холсте
  • Он хранится в <defs> внутри SVG
  • Может содержать любые SVG-элементы

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

Для отображения символа применяется метод use():

draw.use(star).move(50, 50)
draw.use(star).move(150, 50).scale(0.5)
draw.use(star).move(250, 50).fill('#0f6')

Ключевые возможности:

  • Переиспользование одного и того же объекта
  • Индивидуальные трансформации (позиция, масштаб, поворот)
  • Возможность переопределения атрибутов (например, цвета)

Преимущества использования библиотек символов

1. Оптимизация памяти

  • Один объект хранится один раз
  • Использование через ссылки уменьшает размер SVG

2. Повышение производительности

  • Меньше DOM-узлов
  • Быстрее рендеринг

3. Централизованное управление

  • Изменение символа влияет на все его копии

Группировка символов

Символы могут включать группы (group()), что позволяет создавать сложные композиции:

const icon = draw.symbol()

const g = icon.group()

g.circle(50).fill('#ccc')
g.rect(20, 20).center(25, 25).fill('#333')

Такой подход позволяет:

  • Структурировать элементы
  • Применять трансформации к группе целиком

Вложенные символы

SVG.js позволяет использовать символы внутри других символов:

const small = draw.symbol()
small.circle(10).fill('blue')

const big = draw.symbol()
big.use(small).move(10, 10)
big.use(small).move(30, 10)

Практическое применение:

  • Создание компонентной графики
  • Построение сложных UI-элементов

Работа с атрибутами символов

Атрибуты, заданные при использовании (use()), могут переопределять исходные:

draw.use(star).fill('red')
draw.use(star).fill('green')

Однако важно учитывать:

  • Не все атрибуты наследуются корректно
  • Иногда требуется использовать attr() для точной настройки

Масштабирование и трансформации

Каждое использование символа может иметь собственные трансформации:

draw.use(star)
    .scale(2)
    .rotate(45)
    .translate(100, 100)

SVG.js предоставляет удобные методы:

  • scale()
  • rotate()
  • translate()
  • transform()

Использование viewBox в символах

Символы могут иметь собственную систему координат:

const sym = draw.symbol().viewbox(0, 0, 100, 100)

sym.rect(100, 100).fill('#ddd')
sym.circle(50).center(50, 50)

Это позволяет:

  • Независимо масштабировать символ
  • Создавать адаптивные элементы

Хранение символов в <defs>

SVG.js автоматически помещает символы в <defs>, что соответствует стандарту SVG:

<defs>
  <symbol id="...">
    ...
  </symbol>
</defs>

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

  • Символы не отображаются напрямую
  • Удобная организация ресурсов

Динамическое изменение символов

Изменение символа после его создания влияет на все экземпляры:

star.fill('blue')

Все элементы use(star) автоматически обновятся.

Это делает символы удобными для:

  • Темизации интерфейсов
  • Реактивной графики

Практика: создание библиотеки иконок

Типичный сценарий — создание набора иконок:

const icons = {
  play: draw.symbol(),
  pause: draw.symbol()
}

icons.play.polygon('0,0 50,25 0,50').fill('black')
icons.pause.rect(15, 50).move(0, 0)
icons.pause.rect(15, 50).move(25, 0)

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

draw.use(icons.play).move(10, 10)
draw.use(icons.pause).move(70, 10)

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

Библиотеки символов удобно выносить в отдельные файлы или модули:

export function createIcons(draw) {
  const star = draw.symbol()
  star.polygon(...)

  return { star }
}

Это обеспечивает:

  • Чистую архитектуру
  • Повторное использование в разных проектах

Ограничения и особенности

1. Нельзя напрямую взаимодействовать с use() как с оригиналом

  • Изменения применяются к экземпляру, а не к источнику

2. Стилизация через CSS ограничена

  • Иногда требуется inline-стили

3. События

  • Обработчики событий работают на уровне use(), а не symbol

Сравнение с клонированием (clone())

Подход Особенности
symbol + use Один источник, ссылки
clone() Полное копирование
const copy = star.clone()

Когда использовать:

  • symbol — для массового повторения
  • clone — когда нужна независимость элементов

Анимация символов

Анимация может применяться как к символу, так и к его экземплярам:

draw.use(star)
    .animate(1000)
    .rotate(360)

Если анимация задана внутри символа:

  • Все экземпляры наследуют её

Интеграция с внешними SVG

SVG.js позволяет импортировать SVG и превращать его в символ:

SVG().svg('<svg>...</svg>')

После чего элементы можно обернуть в symbol() для повторного использования.


Архитектурные подходы

1. Централизованная библиотека

  • Все символы создаются в одном месте

2. Ленивое создание

  • Символы создаются по мере необходимости

3. Кэширование

  • Повторное использование уже созданных символов

Типичные сценарии применения

  • Иконки интерфейса
  • Повторяющиеся декоративные элементы
  • Игровые объекты
  • Диаграммы и визуализация данных
  • UI-компоненты

Рекомендации по организации

  • Использовать понятные имена символов
  • Группировать по назначению
  • Выносить в отдельные модули
  • Минимизировать вложенность без необходимости
  • Использовать viewBox для универсальности

Отладка и инспекция

Символы можно инспектировать через DevTools:

  • Находятся внутри <defs>
  • Используются через <use xlink:href="...">

Это помогает:

  • Проверять структуру
  • Анализировать производительность
  • Искать ошибки в атрибутах

Расширение через плагины

SVG.js поддерживает плагины, которые могут расширять работу с символами:

  • Упрощённое управление библиотеками
  • Автоматическая регистрация
  • Генерация иконок

Итоговая структура использования

  1. Создание символа
  2. Наполнение графикой
  3. Сохранение в библиотеке
  4. Использование через use()
  5. Применение трансформаций и стилей

Такой подход формирует основу для построения масштабируемых и производительных графических интерфейсов на базе SVG.js.