PerfectVector
Par Irene Kim

SVG.js : importer un dessin, modifier un chemin, exporter

Importe un balisage SVG fiable dans SVG.js, recolore un chemin nommé et compare les exports de racine complète ou d’enfants seuls. Garde la géométrie et examine les fichiers enregistrés.

10 min de lecture
Sur cette page

Pour importer un dessin dans SVG.js et en modifier une partie, fournis un balisage SVG fiable à .svg(), trouve l’élément voulu par son ID d’origine et change son fond. Exporte la racine SVG complète du dessin pour obtenir un fichier autonome. Un export des enfants seuls est un fragment : il nécessite une racine avec les dimensions et le viewBox voulus avant d’être livré comme document.

Ce guide utilise un losange creux original et un triangle distinct. Le triangle passe de l’ocre au corail tandis que le losange garde son fond bleu-vert et son ouverture. Nous avons testé l’exemple complet ci-dessous avec SVG.js 3.2.6, fixé à la version officielle 3.2.6. Ces observations concernent deux chemins simples créés par nos soins, pas toutes les fonctions qu’un autre SVG pourrait contenir.

Décide si tu as besoin de formes actives ou d’une image

Une instruction d’import JavaScript qui produit une URL de ressource répond à une question de chargement. Elle ne place pas, à elle seule, les chemins du fichier dans l’arbre SVG actif de ton éditeur. La documentation actuelle d’import/export de SVG.js décrit l’importation de balisage et la récupération d’un élément SVG extérieur ou de ses enfants.

ReprésentationCe que notre exemple permet de ciblerVérification de livraison
Balisage fiable importé dans une racine SVG activeLe chemin nommé accentExaminer la racine modifiée et rouvrir son export
SVG chargé par un élément imageL’élément image entierExaminer les données de l’image séparément
Balisage des enfants seulsDeux éléments chemin sans la racine d’origineFournir une racine, des dimensions et un viewBox choisis volontairement

Un SVG dans une image reste du contenu SVG. Dans notre contrôle d’enveloppe d’image, cependant, l’arbre SVG contenant possède un élément image et aucun chemin direct ; y chercher accent ne trouve rien. Cela n’entre pas dans le document de l’image intégrée. MDN décrit le contexte d’image SVG distinct et ses restrictions. Ne déduis pas le modèle de modification d’un rendu d’apparence nette.

Pour le choix plus général d’intégration, lis SVG en ligne contre image. Si tu préfères le modèle d’objets canvas de Fabric, le tutoriel d’importation Fabric.js traite d’un autre analyseur et d’une autre API de modification.

Modifie un chemin nommé et enregistre chaque représentation

Enregistre le code complet ci-dessous sous starter.html dans un dossier vide. Sers-le en HTTP, par exemple avec python3 -m http.server 8000, puis ouvre http://localhost:8000/starter.html. Le script charge le paquet de version fixe depuis son CDN : cette base nécessite donc une connexion réseau.

La page affiche le dessin original, la copie active modifiée et un contrôle d’enveloppe d’image. Ses liens téléchargent le maître original, les racines complètes avant/après, le fragment de texte des enfants seuls, une copie réenveloppée et l’enveloppe d’image. Le rapport lit des pixels d’images SVG peintes dans un canevas ; il n’exporte pas de PNG.

