web-dev-qa-db-fra.com

JavaScript createElement et SVG

Je veux créer des graphiques SVG en ligne en utilisant Javascript.

Cependant, il semble que la fonction createElementNS applique une certaine normalisation et transforme toutes les balises en minuscules. C'est bien pour HTML mais pas pour XML/SVG. Le NS que j'ai utilisé est http://www.w3.org/2000/svg .

En particulier, j'ai des problèmes pour créer un élément. Comme il sera ajouté en tant que tel, cela ne fonctionnera pas.

J'ai fait quelques recherches mais je n'ai pas encore trouvé de solution.

Quelqu'un connaît-il une solution?

Merci beaucoup!

document.createElementNS("http://www.w3.org/2000/svg","textPath");

résulte en

<textpath></textpath>
31
pat

J'espère que l'exemple suivant vous aidera:

function CreateSVG() {
    var xmlns = "http://www.w3.org/2000/svg";
    var boxWidth = 300;
    var boxHeight = 300;

    var svgElem = document.createElementNS(xmlns, "svg");
    svgElem.setAttributeNS(null, "viewBox", "0 0 " + boxWidth + " " + boxHeight);
    svgElem.setAttributeNS(null, "width", boxWidth);
    svgElem.setAttributeNS(null, "height", boxHeight);
    svgElem.style.display = "block";

    var g = document.createElementNS(xmlns, "g");
    svgElem.appendChild(g);
    g.setAttributeNS(null, 'transform', 'matrix(1,0,0,-1,0,300)');

    // draw linear gradient
    var defs = document.createElementNS(xmlns, "defs");
    var grad = document.createElementNS(xmlns, "linearGradient");
    grad.setAttributeNS(null, "id", "gradient");
    grad.setAttributeNS(null, "x1", "0%");
    grad.setAttributeNS(null, "x2", "0%");
    grad.setAttributeNS(null, "y1", "100%");
    grad.setAttributeNS(null, "y2", "0%");
    var stopTop = document.createElementNS(xmlns, "stop");
    stopTop.setAttributeNS(null, "offset", "0%");
    stopTop.setAttributeNS(null, "stop-color", "#ff0000");
    grad.appendChild(stopTop);
    var stopBottom = document.createElementNS(xmlns, "stop");
    stopBottom.setAttributeNS(null, "offset", "100%");
    stopBottom.setAttributeNS(null, "stop-color", "#0000ff");
    grad.appendChild(stopBottom);
    defs.appendChild(grad);
    g.appendChild(defs);

    // draw borders
    var coords = "M 0, 0";
    coords += " l 0, 300";
    coords += " l 300, 0";
    coords += " l 0, -300";
    coords += " l -300, 0";

    var path = document.createElementNS(xmlns, "path");
    path.setAttributeNS(null, 'stroke', "#000000");
    path.setAttributeNS(null, 'stroke-width', 10);
    path.setAttributeNS(null, 'stroke-linejoin', "round");
    path.setAttributeNS(null, 'd', coords);
    path.setAttributeNS(null, 'fill', "url(#gradient)");
    path.setAttributeNS(null, 'opacity', 1.0);
    g.appendChild(path);

    var svgContainer = document.getElementById("svgContainer");
    svgContainer.appendChild(svgElem);
}
#svgContainer {
  width: 400px;
  height: 400px;
  background-color: #a0a0a0;
}
<body onload="CreateSVG()">
    <div id="svgContainer"></div>
</body>
43
gumape

Tout d'abord, utilisez createElementNS, comme vous le faites. createElement (sans NS) met automatiquement en minuscule les noms des éléments dans les documents HTML, selon documentation Mozilla .

Deuxièmement, ne faites pas confiance à la fonctionnalité "Inspecter l'élément" de Google Chrome ici. Il semble afficher chaque élément en minuscules, quel que soit le nom de nœud réel. Essaye ça:

> document.createElementNS ("http://www.w3.org/2000/svg", "textPath"). nodeName 
 "textPath" 
> document.createElement ( "textPath"). nodeName 
 "TEXTPATH" 

Votre problème peut être un problème sans rapport. Par exemple, ce code fonctionne bien dans Firefox, mais se casse dans Chrome (12.0.742.112):

<html>
  <head>
      <script>
        function animateSVG() {
          var svgNS = "http://www.w3.org/2000/svg";
          var textElement = document.getElementById("TextElement");
          var amElement = document.createElementNS(svgNS, "animateMotion");
          console.log(textElement);
          console.log(amElement);
          console.log(amElement.nodeName);
          amElement.setAttribute("path", "M 0 0 L 100 100");
          amElement.setAttribute("dur", "5s");
          amElement.setAttribute("fill", "freeze");
          textElement.appendChild(amElement);
          //amElement.beginElement();
        };
      </script>
  </head>
  <body onload="animateSVG()">
    <svg width="100%" height="100%" version="1.1" xmlns="http://www.w3.org/2000/svg">
      <g transform="translate(100,100)">
        <text id="TextElement" x="0" y="0" style="font-family:Verdana;font-size:24">
          It's SVG!
          <!-- <animateMotion path="M 0 0 L 100 100" dur="5s" fill="freeze"/> -->
        </text>
      </g>
    </svg>
  </body>
</html>

Mon problème a probablement quelque chose à voir avec la gestion défectueuse d'animateMotion dans Chrome ( problème 13585 ).

Votre problème peut être le même, ou il peut s'agir d'un autre problème, mais assurez-vous que vous n'êtes pas dupe de l'inspecteur d'éléments.

11
dlitz

Je viens de résoudre un problème similaire. document.createElement (et je suppose que document.createElementNS), lorsqu'il est appelé à partir d'une page HTML crée un nœud HTML (où la casse n'a pas d'importance), pas un nœud xml.

Les éléments suivants fonctionnent dans Chrome:

doc = document.implementation.createDocument (null, null, null); doc.createElementNS ("http://www.w3.org/2000/svg", "textPath");

vous obtiendrez votre nœud de cas mixte.

2
Markus De Freitas