Recherche…


Remarques

Le script SVG utilisant les interfaces natives du DOM est actuellement (2016) en léger changement. La norme SVG actuelle (1.1) est bien implémentée par la plupart des principaux navigateurs Web. Cependant, comme la norme SVG 2.0 est en cours de développement, certains navigateurs ont commencé à supprimer les fonctionnalités SVG 1.1 qui seront obsolètes en 2.0. Vous pouvez voir une liste complète des modifications proposées de SVG 1.1 à SVG 2.0 dans l' annexe L de SVG 2.0 .

Remplacement de pathSegList et d'autres utilisations de SVGPathSeg

Dans SVG 1.1 <path> éléments <path> sont définis pour avoir une propriété pathSegList qui donne accès à une représentation native de toutes les commandes de chemin . Google Chrome v48 a supprimé cette propriété à la fin de 2015, en prévision d'un remplacement proposé dans SVG 2.0 . Jusqu'à ce que le support de SVG 2.0 soit ajouté, vous devez utiliser un polyfill pour récupérer la fonctionnalité 1.1 ou implémenter l'API 2.0 proposée .

Remplacement de getTransformToElement()

Chrome v48 a également supprimé la méthode SVGGraphicsElement.getTransformToElement() . Un polyfill simple existe pour implémenter l'ancienne méthode .

Créer un élément

La manière la plus simple de comprendre la création et la modification d'éléments SVG consiste à opérer sur les éléments en utilisant les interfaces DOM Level 2 Core , comme vous le feriez avec HTML ou XML.

Il est impératif que les éléments créés à partir de JavaScript soient créés dans le même espace de noms déclaré dans l'élément SVG - dans cet exemple: " http://www.w3.org/2000/svg ". Cependant, presque tous les attributs des éléments SVG ne se trouvent dans aucun espace de noms. Vous ne devez pas les placer dans l'espace de noms SVG.

Ici, nous démontrons SVG hébergé à l'intérieur de HTML, car c'est un cas courant:

<!doctype HTML>
<html><title>Creating an Element</title>
<body>
  <svg xmlns="http://www.w3.org/2000/svg"
       width="100%" height="100%"
       viewBox="0 0 400 300"></svg>

  <script>
     var svgNS = "http://www.w3.org/2000/svg";

     // Create a circle element (not part of the DOM yet)
     var circle = document.createElementNS(svgNS,'circle'); // Creates a <circle/>
     circle.setAttribute('fill','red'); // Note: NOT setAttributeNS()
     circle.setAttribute('cx',150);     // setAttribute turns 150 into a string
     circle.setAttribute('cy','80');    // using a string works, too
     circle.setAttribute('r',35);       // give the circle a radius so we can see it

     // Now, add the circle to the SVG document so we can see it
     var svg = document.querySelector('svg'); // the root <svg> element
     svg.appendChild(circle);
  </script>
</body></html>

Il y a quelques attributs à créer dans un espace de noms particulier. Ce sont ceux listés avec des deux-points dans leurs noms dans l' index des attributs SVG . Plus précisément, ils sont: xlink:actuate : xlink:actuate , xlink:arcrole , xlink:href , xlink:role , xlink:show , xlink:title , xlink:type , xml:base , xml:lang et xml:space . Définissez ces attributs à l'aide de setAttributeNS() :

var svgNS   = "http://www.w3.org/2000/svg";
var xlinkNS = "http://www.w3.org/1999/xlink";
var img = document.createElementNS( svgNS, 'image' );
img.setAttributeNS( xlinkNS, 'href', 'my.png' );

Si vous créez souvent des éléments, en particulier avec de nombreux attributs, une fonction d'assistance comme celle-ci peut vous éviter de taper, éviter les erreurs et rendre votre code plus facile à lire:

<!doctype HTML>
<html><title>Creating an Element</title>
<body>
  <svg xmlns="http://www.w3.org/2000/svg"></svg>
  <script>
     var svg = document.querySelector('svg');
     var circle = createOn( svg, 'circle', {fill:'red', cx:150, cy:80, r:35} );

    // Create an SVG element on another node with a set of attributes.
    // Attributes with colons in the name (e.g. 'xlink:href') will automatically
    // find the appropriate namespace URI from the SVG element.
    // Optionally specify text to create as a child node, for example
    //   createOn(someGroup,'text',{x:100,'text-anchor':'middle'},"Hello World!");
    function createOn(parentEl,name,attrs,text){
      var doc=parentEl.ownerDocument, svg=parentEl;
      while (svg && svg.tagName!='svg') svg=svg.parentNode;
      var el = doc.createElementNS(svg.namespaceURI,name);
      for (var a in attrs){
        if (!attrs.hasOwnProperty(a)) continue;
        var p = a.split(':');
        if (p[1]) el.setAttributeNS(svg.getAttribute('xmlns:'+p[0]),p[1],attrs[a]);
        else      el.setAttribute(a,attrs[a]);
      }
      if (text) el.appendChild(doc.createTextNode(text));
      return parentEl.appendChild(el);
    }
  </script>
</body></html>

Lecture / écriture des attributs

Vous pouvez utiliser les méthodes DOM Niveau 2 Core getAttribute() , getAttributeNS() , setAttribute() et setAttributeNS() pour lire et écrire des valeurs à partir d'éléments SVG ou utiliser les propriétés et méthodes personnalisées spécifiées dans l' IDL SVG 1.1 (Interface). Langage de définition).

Attributs numériques simples

Par exemple, si vous avez un élément de cercle SVG:

<circle id="circ" cx="10" cy="20" r="15" />

vous pouvez utiliser les méthodes DOM pour lire et écrire les attributs:

var circ = document.querySelector('#circ');
var x = circ.getAttribute('cx') * 1; // Use *1 to convert from string to number value
circ.setAttribute('cy', 25);