<!doctype html>
<html lang="en">
<meta charset="utf-8">
<title>Original SVG.js artwork import and export</title>
<style>
  body { margin: 24px; font: 16px system-ui; background: #f6f2e8; }
  main { display: grid; grid-template-columns: repeat(3, 260px); gap: 20px; }
  figure { margin: 0; }
  svg, img { display: block; background: white; border: 1px solid #bbb; }
  pre { white-space: pre-wrap; font-size: 12px; }
</style>
<h1>Trusted artwork, one fill edit and two export forms</h1>
<main>
  <figure><img id="original" alt="Original artwork"><figcaption>Original SVG image</figcaption></figure>
  <figure><div id="live"></div><figcaption>Imported live SVG, accent edited</figcaption></figure>
  <figure><div id="wrapper"></div><figcaption>Image wrapper, original artwork</figcaption></figure>
</main>
<p id="downloads"></p>
<pre id="report"></pre>
<script src="https://cdn.jsdelivr.net/npm/@svgdotjs/svg.js@3.2.6/dist/svg.min.js"></script>
<script>
  const markup = '<svg xmlns="http://www.w3.org/2000/svg" id="original-artwork" width="240" height="160" viewBox="0 0 240 160">'
    + '<path id="body" d="M80 20 L140 80 L80 140 L20 80 Z M80 56 L104 80 L80 104 L56 80 Z" fill="#176b5b" fill-rule="evenodd"/>'
    + '<path id="accent" d="M172 48 L220 80 L172 112 Z" fill="#d4a53a"/></svg>';
  const url = text => 'data:image/svg+xml;charset=utf-8,' + encodeURIComponent(text);
  async function pixels(text) {
    const image = new Image();
    image.src = url(text);
    await image.decode();
    const canvas = document.createElement('canvas');
    canvas.width = 240;
    canvas.height = 160;
    const ctx = canvas.getContext('2d');
    ctx.drawImage(image, 0, 0);
    const rgba = (x, y) => [...ctx.getImageData(x, y, 1, 1).data];
    return { naturalWidth: image.naturalWidth, naturalHeight: image.naturalHeight,
      opening: rgba(80, 80), body: rgba(80, 40), accent: rgba(188, 80), corner: rgba(0, 0) };
  }
  function inventory(text) {
    const node = new DOMParser().parseFromString(text, 'image/svg+xml').documentElement;
    return { root: node.localName, viewBox: node.getAttribute('viewBox'),
      paths: [...node.querySelectorAll('path')].map(p => ({ id: p.id, d: p.getAttribute('d'), fill: p.getAttribute('fill') })),
      imageCount: node.querySelectorAll('image').length };
  }
  async function run() {
    document.getElementById('original').src = url(markup);
    const host = SVG().addTo('#live').size(240, 160).viewbox(0, 0, 240, 160);
    host.svg(markup);
    const artwork = host.findOne('#original-artwork');
    const before = artwork.svg();
    const accent = artwork.findOne('#accent');
    const beforeD = accent.attr('d');
    accent.fill('#b95434');
    const full = artwork.svg();
    const children = artwork.svg(false);
    const rewrapped = SVG().size(240, 160).viewbox(0, 0, 240, 160);
    rewrapped.svg(children);
    const wrappedFull = rewrapped.svg();
    const imageWrapper = SVG().addTo('#wrapper').size(240, 160).viewbox(0, 0, 240, 160);
    imageWrapper.image(url(markup)).size(240, 160);
    const wrapperFull = imageWrapper.svg();
    const files = { 'master.svg': markup, 'before.svg': before, 'edited.svg': full,
      'children-only.txt': children, 'rewrapped.svg': wrappedFull, 'image-wrapper.svg': wrapperFull };
    for (const [name, text] of Object.entries(files)) {
      const a = document.createElement('a');
      a.href = name.endsWith('.txt') ? 'data:text/plain;charset=utf-8,' + encodeURIComponent(text) : url(text);
      a.download = name;
      a.textContent = name;
      a.style.marginRight = '12px';
      document.getElementById('downloads').append(a);
    }
    const results = {};
    for (const [name, text] of Object.entries(files)) {
      if (name.endsWith('.svg')) results[name] = { inventory: inventory(text), pixels: await pixels(text) };
    }
    document.getElementById('report').textContent = JSON.stringify({
      requestedPackageVersion: '3.2.6',
      scriptURL: document.querySelector('script[src]').src,
      selectedAccentFound: Boolean(accent), selectedAccentDUnchanged: beforeD === accent.attr('d'),
      allPathDUnchanged: JSON.stringify(inventory(before).paths.map(p => p.d)) === JSON.stringify(inventory(full).paths.map(p => p.d)),
      childrenHasOuterSVG: /<svg[\s>]/i.test(children),
      wrapperDirectPathCount: imageWrapper.find('path').length,
      wrapperAccentFound: Boolean(imageWrapper.findOne('#accent')), results
    }, null, 2);
  }
  run();
</script>
</html>
 

Le balisage importé contient une racine imbriquée nommée original-artwork. L’exemple sélectionne cette racine avant d’exporter : la copie de livraison a donc son viewport d’origine de 240 × 160 au lieu de dépendre d’un conteneur parent sans rapport. Il sélectionne ensuite accent dans cette racine. SVG.js documente les références par sélecteurs et méthodes d’éléments ; des noms de parties explicites évitent de dépendre de l’ordre des chemins.

Le code est volontairement limité à son propre balisage fixe. Ce n’est pas un outil d’assainissement des fichiers SVG téléversés. Analyser ou insérer une chaîne quelconque ne prouve pas qu’elle est sûre ; la référence de DOMParser de MDN distingue l’analyse des risques d’insertion de contenu non fiable. Conçois une politique de validation et de confiance distincte avant d’adapter cette routine aux téléversements.

Examine le résultat enregistré, pas seulement l’aperçu actif

Notre exécution réelle dans le navigateur a produit ces vérifications :

Représentation enregistréeChemins dans son arbre de documentImagesFond du triangle
Maître original20#d4a53a
Racine complète avant modification20#d4a53a
Racine complète après modification20#b95434
Enfants placés dans une nouvelle racine complète20#b95434
Enveloppe d’image01Ocre original dans ses données d’image

Les deux chaînes d des chemins originaux restaient identiques dans les exports avant/après. L’échantillon intérieur du triangle passait de RGBA (212, 165, 58, 255) à (185, 84, 52, 255). L’intérieur du losange échantillonné restait (23, 107, 91, 255) ; son ouverture et le coin extérieur gardaient un alpha de 0. Les cinq fichiers SVG autonomes se rouvraient comme images aux dimensions naturelles de 240 × 160.

Changer une partie nommée
Comparaison conceptuelle de dessins identiques de losange creux où seul un triangle distinct passe du doré au corail
Illustration conceptuelle d’une modification de couleur sur une partie. Les limites décoratives et les flèches sont des repères de schéma ; la base exécutée, l’inventaire source enregistré et les contrôles de pixels du navigateur fournissent les preuves réelles.

Ces résultats établissent la modification voulue pour ce fichier de test. Ils n’établissent ni une préservation XML identique octet pour octet, ni la prise en charge de tous les filtres ou du CSS, ni l’adéquation à un processus de fabrication. La sérialisation de la bibliothèque peut changer le balisage du document tout en gardant ces chaînes de chemin particulières intactes. Garde le maître original à côté de la copie livrée.

Pour ton dessin, vérifie les structures réellement utilisées : noms et groupes, découpes, dégradés, transformations, contours et texte. Rouvre le fichier exporté dans son application destinataire, puis répète la modification prévue. Le guide de modification SVG peut aider à diagnostiquer la structure source avant de changer le code d’importation.

Traite un export des enfants seuls comme un fragment volontaire

Dans cette exécution, artwork.svg(false) renvoyait deux chemins sans balise svg extérieure. Il omettait le viewport de la racine du dessin. La racine SVG distincte rewrapped fournit les dimensions 240 × 160 et le même viewBox avant d’accepter ces enfants ; son fichier exporté rend ensuite le triangle corail vérifié.

Choisis entre un document complet et un fragment selon la destination. Pour un téléchargement autonome, garde toute la racine voulue. Pour une insertion dans un dessin existant, décide du système de coordonnées parent, des styles hérités et des définitions que ces enfants utiliseront. Ce test simple n’a ni ressources externes ni définitions partagées : il ne vérifie donc pas qu’un fragment contenant des références emporte toutes les dépendances nécessaires.

Notre export d’enveloppe d’image gardait un SVG encodé dont les octets décodés correspondaient au maître original. Ce contrôle montre une différence de représentation, pas une conversion matricielle. Si ta source est déjà une géométrie vectorielle utilisable, corrige la sélection d’élément ou la limite d’exportation avant de la vectoriser à nouveau.

Quand la source n’a pas de chemins à modifier

Si ton illustration plate PNG ou JPG nécessite des régions recolorables séparément, prépare un SVG candidat avec PerfectVector. Examine les contours et les ouvertures, puis crée les noms de parties nécessaires à ton application. La vectorisation ne sait pas qu’une région doit s’appeler accent et ne garantit pas qu’un document importé convient au modèle de données de ton éditeur.

Garde un maître SVG adapté lorsque ces formes existent déjà. Utilise l’aperçu de la vectorisation pour décider si une préparation matricielle vers vectorielle a sa place en amont de ton code.

Questions fréquentes

SVG.js peut-il importer une chaîne SVG pour la modifier ? Oui. Cette base importe son propre balisage fiable dans un conteneur SVG actif, sélectionne un chemin créé et change son fond. Des téléversements quelconques nécessitent une politique distincte de confiance et de validation ; l’API de balisage n’est pas un outil d’assainissement.

Pourquoi puis-je voir le dessin sans trouver son chemin accent ? Vérifie si tu as importé du balisage actif ou placé une image. Notre contrôle d’enveloppe d’image affiche le dessin SVG mais n’expose aucun chemin accent direct dans l’arbre de l’enveloppe. Vérifie aussi le parent sélectionné et les ID réels de la source.

Un export des enfants seuls est-il un fichier SVG complet ? Pas dans ce test. Il contient deux chemins sans le viewport SVG extérieur. Utilise la racine complète voulue pour un fichier autonome, ou fournis explicitement la racine et le système de coordonnées de destination lors de l’insertion d’un fragment.

Une modification réussie prouve-t-elle que l’export préserve toutes les fonctions SVG ? Non. Nous avons vérifié deux chemins simples, leurs fonds, leurs données exactes et cinq fichiers rouverts. Teste les fonctions spécifiques et l’application destinataire dont ton dessin a besoin, et garde le maître original.

Sources

  1. SVG.js — Importation/exportation, version 3.2 — Importation de balisage et sérialisation de racine complète ou d’enfants seuls.
  2. SVG.js — Référencer/créer des éléments, version 3.2 — Recherche d’éléments nommés et modification de leurs propriétés.
  3. SVG.js — Version 3.2.6 — Version officielle fixée par la base exécutée.
  4. MDN — SVG comme image — Contexte d’intégration d’image et ses restrictions.
  5. MDN — DOMParser.parseFromString — Analyse du balisage et traitement distinct des entrées non fiables.

Si ton illustration n’existe qu’en pixels matriciels et nécessite des modifications par partie, prépare un candidat vectoriel depuis ton dessin. Vérifie le contour et les ouvertures, garde le maître, puis valide la modification nommée et le SVG enregistré dans ton processus destinataire.

Plus depuis le blog

PerfectVector

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

Sans carte bancaire