SVG.js и Angular

Для работы с SVG в Angular используется библиотека SVG.js, которая предоставляет удобный и гибкий API для создания и управления векторной графикой. Основная концепция заключается в том, что элементы SVG создаются динамически через объекты SVG() и манипулируются методами библиотеки, без необходимости писать громоздкий HTML-код вручную.

Установка и подключение

Установка SVG.js в проект Angular выполняется через npm:

npm install @svgdotjs/svg.js

После установки импортируем необходимые функции в компонент:

import { Component, OnInit, ElementRef, ViewChild } from '@angular/core';
import { SVG, Svg } from '@svgdotjs/svg.js';

Создаётся контейнер для SVG в шаблоне компонента:

<div #svgContainer></div>

В компоненте создаётся ссылка на этот контейнер через ViewChild:

export class SvgComponent implements OnInit {
  @ViewChild('svgContainer', { static: true }) svgContainer!: ElementRef<HTMLDivElement>;
  private draw!: Svg;

  ngOnInit(): void {
    this.draw = SVG().addTo(this.svgContainer.nativeElement).size('100%', '100%');
  }
}

Создание и управление элементами

SVG.js предоставляет методы для создания любых SVG-элементов: rect, circle, line, text, path.

Пример: создание прямоугольника и круга

ngOnInit(): void {
  this.draw = SVG().addTo(this.svgContainer.nativeElement).size('100%', '100%');

  const rect = this.draw.rect(100, 50).attr({ fill: '#3498db', x: 50, y: 50 });
  const circle = this.draw.circle(80).attr({ fill: '#e74c3c', cx: 200, cy: 75 });
}

Ключевые методы управления элементами:

  • attr({}) – установка атрибутов SVG;
  • move(x, y) – перемещение элемента;
  • size(width, height) – установка размеров;
  • fill(color) и stroke(color, width) – стилизация;
  • animate(duration) – анимация свойств.

Работа с анимациями

Анимации в SVG.js упрощают создание интерактивной графики. Можно анимировать координаты, размеры, цвета и прозрачность.

Пример анимации прямоугольника:

rect.animate(2000, '<>').move(200, 200).loop(true, true);

Параметры:

  • 2000 – длительность в миллисекундах;
  • '<>' – тип easing (ускорение/замедление);
  • loop(true, true) – бесконечная анимация с обратным проигрыванием.

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

SVG.js позволяет объединять элементы в группы для коллективных трансформаций:

const group = this.draw.group();
group.add(rect);
group.add(circle);
group.rotate(45, 150, 150); // Поворот всей группы

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


Работа с событиями

SVG.js поддерживает работу с событиями, совместимую с Angular:

rect.on('click', () => {
  rect.fill({ color: '#2ecc71' });
});

circle.on('mouseenter', () => {
  circle.animate(300).scale(1.2);
});

circle.on('mouseleave', () => {
  circle.animate(300).scale(1);
});

Использование событий совместно с Angular упрощает создание интерактивных графиков и UI-компонентов.


Интеграция с Angular Change Detection

При динамическом обновлении данных Angular, особенно при использовании Observables или ngFor, важно управлять DOM через Renderer2 или напрямую через методы SVG.js, чтобы изменения в модели корректно отображались:

import { Renderer2 } from '@angular/core';

constructor(private renderer: Renderer2) {}

updateRect(rect: any, newWidth: number) {
  this.renderer.setAttribute(rect.node, 'width', newWidth.toString());
}

Использование renderer гарантирует, что изменения будут корректно обработаны Angular без конфликтов с внутренней системой обнаружения изменений.


Работа с масштабированием и координатными системами

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

this.draw.viewbox(0, 0, 400, 200); // Установка видимой области
this.draw.zoom(2, 200, 100); // Масштабирование с центром (200, 100)

Это особенно важно при построении диаграмм, интерактивных карт или сложных интерфейсов.


Создание сложных графиков и диаграмм

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

const data = [30, 70, 50, 90];
data.forEach((value, index) => {
  this.draw.rect(40, value)
    .attr({ fill: '#3498db', x: 50 + index * 50, y: 150 - value })
    .animate(1000)
    .height(value);
});

Использование циклов и динамических атрибутов позволяет создавать диаграммы, изменяющиеся в реальном времени, реагируя на обновления данных Angular.


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

SVG.js поддерживает подключение плагинов для дополнительных возможностей:

  • svg.filter.js – фильтры и эффекты;
  • svg.pathmorphing.js – анимация путей;
  • svg.draggable.js – перетаскивание элементов.

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

import '@svgdotjs/svg.draggable.js';

rect.draggable().on('dragend', (e) => {
  console.log('Новая позиция:', e.detail.box.x, e.detail.box.y);
});

Плагины расширяют возможности библиотеки, делая её удобной для интерактивных приложений в Angular.


Оптимизация производительности

При работе с большими SVG-графиками важно учитывать производительность:

  • Минимизировать количество элементов в DOM.
  • Использовать группы для пакетных трансформаций.
  • Ограничивать частоту анимаций.
  • Применять requestAnimationFrame для сложных анимаций.

Эти подходы позволяют поддерживать плавность интерфейса даже при сложной визуализации данных.


SVG.js в связке с Angular предоставляет мощный инструмент для создания интерактивной, динамической и масштабируемой векторной графики, с полной поддержкой событий, анимаций и структурирования элементов.