PerfectVector
Par Irene Kim9 min de lecture

Import SVG Fabric.js : garder le dessin éditable sur canvas

Importe un SVG dans Fabric.js comme objets éditables, recolore une partie et exporte une copie SVG vérifiée. Suis l’exemple testé et distingue source et bugs d’API.

Sur cette page

Pour importer un SVG éditable dans Fabric.js, attends loadSVGFromString() ou loadSVGFromURL(), puis ajoute les objets renvoyés à un canvas. Garde une référence à la partie à modifier, change son remplissage et exporte avec canvas.toSVG(). Charger le dessin comme image offre un autre modèle d’édition : sélectionner cette image ne donne pas accès à chaque région colorée comme forme distincte.

Cette distinction compte pour un configurateur de produit, un éditeur de badges ou une icône recolorable. Tu as besoin d’objets correspondant aux parties que ton utilisateur peut modifier. Un fichier se terminant par .svg ne garantit pas cette structure.

Ce guide utilise Fabric.js 7.4.0 et une petite lampe écrite à la main. Il teste trois formes à travers l’import, la recoloration et l’export. C’est un exemple de code original, pas une conversion PerfectVector ni une affirmation que toutes les fonctionnalités SVG survivent au même parcours.

Choisir le modèle d’objets avant le chargeur

Fabric.js analyse le SVG pour créer ses propres objets canvas. Tu les modifies via l’API de Fabric ; ce ne sont pas des éléments DOM SVG actifs dans le canvas. La référence actuelle de loadSVGFromString décrit une promesse résolue avec le résultat d’analyse et une fonction reviver qui reçoit chaque élément source et son objet créé.

Ta tâchePoint de départ utileVérification avant de continuer
Modifier des formes distinctesAnalyser le SVG en objets FabricLa région cible existe comme objet propre
Déplacer le dessin comme une unitéGrouper volontairement les objets analysésL’édition des enfants et la sélection fonctionnent comme prévu
Placer une illustration sans modifier ses partiesUtiliser une procédure imageUne seule image sélectionnable suffit
Recolorer un dessin disponible seulement en PNG ou JPGPréparer d’abord la géométrie vectorielleLes régions vectorisées correspondent aux modifications nécessaires

Ne déduis pas la structure des objets de l’apparence. Deux couleurs peuvent appartenir à des tracés distincts, tandis que plusieurs îlots déconnectés peuvent appartenir à un seul tracé. Le guide de dissociation SVG explique ce diagnostic du fichier source.

Exécuter un petit exemple d’import, recoloration et export

Commence dans un dossier vide. Installe la dépendance à version fixée :

npm install --save-exact fabric@7.4.0

Enregistre ceci sous 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>

Enregistre ceci sous main.js. Le chemin relatif du module permet à ce petit exemple de fonctionner sans outil de regroupement. Dans une application compilée, importe les mêmes noms depuis 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());

Sers le dossier en HTTP au lieu d’ouvrir directement le fichier HTML. Par exemple, si Python est installé, lance python3 -m http.server 8000 et ouvre http://localhost:8000. Clique sur Recolor shade, puis sur Export SVG. Le bouton affiche la chaîne exportée sous le canvas ; il ne télécharge pas de fichier.

Cette démonstration insère dans l’aperçu uniquement l’export de son propre exemple fixe. Ne réutilise pas cet aperçu innerHTML comme gestionnaire général de téléversement pour des SVG non fiables. L’exemple omet aussi la gestion des erreurs et la validation des fichiers au niveau de l’application.

La map capture les identifiants source pendant l’analyse. La recoloration cible l’abat-jour par cette référence explicite, au lieu de supposer que le premier objet renvoyé est toujours la partie voulue. Dans un éditeur de production, décide comment ces identifiants et références sont stockés lors de l’enregistrement et de la réouverture d’un document.

Ce qu’a montré le test

Notre exemple a été importé comme trois objets : path, rect et path. Après le changement de l’abat-jour de #e6a23c à #397e86, l’aperçu exporté montrait sa nouvelle couleur tandis que le pied et la base gardaient leur remplissage sombre original. L’export contenait deux tracés, un rectangle et aucun élément image.

Démonstration locale réelle Fabric.js montrant la lampe recolorée sur canvas, l’aperçu SVG exporté correspondant et un rapport de trois objets importés sans image exportée
Capture authentique de l’exemple écrit à la main dans Fabric.js 7.4.0 après recoloration et export. Ces observations concernent les trois formes simples testées ici.

Ces vérifications établissent que cet exemple reste de la géométrie vectorielle après l’export. Elles n’établissent pas la préservation du XML original, des groupes, des règles CSS ou de toutes les fonctionnalités d’un autre fichier. Garde l’original et compare une copie livrable dans l’application qui la recevra.

Éviter de mélanger tutoriels à fonctions de rappel et API à promesses

Les anciens exemples appellent souvent fabric.loadSVGFromString(svg, callback) en attendant que cette fonction de rappel reçoive tout le tableau d’objets. Ce n’est pas le rôle du second argument dans l’API actuelle : c’est un reviver par objet. Attends le résultat d’analyse pour obtenir la collection complète.

Le guide de migration 6.0 de Fabric explique le passage aux imports nommés et aux API à promesses. Vérifie la version du paquet installé avant d’adapter un ancien extrait ; remplacer seulement l’instruction d’import laisse la logique de chargement incorrecte.

Pour un fichier SVG de même origine, le point de départ équivalent est :

import { loadSVGFromURL } from 'fabric';
const parsed = await loadSVGFromURL('/artwork.svg');
canvas.add(...parsed.objects.filter(Boolean));
canvas.requestRenderAll();

La documentation de loadSVGFromURL indique qu’il récupère le SVG et doit respecter la politique de même origine. Si l’hôte distant n’autorise pas ton origine, changer le code de regroupement ne corrigera pas l’échec réseau. Teste d’abord un fichier servi par ton application, puis examine la requête échouée et la configuration CORS du serveur distant.

Vérifier l’éditabilité séparément de l’apparence

Un rendu réussi répond à une question : quelque chose est-il apparu ? Un éditeur nécessite davantage de vérifications.

  1. Sélectionne la région qui doit changer. Confirme qu’une autre partie ne change pas avec elle.
  2. Recolore avec la méthode set de l’objet et demande un rendu, comme dans l’exemple.
  3. Exporte et ouvre le résultat indépendamment. L’API Canvas.toSVG de Fabric génère le balisage SVG depuis l’état du canvas.
  4. Examine tout ce dont dépend ton dessin réel, comme contours, rognage, dégradés, texte ou transformations imbriquées. L’exemple simple ci-dessus ne teste pas ces fonctionnalités.
  5. Enregistre, rouvre et répète la modification prévue dans ton éditeur avant de considérer la procédure comme terminée.

Si l’import produit un objet image, cherche une image matricielle intégrée dans la source. Le guide du contenu matriciel dans les SVG montre pourquoi une enveloppe SVG ne donne pas des tracés éditables aux pixels. Si la source possède déjà des formes vectorielles exploitables, travaille sur l’import et l’organisation des objets plutôt que de la vectoriser à nouveau.

Quand le dessin matriciel nécessite une conversion en amont

Si ta seule source est un PNG ou JPG à aplats et que les utilisateurs doivent modifier ses régions colorées, la procédure image vers vecteur de PerfectVector peut aider à préparer un SVG candidat. Compare le résultat à l’original, examine les tracés et vérifie si les régions nécessaires sont éditables indépendamment avant l’import dans Fabric.js.

La vectorisation n’attribue pas de sens propre à l’application comme abat-jour, pied ou base. Les noms de notre exemple ont été écrits volontairement. Ajoute ta propre correspondance de parties et tes règles d’édition après avoir examiné la géométrie convertie. Pour un jeu d’icônes réutilisable, la procédure de kit d’interface PNG vers SVG traite de la préparation des sources et des vérifications de cohérence.

Garde les photographies en matriciel lorsqu’elles doivent rester des photographies. Garde un SVG original adapté lorsqu’il contient déjà les formes nécessaires. La présentation de la vectorisation peut aider à décider si cette étape appartient même à la procédure.

FAQ

Fabric.js importe-t-il les SVG comme tracés éditables ? Il peut analyser le contenu SVG pris en charge en objets Fabric. L’éditabilité dépend de la structure source : un tracé, un groupe de formes et une image matricielle intégrée n’offrent pas les mêmes options. Examine les objets renvoyés et teste la modification précise nécessaire.

Pourquoi un ancien exemple loadSVGFromString échoue-t-il ? Les anciens tutoriels peuvent attendre une fonction de rappel de fin comme second argument. L’API actuelle renvoie une promesse et utilise cet argument comme reviver par objet. Adapte ton code à la version installée et attends le résultat d’analyse.

toSVG préserve-t-il exactement le fichier original ? N’attends pas un document source identique. Il génère le SVG depuis l’état du canvas Fabric. Préserve l’original et vérifie l’apparence exportée et les structures nécessaires à ta procédure destinataire.

Importer un PNG rend-il ses régions individuelles éditables ? Placer un PNG ne le vectorise pas en régions distinctes. Si ces modifications sont nécessaires, prépare d’abord une géométrie vectorielle adaptée, examine les parties obtenues et définis leurs rôles dans ton application.

Sources

  1. Fabric.js — loadSVGFromString — Promesse renvoyée et contrat du reviver entre élément source et objet.
  2. Fabric.js — Passer à Fabric.js 6.0 — Imports nommés et migration des fonctions de rappel vers les promesses.
  3. Fabric.js — loadSVGFromURL — Analyse depuis une URL et contraintes de récupération de même origine.
  4. Fabric.js — API Canvas — Export de l’état du canvas en balisage SVG.

Si la pièce manquante est une géométrie éditable depuis un dessin matriciel, prépare un SVG candidat avec PerfectVector. Vérifie d’abord les formes, puis démontre que ton éditeur Fabric.js peut recolorer la partie prévue et exporter correctement le résultat.

Plus depuis le blog

Repartez d’un SVG plus net
et plus facile à modifier