web-dev-qa-db-fra.com

Scriptage des données <path> en SVG (lecture et modification)

Quelqu'un peut-il vraiment m'aider, s'il vous plaît? J'ai cherché des moyens d'exécuter des scripts pour mon SVG. Mais tout ce que j'ai obtenu ne correspond pas! Et il ne contient pas suffisamment d'informations pour lesquelles il a utilisé cet ensemble de codes. Par exemple, l'un a utilisé event.target, un autre a event.getTarget () et un autre a event.target.firstchild.data. Quelqu'un peut-il m'aider s'il-vous-plaît?

<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
  <path d="M150 0 L75 200 L225 200 Z" />
</svg>

est un exemple d'un chemin svg à droite? Ce dont j'ai besoin, c'est d'obtenir ces coordonnées, probablement de les mettre dans une variable et de les utiliser comme coordonnées pour un autre svg. Alors, comment puis-je faire ça? Une autre chose est de savoir comment puis-je changer ces coordonnées en entrant des nombres dans une interface.

J'ai donc essayé de chercher des réponses, mais comme je l'ai dit, je n'ai pas trouvé les informations dont j'avais besoin ou peut-être que je n'ai tout simplement pas compris ce qu'elles m'ont montré.

27
Lei Leyba

Il semble que vous ayez quatre questions:

  1. Comment intégrer un script dans un fichier SVG?
  2. Comment exécuter un script dans un fichier SVG?
  3. Comment accéder aux données d'un élément <path> À partir d'un script?
  4. Comment puis-je manipuler les données d'un élément <path> À partir du script?

Abordons-les un à la fois:


Comment intégrer un script dans un fichier SVG?

Comme décrit dans la spécification SVG vous pouvez placer un élément <script> Dans votre document pour contenir du code JavaScript. Selon les dernières spécifications SVG, vous n'avez pas besoin de spécifier un attribut type pour votre script. Il sera par défaut à type="application/ecmascript".

  • Les autres types de mimes courants incluent "text/javascript", "text/ecmascript" (Spécifié dans SVG 1.1), "application/javascript" Et "application/x-javascript". Je n'ai pas d'informations détaillées sur la prise en charge du navigateur pour tous ces éléments, ni sur l'omission totale de l'attribut type. J'ai toujours eu un bon succès avec text/javascript.

Comme avec HTML, vous pouvez soit mettre le code de script directement dans le document, soit référencer un fichier externe. Lorsque vous effectuez cette dernière, vous devez utiliser un attribut href (pas src) pour l'URI, avec l'attribut dans l'espace de noms xlink.

<svg version="1.1" baseProfile="full" xmlns="http://www.w3.org/2000/svg"
     xmlns:xlink="http://www.w3.org/1999/xlink">
  <script xlink:href="/js/mycode.js" />
  <script><![CDATA[
    // Wrap the script in CDATA since SVG is XML and you want to be able to write
    // for (var i=0; i<10; ++i )
    // instead of having to write
    // for (var i=0; i&lt;10; ++i )
  ]]></script>
</svg>

Comment exécuter un script dans un fichier SVG?

Comme avec HTML, le code inclus dans votre document SVG sera exécuté dès qu'il sera rencontré. Si vous placez votre élément <script> Au-dessus du reste de votre document (comme vous pourriez le faire lorsque vous placez <script> Dans le <head> D'un document HTML), aucun de vos éléments de document ne sera disponible lorsque votre code est en cours d'exécution.

Le moyen le plus simple d'éviter cela est de placer vos éléments <script> Au bas de votre document:

<svg version="1.1" baseProfile="full" xmlns="http://www.w3.org/2000/svg"
     xmlns:xlink="http://www.w3.org/1999/xlink">
  <!-- all SVG content here, above the script -->
  <script><![CDATA[
    // Now I can access the full DOM of my document
  ]]></script>
</svg>

Alternativement, vous pouvez créer une fonction de rappel en haut de votre document qui n'est invoquée que lorsque le reste du document est prêt:

<svg version="1.1" baseProfile="full" xmlns="http://www.w3.org/2000/svg">
  <title>SVG Coordinates for Embedded XHTML Elements</title>
  <script>document.documentElement.addEventListener('load',function(){
    // This code runs once the 'onload' event fires on the root SVG element
    console.log( document.getElementById('foo') );
  },false)</script>
  <path id="foo" d="M0 0" />
</svg>

Comment accéder aux données d'un élément <path> À partir d'un script?

Il existe deux façons d'accéder à la plupart des informations sur les éléments dans SVG: vous pouvez soit accéder à l'attribut sous forme de chaîne via la méthode standard DOM niveau 1 getAttribute() , soit utiliser le objets et méthodes DOM SVG . Regardons les deux:

Accès aux données de chemin via getAttribute()

L'utilisation de getAttribute() renvoie la même chaîne que celle que vous verriez lorsque vous affichez la source:

