SVG.js и Vue

Для работы с SVG.js в проекте на Vue необходимо сначала установить библиотеку через npm:

npm install @svgdotjs/svg.js

Далее импорт выполняется в компоненте Vue:

import { SVG } from '@svgdotjs/svg.js';

Для инициализации SVG-контейнера можно использовать <div> или <svg> в шаблоне компонента:

<template>
  <div ref="drawingArea" style="width: 500px; height: 500px;"></div>
</template>

В mounted() создается экземпляр SVG:

mounted() {
  this.draw = SVG().addTo(this.$refs.drawingArea).size(500, 500);
}

Создание базовых элементов

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

// Круг
this.circle = this.draw.circle(100).attr({ fill: 'red', cx: 150, cy: 150 });

// Прямоугольник
this.rect = this.draw.rect(200, 100).attr({ fill: 'blue', x: 50, y: 50 });

// Линия
this.line = this.draw.line(0, 0, 300, 300).stroke({ width: 5, color: '#00ff00' });

Элементы можно динамически изменять:

this.circle.animate(1000).attr({ r: 50, fill: 'orange' });
this.rect.move(100, 200).animate(500).attr({ fill: 'purple' });

Работа с группами и слоями

Группы позволяют объединять элементы для совместной трансформации:

this.group = this.draw.group();
this.group.add(this.circle);
this.group.add(this.rect);

// Применение трансформации ко всей группе
this.group.rotate(45, 150, 150);
this.group.scale(1.5);

Использование слоев упрощает управление сложными сценами:

this.layer1 = this.draw.group().attr({ id: 'layer1' });
this.layer2 = this.draw.group().attr({ id: 'layer2');

this.layer1.add(this.rect);
this.layer2.add(this.circle);

Анимация и интерактивность

SVG.js обладает встроенной системой анимации:

this.circle.animate(2000, '<>').attr({ r: 80 }).loop(true, true);

Анимацию можно сочетать с событиями Vue:

this.circle.on('click', () => {
  this.circle.animate(500).attr({ fill: 'green' });
});

Работа с кривыми и сложными фигурами

Кривые Безье и полигоны создаются с помощью метода path и polygon:

// Кривая
this.path = this.draw.path('M10 80 C 40 10, 65 10, 95 80').fill('none').stroke({ color: 'black', width: 2 });

// Полигон
this.polygon = this.draw.polygon('200,10 250,190 160,210').fill('yellow').stroke({ color: 'orange', width: 3 });

Элементы path можно анимировать по траектории:

this.path.animate(2000).plot('M10 80 C 40 150, 65 150, 95 80');

Интеграция с реактивными данными Vue

Использование реактивных свойств позволяет синхронизировать SVG с состоянием компонента:

data() {
  return {
    circleRadius: 50,
    rectColor: 'blue'
  };
},
watch: {
  circleRadius(newRadius) {
    this.circle.radius(newRadius);
  },
  rectColor(newColor) {
    this.rect.fill(newColor);
  }
}

Также можно связывать события с реактивными методами:

methods: {
  increaseRadius() {
    this.circleRadius += 10;
  },
  changeRectColor(color) {
    this.rectColor = color;
  }
}

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

SVG.js поддерживает комплексные трансформации с указанием центра:

this.rect.rotate(30, 150, 150).scale(1.2, 1.2, 150, 150).translate(50, 50);

Комбинирование трансформаций с группами упрощает работу с интерактивными интерфейсами:

this.group.animate(1000).rotate(360).scale(1.5).loop(true, true);

Экспорт и сохранение SVG

SVG.js позволяет получить текущий код SVG для сохранения или отправки на сервер:

const svgData = this.draw.svg(); // Получение строки SVG
console.log(svgData);

Можно также экспортировать отдельные элементы:

const circleSVG = this.circle.svg();

Интеграция с Vue Composition API

При использовании Composition API и ref:

import { ref, onMounted } from 'vue';
import { SVG } from '@svgdotjs/svg.js';

export default {
  setup() {
    const drawingArea = ref(null);
    let draw;

    onMounted(() => {
      draw = SVG().addTo(drawingArea.value).size(500, 500);
      const circle = draw.circle(100).attr({ fill: 'red', cx: 150, cy: 150 });
    });

    return { drawingArea };
  }
};

Реактивность можно объединять с watch или computed, чтобы динамически управлять SVG в зависимости от состояния приложения.

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