... ou vous pouvez utiliser les propriétés cx , cy et r définies pour SVGCircleElement . Notez que ce ne sont pas des nombres directs, mais, comme avec de nombreux accesseurs dans SVG 1.1, ils permettent d'accéder à des valeurs animées. Ces propriétés sont de type SVGAnimatedLength . Sans tenir compte des unités d'animation et de longueur, vous pouvez utiliser des attributs tels que:

var x = circ.cx.baseVal.value; // this is a number, not a string
circ.cy.baseVal.value = 25;

Transformations

Les groupes SVG peuvent être utilisés pour déplacer, faire pivoter, mettre à l'échelle et transformer plusieurs éléments graphiques dans leur ensemble. (Pour plus de détails sur les traductions SVG, voir le chapitre 7 ). Voici un groupe qui fait un smiley que vous pouvez ajuster la taille, la rotation et le placement en ajustant la transform :

<g id="smiley" transform="translate(120,120) scale(5) rotate(30)">
  <circle r="20" fill="yellow" stroke-width="2"/>
  <path fill="none" d="M-10,5 a 5 3 0 0 0 20,0" stroke-width="2"/>
  <circle cx="-6" cy="-5" r="2" fill="#000"/>
  <circle cx="6"  cy="-5" r="2" fill="#000"/>
</g>

L'utilisation d'un script pour ajuster cette échelle via les méthodes DOM nécessite de manipuler l'intégralité de l'attribut transform sous forme de chaîne:

var face = document.querySelector('#smiley');

// Find the full string value of the attribute
var xform = face.getAttribute('transform');

// Use a Regular Expression to replace the existing scale with 'scale(3)'
xform = xform.replace( /scale\s*\([^)]+\)/, 'scale(3)' );

// Set the attribute to the new string.
face.setAttribute('transform',xform);

Avec le DOM SVG, on peut parcourir les transformations spécifiques de la liste, trouver celle qui est souhaitée et modifier les valeurs:

var face = document.querySelector('#smiley');

// Get the SVGTransformList, ignoring animation
var xforms = face.transform.baseVal;          

// Find the scale transform (pretending we don't know its index)
for (var i=0; i<xforms.numberOfItems; ++i){
  // Get this part as an SVGTransform
  var xform = xforms.getItem(i);
  if (xform.type == SVGTransform.SVG_TRANSFORM_SCALE){
    // Set the scale; both X and Y scales are required
    xform.setScale(3,3);
    break;
  }
}
  • Pour parcourir et manipuler le nombre de transformations, voir SVGTransformList .
  • Pour manipuler des transformations individuelles, voir SVGTransform .

Faire glisser des éléments SVG

L'utilisation de la souris pour faire glisser un élément SVG (ou un groupe d'éléments) peut être réalisée par:

  1. Ajout mousedown gestionnaire mousedown pour mousedown le glissement: ajout d'une traduction sur l'élément à utiliser pendant le glissement (si nécessaire), suivi des événements mousemove et ajout d'un gestionnaire de mouseup pour mettre fin au glissement.
  2. Au cours de mousemove , transformer la position de la souris des coordonnées d'écran en coordonnées locales pour l'objet que vous faites glisser et mettre à jour la traduction en conséquence.
  3. Au cours de la mise au mouseup , en retirant les mousemove et de mouseup .
// Makes an element in an SVG document draggable.
// Fires custom `dragstart`, `drag`, and `dragend` events on the
// element with the `detail` property of the event carrying XY
// coordinates for the location of the element.
function makeDraggable(el){
  if (!el) return console.error('makeDraggable() needs an element');
  var svg = el;
  while (svg && svg.tagName!='svg') svg=svg.parentNode;
  if (!svg) return console.error(el,'must be inside an SVG wrapper');
  var pt=svg.createSVGPoint(), doc=svg.ownerDocument;

  var root = doc.rootElement || doc.body || svg;
  var xlate, txStartX, txStartY, mouseStart;
  var xforms = el.transform.baseVal;

  el.addEventListener('mousedown',startMove,false);

  function startMove(evt){
    // We listen for mousemove/up on the root-most
    // element in case the mouse is not over el.
    root.addEventListener('mousemove',handleMove,false);
    root.addEventListener('mouseup',  finishMove,false);

    // Ensure that the first transform is a translate()
    xlate = xforms.numberOfItems>0 && xforms.getItem(0);
    if (!xlate || xlate.type != SVGTransform.SVG_TRANSFORM_TRANSLATE){
      xlate = xforms.createSVGTransformFromMatrix( svg.createSVGMatrix() );
      xforms.insertItemBefore( xlate, 0 );
    }
    txStartX=xlate.matrix.e;
    txStartY=xlate.matrix.f;
    mouseStart = inElementSpace(evt);
    fireEvent('dragstart');
  }

  function handleMove(evt){
    var point = inElementSpace(evt);
    xlate.setTranslate(
      txStartX + point.x - mouseStart.x,
      txStartY + point.y - mouseStart.y
    );
    fireEvent('drag');
  }

  function finishMove(evt){
    root.removeEventListener('mousemove',handleMove,false);
    root.removeEventListener('mouseup',  finishMove,false);
    fireEvent('dragend');
  }

  function fireEvent(eventName){
    var event = new Event(eventName);
    event.detail = { x:xlate.matrix.e, y:xlate.matrix.f };
    return el.dispatchEvent(event);
  }

  // Convert mouse position from screen space to coordinates of el
  function inElementSpace(evt){
    pt.x=evt.clientX; pt.y=evt.clientY;
    return pt.matrixTransform(el.parentNode.getScreenCTM().inverse());
  }
}


Modified text is an extract of the original Stack Overflow Documentation
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow