46

Javascriptを使用してインラインSVGグラフィックを作成したい。

ただし、createElementNS関数は正規化を適用し、すべてのタグを小文字に変換しているようです。これはHTMLには問題ありませんが、XML/SVGには問題ありません。私が使用したNSはhttp://www.w3.org/2000/svgです。

特に、要素の作成に問題があります。として追加される<textpath>ため、機能しません。

いくつか検索しましたが、まだ解決策が見つかりませんでした。

誰かが解決策を知っていますか?

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

結果は

<textpath></textpath>
4

4 に答える 4

69

次の例がお役に立てば幸いです。

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>

于 2010-08-16T11:07:19.223 に答える
14

まず、あなたがしているように、createElementNSを使用します。createElement(NSなし)は、 Mozillaのドキュメントに従って、HTMLドキュメント内の要素名を自動的に小文字にします。

次に、ここでGoogleChromeの「要素の検査」機能を信頼しないでください。実際のnodeNameに関係なく、すべての要素が小文字で表示されているようです。これを試して:

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

document.createElement("textPath").nodeName
// Output: "TEXTPATH"

あなたの問題は無関係の問題かもしれません。たとえば、このコードはFirefoxでは正常に機能しますが、Chrome(12.0.742.112)では機能しません。

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();
};
<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>

私の問題は、おそらくChromeでのanimateMotionの処理の失敗と関係があります(問題13585)。

あなたの問題は同じかもしれませんし、別の問題かもしれませんが、要素検査官にだまされていないことを確認してください。

于 2011-07-06T15:16:49.670 に答える
2

同様の問題を解決しました。document.createElement(そして私はdocument.createElementNSを想定しています)は、HTMLページから呼び出されると、xmlノードではなくHTMLノード(大文字と小文字は区別されません)を作成します。

Chromeでは次の機能があります。

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

混合ケースノードを取得します。

于 2012-10-17T03:24:24.873 に答える
-2

与えられた答えは広すぎて、私にはあまり役に立ちません。私はそれが非常に面倒であるか、単に偽物であると言います。もし私があなたなら、私は単純に次のようなタグを付けたhtmlの要素を持っているでしょう:

<b id="myElement"></b>

要素を作成したり情報を追加したりする必要がある場合は、次のようにします。

document.getElementById('myElement').innerHTML = 'your stuff here'; 

お役に立てば幸いです。

于 2011-05-19T17:43:58.560 に答える