Импорт SVG в Fabric.js: редактируемая графика на canvas
Импортируйте SVG в Fabric.js как редактируемые объекты, перекрасьте одну часть и экспортируйте проверенную копию SVG. Следуйте примеру и отличайте проблемы исходника от ошибок API.
На этой странице
Чтобы импортировать редактируемый SVG в Fabric.js, дождитесь loadSVGFromString() или loadSVGFromURL(), затем добавьте возвращённые объекты на canvas. Сохраните ссылку на редактируемую часть, измените её заливку и экспортируйте через canvas.toSVG(). Загрузка графики как изображения даёт другую модель редактирования: выбор этого изображения не раскрывает каждую цветную область как отдельную фигуру.
Это различие важно для конфигуратора товаров, редактора значков или перекрашиваемой иконки. Вам нужны объекты, соответствующие частям, которые может менять пользователь. Расширение .svg не гарантирует такую структуру.
Этот пример использует Fabric.js 7.4.0 и небольшую лампу, написанную вручную. Он проверяет три фигуры через импорт, перекрашивание и экспорт. Это собственный кодовый образец, а не преобразование PerfectVector или утверждение, что все возможности SVG сохраняются на том же пути.
Выберите модель объектов перед загрузчиком
Fabric.js разбирает SVG в собственные объекты canvas. Вы редактируете их через API Fabric; это не живые элементы DOM SVG внутри canvas. Текущий справочник loadSVGFromString описывает promise, возвращающий результат разбора, и reviver, получающий каждый исходный элемент и созданный для него объект.
| Ваша задача | Полезная отправная точка | Что проверить перед продолжением |
|---|---|---|
| Менять отдельные фигуры | Разобрать SVG в объекты Fabric | Целевая область существует как отдельный объект |
| Перемещать графику как единое целое | Намеренно сгруппировать разобранные объекты | Правка дочерних объектов и выбор работают как задумано |
| Разместить иллюстрацию без редактирования её частей | Загрузить как изображение | Одного выбираемого изображения достаточно |
| Перекрашивать графику, доступную только в PNG или JPG | Сначала подготовить векторную геометрию | Трассированные области соответствуют нужным правкам |
Не выводите структуру объектов из внешнего вида. Два цвета могут принадлежать отдельным контурам, а несколько несвязанных островков — одному. Руководство по разгруппировке SVG объясняет такую диагностику исходного файла.
Запустите небольшой пример импорта, перекрашивания и экспорта
Начните в пустой папке. Установите зависимость фиксированной версии:
npm install --save-exact fabric@7.4.0Сохраните это как index.html:
<!doctype html>
<html lang="en">
<meta charset="utf-8">
<title>Fabric SVG import test</title>
<canvas id="editor" width="320" height="240"></canvas>
<button id="recolor">Recolor shade</button>
<button id="export">Export SVG</button>
<div id="output"></div>
<pre id="report"></pre>
<script type="module" src="main.js"></script>
</html>Сохраните это как main.js. Относительный путь модуля позволяет небольшому примеру работать без сборщика. В приложении со сборкой импортируйте те же имена из fabric.
import { Canvas, loadSVGFromString } from './node_modules/fabric/dist/index.min.mjs';
const svg = `<svg xmlns="http://www.w3.org/2000/svg" width="320" height="240" viewBox="0 0 320 240">
<path id="shade" fill="#e6a23c" d="M115 40 H205 L230 135 H90 Z"/>
<rect id="stem" x="151" y="135" width="18" height="57" fill="#214c54"/>
<path id="base" fill="#214c54" d="M110 192 H210 L220 210 H100 Z"/>
</svg>`;
const canvas = new Canvas('editor', { width: 320, height: 240 });
const parts = new Map();
const parsed = await loadSVGFromString(svg, (element, object) => {
const id = element.getAttribute('id');
if (id) parts.set(id, object);
});
canvas.add(...parsed.objects.filter(Boolean));
canvas.requestRenderAll();
function report(exported) {
const xml = new DOMParser().parseFromString(exported, 'image/svg+xml');
const data = {
version: '7.4.0',
importedObjects: canvas.getObjects().length,
types: canvas.getObjects().map(object => object.type),
shadeFill: parts.get('shade').fill,
exportedPaths: xml.querySelectorAll('path').length,
exportedRects: xml.querySelectorAll('rect').length,
exportedImages: xml.querySelectorAll('image').length,
};
document.querySelector('#report').textContent = JSON.stringify(data, null, 2);
document.querySelector('#output').innerHTML = exported;
}
document.querySelector('#recolor').onclick = () => {
parts.get('shade').set('fill', '#397e86');
canvas.requestRenderAll();
document.querySelector('#report').textContent = 'Shade recolored. Export to check delivery SVG.';
};
document.querySelector('#export').onclick = () => report(canvas.toSVG());
report(canvas.toSVG());Предоставьте папку через HTTP вместо прямого открытия HTML-файла. Например, если установлен Python, запустите python3 -m http.server 8000 и откройте http://localhost:8000. Нажмите Recolor shade, затем Export SVG. Кнопка отображает экспортированную строку под canvas, но не скачивает файл.
Демонстрация вставляет в предпросмотр только экспорт собственного фиксированного образца. Не используйте этот предпросмотр через innerHTML как универсальный обработчик загрузки недоверенного SVG. Пример также опускает обработку ошибок и проверку файлов на уровне приложения.
Map сохраняет исходные ID во время разбора. Перекрашивание обращается к абажуру по явной ссылке вместо предположения, что первый возвращённый объект всегда нужный. В рабочем редакторе решите, как хранить эти идентификаторы и ссылки при сохранении и повторном открытии документа.
Что показал тест
Наш образец импортировался как три объекта: path, rect и path. После смены цвета абажура с #e6a23c на #397e86 экспортированный предпросмотр показал новый цвет, а стойка и основание сохранили исходную тёмную заливку. Экспорт содержал два контура, один прямоугольник и ни одного элемента image.