<path id="foo" d="M150 0 L75 200 L225 200 Z" />
<script><![CDATA[
  var path = document.getElementById('foo');
  var data = path.getAttribute('d');
  console.log(data);
  //-> "M150 0 L75 200 L225 200 Z"
]]></script>
  • Avantages: très simple à appeler; vous n'avez rien à savoir sur le DOM SVG
  • Inconvénient: puisque vous récupérez une chaîne, vous devez analyser l'attribut vous-même; pour les données SVG <path>, cela peut être atroce.

Accès aux données de chemin via les méthodes DOM SVG

<path id="foo" d="M150 0 L75 200 L225 200 Z" />
<script><![CDATA[
  var path = document.getElementById('foo');

  // http://www.w3.org/TR/SVG/paths.html#__svg__SVGAnimatedPathData__normalizedPathSegList
  // See also path.pathSegList and path.animatedPathSegList and path.animatedNormalizedPathSegList
  var segments = path.normalizedPathSegList ;

  for (var i=0,len=segments.numberOfItems;i<len;++i){
    var pathSeg = segments.getItem(i);
    // http://www.w3.org/TR/SVG/paths.html#InterfaceSVGPathSeg
    switch(pathSeg.pathSegType){
      case SVGPathSeg.PATHSEG_MOVETO_ABS:
        // http://www.w3.org/TR/SVG/paths.html#InterfaceSVGPathSegMovetoAbs
        console.log("Move to",pathSeg.x,pathSeg.y);
      break;
      case SVGPathSeg.PATHSEG_LINETO_ABS:
        // http://www.w3.org/TR/SVG/paths.html#InterfaceSVGPathSegLinetoAbs
        console.log("Line to",pathSeg.x,pathSeg.y);
      break;
      case SVGPathSeg.PATHSEG_CLOSEPATH:
        // http://www.w3.org/TR/SVG/paths.html#InterfaceSVGPathSegClosePath
        console.log("Close Path");
      break;
    }
  }
]]></script>

Le script ci-dessus produit la sortie suivante:

Move to 150 0
Line to 75 200
Line to 225 200
Close Path
  • Avantages: les données de chemin sont analysées pour vous; vous obtenez des nombres exacts de l'API elle-même; utiliser normalizedPathSegList prend des commandes relatives et les rend absolues pour vous; si l'animation SMIL modifie les données de chemin, l'utilisation de pathSegList non animé peut vous donner accès à la base, des informations non animées non disponibles via getAttribute().

  • Inconvénients: Sweet chimpunks a-flame, regardez ce code! Et cela ne gère même pas tous les segments de chemin possibles disponibles.

Parce qu'il peut être difficile de lire les spécifications du W3C pour SVG DOM, il y a de nombreuses années, j'ai créé un outil en ligne pour parcourir les propriétés et les objets existants. Vous pouvez l'utiliser ici: http://objjob.phrogz.net/svg/hierarchy


Comment puis-je manipuler les données d'un élément <path> À partir du script

Semblable à ce qui précède, vous pouvez soit créer une nouvelle chaîne et utiliser setAttribute() pour la placer sur l'objet, soit manipuler le DOM SVG.

Manipulation des données de chemin à l'aide de setAttribute()

<path id="foo" d="M150 0 L75 200 L225 200 Z" />
<script><![CDATA[
  var path = document.getElementById('foo');
  path.setAttribute('d','M150,0 L150,100 200,300 Z');
]]></script>

Manipulation des données de chemin à l'aide de DOM SVG

<path id="foo" d="M150,0 L75,200 l150,0 Z" />
<script><![CDATA[
  var path = document.getElementById('foo');
  var segments = path.pathSegList;
  segments.getItem(2).y = -10;
]]></script>

En général, il suffit de modifier les propriétés des différentes instances de la sous-classe SVGPathSeg; les modifications sont effectuées immédiatement dans le DOM. (Avec l'exemple ci-dessus, le triangle d'origine est de travers lorsque le dernier point est légèrement remonté.)

Lorsque vous devez créer de nouveaux segments de chemin, vous devez utiliser des méthodes telles que var newSegment = myPath.createSVGPathSegArcAbs(100,200,10,10,Math.PI/2,true,false) , puis utiliser l'une des méthodes pour coller ce segment dans la liste, par exemple segments.appendItem(newSegment) .

96
Phrogz

Éléments Dynamic Path en SVG avec prise en charge Javascript et Css

var XMAX = 500;
    var YMAX = 500;
    var _xx=10;
    var _reg=100;
    var _l=10;
    // Create PATH element
    for(var x=1;x<20;x++)
    {
    var pathEl = document.createElementNS("http://www.w3.org/2000/svg", "path");
    pathEl.setAttribute('d','M'+_l+' 100 Q 100  300 '+_l+' 500' );
    pathEl.style.stroke = 'rgb('+(_reg)+',0,0)';
    pathEl.style.strokeWidth = '5';
    pathEl.style.fill = 'none';
        $(pathEl).mousemove(function(evt){$(this).css({"strokeWidth":"3","stroke":"#ff7200"}).hide(100).show(500).css({"stroke":"#51c000"})});

    document.querySelector('svg').appendChild(pathEl);
    _l+=50;
    }

Démo dans jsfiddle

5
Godly Mathew