Интеграция с canvas

Библиотека SVG.js предназначена для работы с векторной графикой в формате SVG. Однако иногда возникает необходимость комбинировать возможности SVG с растровыми элементами Canvas для создания сложных визуальных эффектов, таких как динамические анимации, фильтры, текстуры или экспорт изображений. Интеграция SVG.js с <canvas> требует понимания преобразования векторных элементов в растровый контекст.


Создание Canvas и SVG

Для начала необходимо создать элемент <canvas> и контейнер SVG:

// Создание canvas
const canvas = document.createElement('canvas');
canvas.width = 800;
canvas.height = 600;
document.body.appendChild(canvas);
const ctx = canvas.getContext('2d');

// Создание SVG с помощью SVG.js
const draw = SVG().addTo('body').size(800, 600);
const rect = draw.rect(200, 100).fill('#f06').move(100, 50);

Здесь rect — простой прямоугольник, который позже будет преобразован в растровый формат для Canvas.


Экспорт SVG в изображение

SVG.js позволяет получить SVG-код элемента, который затем можно использовать для создания объекта Image, совместимого с Canvas:

const svgData = draw.svg(); // Получаем SVG как строку
const img = new Image();
const svgBlob = new Blob([svgData], { type: 'image/svg+xml;charset=utf-8' });
const url = URL.createObjectURL(svgBlob);

img.onl oad = function() {
    ctx.drawImage(img, 0, 0); // Рисуем SVG на Canvas
    URL.revokeObjectURL(url); // Освобождаем память
};
img.src = url;

Ключевой момент: создание Blob и URL позволяет использовать любой SVG как источник изображения для Canvas.


Преобразование отдельных элементов SVG

Для динамических интерфейсов часто нужно рендерить не весь SVG, а отдельные элементы:

const circle = draw.circle(80).fill('blue').move(300, 200);

// Получаем SVG отдельного элемента
const circleSVG = circle.svg();
const circleBlob = new Blob([circleSVG], { type: 'image/svg+xml;charset=utf-8' });
const circleUrl = URL.createObjectURL(circleBlob);

const circleImg = new Image();
circleImg.onl oad = function() {
    ctx.drawImage(circleImg, 300, 200);
    URL.revokeObjectURL(circleUrl);
};
circleImg.src = circleUrl;

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


Анимация SVG на Canvas

Для создания анимации можно использовать методы SVG.js, одновременно обновляя Canvas. Основная идея — каждый кадр рендерить текущий SVG в Canvas:

let angle = 0;

function animate() {
    ctx.clearRect(0, 0, canvas.width, canvas.height); // Очистка Canvas
    rect.rotate(angle); // Поворот SVG элемента
    const svgData = rect.svg();
    const img = new Image();
    const blob = new Blob([svgData], { type: 'image/svg+xml;charset=utf-8' });
    const url = URL.createObjectURL(blob);

    img.onl oad = function() {
        ctx.drawImage(img, rect.x(), rect.y());
        URL.revokeObjectURL(url);
        requestAnimationFrame(animate); // Следующий кадр
    };
    img.src = url;
    angle += 1; // Увеличение угла
}

animate();

Важно: частое создание Blob может быть ресурсоёмким. Для производительных приложений лучше использовать кэширование изображений или OffscreenCanvas.


Использование фильтров и эффектов

Canvas поддерживает растровые фильтры, которые невозможно применить напрямую к SVG. Для интеграции:

ctx.filter = 'blur(5px) drop-shadow(3px 3px 2px gray)';
ctx.drawImage(img, 0, 0);
ctx.filter = 'none';

Такой метод позволяет комбинировать векторные формы SVG с растровыми эффектами Canvas, расширяя визуальные возможности.


Работа с текстом и шрифтами

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

const text = draw.text('Привет SVG.js!').font({ size: 40, family: 'Arial' });
const svgData = text.svg();
const img = new Image();
const blob = new Blob([svgData], { type: 'image/svg+xml;charset=utf-8' });
const url = URL.createObjectURL(blob);

img.onl oad = function() {
    ctx.drawImage(img, 50, 300);
    URL.revokeObjectURL(url);
};
img.src = url;

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


Синхронизация событий

Canvas не поддерживает нативные события для SVG-элементов. Для обработки кликов и взаимодействий можно использовать SVG.js для отслеживания событий на элементах до их рендеринга на Canvas:

rect.click(() => {
    console.log('Прямоугольник на Canvas был активирован через SVG.js');
});

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


Практическое использование

Интеграция SVG.js с Canvas эффективна для:

  • Создания динамических визуализаций с высокой степенью кастомизации.
  • Применения фильтров, теней и растровых эффектов к векторным формам.
  • Экспорта SVG в растровые форматы (PNG, JPEG) для сохранения и печати.
  • Комбинирования интерактивных SVG-элементов с анимацией на Canvas.

Такой подход объединяет гибкость векторной графики и производительность растрового рендеринга.