Snap.svg — мощная библиотека для работы с векторной графикой SVG на JavaScript, предоставляющая удобный интерфейс для создания, анимации и управления элементами SVG. В контексте Angular её использование требует понимания жизненного цикла компонентов и особенностей работы с DOM.
Для работы с Snap.svg необходимо сначала установить библиотеку через npm:
npm install snapsvg-cjs --save
В компоненте Angular подключение выглядит следующим образом:
import { Component, AfterViewInit, ElementRef, ViewChild } from '@angular/core';
import Snap from 'snapsvg-cjs';
@Component({
selector: 'app-svg-demo',
template: `<div #svgContainer></div>`,
styles: [`div { width: 100%; height: 400px; }`]
})
export class SvgDemoComponent implements AfterViewInit {
@ViewChild('svgContainer', { static: true }) svgContainer!: ElementRef;
ngAfterViewInit(): void {
const s = Snap(this.svgContainer.nativeElement.offsetWidth, this.svgContainer.nativeElement.offsetHeight);
this.svgContainer.nativeElement.appendChild(s.node);
const circle = s.circle(100, 100, 50);
circle.attr({
fill: '#3498db',
stroke: '#2980b9',
strokeWidth: 5
});
}
}
Ключевые моменты:
AfterViewInit гарантирует, что элемент
контейнера уже присутствует в DOM.ViewChild обеспечивает доступ к элементу DOM для
инициализации Snap.svg.Snap.svg предоставляет удобный интерфейс для создания основных фигур:
const rect = s.rect(50, 50, 150, 100);
rect.attr({
fill: '#e74c3c',
stroke: '#c0392b',
strokeWidth: 4,
rx: 10, // скругление углов
ry: 10
});
const text = s.text(75, 120, 'Snap.svg + Angular');
text.attr({
fontSize: '20px',
fill: '#2c3e50'
});
Особенности:
.attr().s.group() для
совместного управления.Snap.svg обеспечивает плавные анимации через метод
.animate():
circle.animate(
{ cx: 300, cy: 200, r: 70, fill: '#2ecc71' },
1000, // продолжительность в миллисекундах
mina.bounce
);
Примечания:
mina предоставляет предустановленные кривые анимации
(linear, easein, easeout,
bounce и др.).circle.hover(), circle.click().Snap.svg интегрируется с событиями DOM и поддерживает собственные обработчики:
circle.click(() => {
circle.animate({ fill: '#f1c40f' }, 500, mina.easein);
});
rect.hover(
() => rect.attr({ fill: '#9b59b6' }),
() => rect.attr({ fill: '#e74c3c' })
);
Важно:
hover() принимает два колбэка: для наведения и ухода
курсора.Группировка элементов позволяет применять трансформации ко всем дочерним элементам одновременно:
const group = s.group(circle, rect, text);
group.transform('t50,50 r45'); // смещение и вращение
tX,Y — смещение на X и Y.rANGLE — вращение на угол.group.animate({ transform: 't0,0 r0' }, 1000, mina.easeinout);
Для обеспечения адаптивности можно привязывать размеры SVG к размеру контейнера:
ngAfterViewInit(): void {
const width = this.svgContainer.nativeElement.offsetWidth;
const height = this.svgContainer.nativeElement.offsetHeight;
const s = Snap(width, height);
this.svgContainer.nativeElement.appendChild(s.node);
window.addEventListener('resize', () => {
s.attr({ width: this.svgContainer.nativeElement.offsetWidth });
s.attr({ height: this.svgContainer.nativeElement.offsetHeight });
});
}
Snap.svg позволяет загружать и манипулировать SVG-файлами:
Snap.load('assets/logo.svg', (fragment) => {
s.append(fragment);
const logo = fragment.select('path');
logo.attr({ fill: '#e67e22' });
});
Особенности:
Snap.load() загружает SVG и передаёт его в виде
фрагмента..select() и
.selectAll() для изменения отдельных элементов SVG.ngAfterViewInit для
предотвращения ошибок при работе с DOM.*ngIf,
*ngFor) требует внимательности: элементы Snap.svg должны
создаваться после того, как контейнер гарантированно существует.Snap.svg в Angular позволяет создавать сложные интерактивные интерфейсы, сочетая мощь SVG с реактивной архитектурой фреймворка.