В библиотеке SVG.js группировка элементов реализуется через объект
G (group), позволяющий объединять несколько SVG-элементов в
логическую структуру. Вложенные группы — это группы, которые содержат
внутри себя другие группы, формируя иерархию.
Такой подход позволяет:
Иерархия групп аналогична DOM-дереву: каждая группа может иметь родителя и потомков.
Базовое создание группы выполняется методом group():
const draw = SVG().addTo('#app').size(400, 400)
const parentGroup = draw.group()
const childGroup = parentGroup.group()
childGroup.rect(100, 100).fill('red')
В данном примере:
parentGroup — корневая группаchildGroup — вложенная группа внутри
parentGroupchildGroup, а значит косвенно
и parentGroupКаждый элемент знает своего родителя:
childGroup.parent() === parentGroup // true
Также можно получить всех потомков:
parentGroup.children()
Глубокая вложенность не ограничена:
const g1 = draw.group()
const g2 = g1.group()
const g3 = g2.group()
g3.circle(50)
Иерархия:
g1
└── g2
└── g3
└── circle
Одно из ключевых преимуществ вложенных групп — каскадное применение трансформаций.
parentGroup.translate(50, 50)
childGroup.rotate(45)
childGroup.rect(100, 100)
Результат:
rotate(45) к элементуtranslate(50, 50) от родителяПорядок трансформаций соответствует иерархии: трансформации родителя применяются после трансформаций потомка.
Некоторые атрибуты могут наследоваться:
parentGroup.fill('blue')
childGroup.rect(100, 100)
Прямоугольник будет синим, если у него не задан собственный
fill.
Однако не все свойства наследуются автоматически. Например,
transform не наследуется напрямую, а применяется через
матрицы преобразований.
Скрытие группы влияет на все вложенные элементы:
parentGroup.hide()
Все дочерние группы и элементы также станут невидимыми.
Показ:
parentGroup.show()
События могут “всплывать” по иерархии:
childGroup.on('click', () => console.log('child'))
parentGroup.on('click', () => console.log('parent'))
При клике по элементу внутри childGroup:
childGroupparentGroupЭто поведение аналогично DOM event bubbling.
Элемент можно переместить в другую группу:
const rect = childGroup.rect(100, 100)
parentGroup.add(rect)
Теперь:
childGroupparentGroupadd() и
put()Методы отличаются:
add() — добавляет существующий элементput() — аналогично, но возвращает сам элементconst rect = draw.rect(50, 50)
childGroup.add(rect)
Порядок элементов внутри группы влияет на отрисовку (z-index):
childGroup.front()
childGroup.back()
Для вложенных групп:
Удаление родительской группы удаляет всех потомков:
parentGroup.remove()
Удаление вложенной группы:
childGroup.remove()
Родитель останется, но дочерняя структура исчезнет.
Клонирование сохраняет структуру:
const clone = parentGroup.clone()
draw.add(clone)
Клон содержит:
const draw = SVG().addTo('#app').size(500, 500)
const scene = draw.group()
const house = scene.group()
const roof = house.group()
const windows = house.group()
house.rect(200, 150).move(100, 200).fill('#ccc')
roof.polygon('100,200 200,100 300,200').fill('#900')
windows.rect(30, 30).move(130, 230).fill('#fff')
windows.rect(30, 30).move(240, 230).fill('#fff')
Структура:
scene
└── house
├── roof
└── windows
Преимущества:
house.translate(...))house.scale(1.5)
Все элементы внутри house увеличатся пропорционально,
включая:
SVG.js использует матрицы трансформаций. Для вложенных групп итоговая матрица вычисляется как произведение всех матриц предков.
childGroup.transform({ scale: 2 })
parentGroup.transform({ rotate: 30 })
Итоговое преобразование элемента:
Matrix_final = Matrix_parent × Matrix_child
Вложенные группы позволяют разделять:
Пример:
const ui = draw.group()
const button = ui.group()
const icon = button.group()
button.rect(100, 50).fill('blue')
icon.circle(20).center(50, 25)
Теперь можно:
buttoniconАнимации применяются независимо:
parentGroup.animate(1000).move(200, 200)
childGroup.animate(1000).rotate(360)
Итог:
each()
для обходаparentGroup.each(function(i, children) {
console.log(this)
}, true)
Параметр true означает глубокий обход (включая вложенные
группы).
При работе с крупной графикой рекомендуется:
Пример структуры:
root
├── background
├── characters
│ ├── hero
│ └── enemies
└── ui
1. Потеря контекста при перемещении
Перемещение элемента между группами может изменить его визуальное положение из-за разных трансформаций.
2. Неправильный порядок трансформаций
Вложенность влияет на итоговую матрицу — порядок критичен.
3. Чрезмерная вложенность
Слишком глубокая иерархия усложняет:
Рекомендуется:
Каждая группа — это <g> элемент SVG:
<g>
<g>
<rect />
</g>
</g>
SVG.js управляет этой структурой, но понимание DOM помогает при отладке.
Вложенные группы в SVG.js — это:
Они позволяют строить сложные сцены, управлять ими на разных уровнях и создавать масштабируемую архитектуру SVG-графики.