Эти проверки подтверждают, что пример остаётся векторной геометрией после экспорта. Они не подтверждают сохранения исходного XML, группировки, правил CSS или любой возможности другого файла. Сохраните исходный оригинал и сравните копию для передачи в принимающем приложении.
Не смешивайте уроки с callback и API на promise
Старые примеры часто вызывают fabric.loadSVGFromString(svg, callback) и ожидают, что callback получит весь массив объектов. В текущем API второй аргумент играет другую роль: это reviver для каждого объекта. Дождитесь результата разбора для полной коллекции.
Руководство Fabric по переходу на 6.0 объясняет переход к именованным импортам и API на promise. Проверьте установленную версию пакета перед адаптацией старого фрагмента; замена одного импорта оставит логику загрузки неправильной.
Для SVG-файла с того же источника эквивалентная отправная точка:
import { loadSVGFromURL } from 'fabric';
const parsed = await loadSVGFromURL('/artwork.svg');
canvas.add(...parsed.objects.filter(Boolean));
canvas.requestRenderAll();Документация loadSVGFromURL отмечает, что метод загружает SVG и должен соблюдать политику одного источника. Если удалённый сервер не разрешает ваш источник, изменение кода группировки не исправит сетевую ошибку. Сначала проверьте файл, обслуживаемый собственным приложением, затем изучите неудачный запрос и настройку CORS удалённого сервера.
Проверяйте редактируемость отдельно от внешнего вида
Успешная отрисовка отвечает на один вопрос: появилось ли что-нибудь? Редактору нужны дополнительные проверки.
- Выберите область, которая должна меняться. Убедитесь, что другая часть не меняется вместе с ней.
- Перекрасьте через метод
setобъекта и запросите отрисовку, как делает пример. - Экспортируйте и откройте результат независимо. API
Canvas.toSVGFabric создаёт разметку SVG из состояния canvas. - Проверьте всё, от чего зависит ваша реальная графика: обводки, отсечение, градиенты, текст или вложенные преобразования. Простой образец выше этих возможностей не проверяет.
- Сохраните, откройте заново и повторите нужную правку в собственном редакторе, прежде чем считать процесс завершённым.
Если импорт создаёт объект изображения, проверьте исходник на встроенный растр. Руководство по растровому содержимому внутри SVG показывает, почему оболочка SVG не даёт пикселям редактируемые контуры. Если исходник уже имеет пригодные векторные фигуры, работайте над импортом и организацией объектов вместо новой трассировки.
Когда растр требует предварительного преобразования
Если единственный источник — плоский PNG или JPG, а пользователям нужно редактировать цветные области, процесс преобразования изображения в вектор PerfectVector может помочь подготовить вариант SVG. Сравните результат с оригиналом, проверьте контуры и возможность независимо редактировать нужные области перед импортом в Fabric.js.
Трассировка не определяет роли частей в приложении, например «абажур», «стойка» или «основание». Имена нашего образца заданы намеренно. Добавьте собственное сопоставление частей и правила редактирования после проверки преобразованной геометрии. Для повторно используемого набора иконок процесс UI-кита из PNG в SVG разбирает подготовку исходников и проверки согласованности.
Оставляйте фотографии растровыми, если они должны оставаться фотографиями. Сохраняйте подходящий исходный SVG, если он уже содержит нужные фигуры. Обзор векторизации поможет решить, нужна ли трассировка в процессе вообще.
Частые вопросы
Импортирует ли Fabric.js SVG как редактируемые контуры? Он может разбирать поддерживаемое содержимое SVG в объекты Fabric. Редактируемость зависит от структуры исходника: контур, группа фигур и встроенный растр дают разные возможности. Проверьте возвращённые объекты и конкретную нужную правку.
Почему старый пример loadSVGFromString не работает? Старые уроки могут ожидать callback завершения вторым аргументом. Текущий API возвращает promise и использует этот аргумент как reviver каждого объекта. Согласуйте код с установленной версией и дождитесь результата разбора.
Сохраняет ли toSVG исходный файл в точности? Не ожидайте идентичного исходного документа. Он создаёт SVG из состояния canvas Fabric. Сохраните исходный оригинал и проверьте экспортированный вид и структуры, нужные принимающему процессу.
Может ли импорт PNG сделать его отдельные области редактируемыми? Размещение PNG не трассирует его в отдельные векторные области. Если эти правки необходимы, сначала подготовьте подходящую векторную геометрию, проверьте полученные части и определите их роли в приложении.
Источники
- Fabric.js — loadSVGFromString — Возвращаемый promise и контракт reviver для исходного элемента и объекта.
- Fabric.js — Upgrading to Fabric.js 6.0 — Именованные импорты и переход от callback к promise.
- Fabric.js — loadSVGFromURL — Разбор URL и ограничения загрузки с одного источника.
- Fabric.js — Canvas API — Экспорт состояния canvas в разметку SVG.
Если не хватает редактируемой геометрии растровой графики, подготовьте вариант SVG с PerfectVector. Сначала проверьте фигуры, затем докажите, что редактор Fabric.js перекрашивает нужную часть и правильно экспортирует результат.
Ещё из блога

SVG в WPF: рендерер или рисунок XAML
Используйте графику SVG в WPF через рендерер, штатный DrawingImage или экспорт PNG. Следуйте примеру иконки и проверяйте границы, цвета и зависимости.

Свои SVG-фигуры draw.io: изображения или трафареты?
Выберите встроенное SVG-изображение или XML-трафарет в формате draw.io. Проверьте редактируемые цвета и точки соединения, затем сохраните нужный объект в библиотеке.