スタートページJavascriptSVG

JavaScriptでsvg要素の動的編集


ここでの各要素の id 名称の命名法

一つのHTML内には複数の SVG要素があるし、line などの図形(子要素)も複数あります。
それを一意に特定するために、各要素に id を付けますが、ここでは、次の命名規則になっているとします。
 ・SVG要素は、SVG1, SVG2, … の連番とする。
 ・その子要素については、SVG1Line1, SVG1Line2, … , SVG2rect1, SVGrect2, … とする。

既存SVG内の図形を修正・削除・新規作成する

最も頻繁に発生する加工でしょう。
右図は下のインラインで作成した SVG1 です。

 <svg id="SVG1" width="200" height="200">
  <line id="SVG1line1" x1="10" y1="50" x2="150" y2="50" stroke="black" />
  <circle id="SVG1circle1" cx="50" cy="100" r="20" stroke="red" fill="yellow" />
 </svg>

次の加工をじます。
・SVG1line1  既存図形の修正
・SVG1circle1 既存図形の削除
・SVG1rect1 新規作成

 function test1() {
  // SVG要素の指定
  var SVG1 = document.getElementById("SVG1");         // ア

  // 既存図形(直線)の修正
  var SVG1line1 = document.getElementById("SVG1line1");      // イ
   SVG1line1.setAttribute("y2", "100");     // 属性変更 // ウ
   SVG1line1.setAttribute("stroke","red");   // 属性変更 
   SVG1line1.setAttribute("stroke-width", "5"); // 属性追加

  // 既存図形(円)の削除(正確には非表示にするだけ)
  var SVG1circle1 = document.getElementById("SVG1circle1");  // エ
   SVG1circle1.setAttribute("display","none");        // オ

  // 新規図形(直方形)の作成追加
  var SVG1rect1 = document.createElementNS("http://www.w3.org/2000/svg", "rect");  // カ
    // ; を作成
   SVG1rect1.setAttributeNS(null, "x", "100");        // キ
   SVG1rect1.setAttributeNS(null, "y", "30");
   SVG1rect1.setAttributeNS(null, "width", "80");
   SVG1rect1.setAttributeNS(null, "height", "50");
   SVG1rect1.setAttributeNS(null, "stroke", "blue");
   SVG1rect1.setAttributeNS(null, "fill", "yellow");
   // 新規作成した SVG1rect1 を SVG1 の子要素として追加
   SVG1.appendChild(SVG1rect1);               // ク
 }

データを外から与えて図形を作図する

既存の SVG2要素 (200x200) に、円の属性を与えて作図します。
前の図形をクリアしていないので、後の図形が重なります。

cx= cy= r= stroke= stroke-width= fill=
function test2() {
    // formからの入力
    var cx = document.form2.cx.value;
    :
    var fill = document.form2.fill.value;
  // SVG の特定
    var SVG2 = document.getElementById("SVG2");
  // 図形作成
    var SVG2circle1 = document.createElementNS("http://www.w3.org/2000/svg", "circle");
    SVG2circle1.setAttributeNS(null, "cx", cx);
    :
    SVG2circle1.setAttributeNS(null, "fill", fill);
  // 図形追加
    SVG2.appendChild(SVG2circle1);    
]

既存SVG要素の子要素取得

右図の SVG画面があります。id="svg3" 以外は、子要素には id がありません。
(通常のインライン記述では、そうなっているでしょう)
そのインライン記述は下の通りですが、ここでは id="svg3" 以外はわかっていないとします。
JavaScript により、各要素の属性を取得するのがここでの目的です。
これは、既存のSVG画像を、Javascript で更新するのに便利でしょう。

<svg id="SVG3" width="200" height="200">
    <line x1="10" y1="10" x2="100" y2="50" stroke="black"  stroke-width="2" stroke-dasharray="15, 5"/>
    <line x1="50" y1="70" x2="150" y2="100" stroke="blue" />
    <rect x="100" y="120" width="80" height="50" />
    <circle cx="40" cy="150" r="30" fill="red" />
</svg>

インライン記述全体の取得

属性は、代表的なものに限定します。


取り出されたコード(これをコピー&ペーストすれば、上の画面が表示されます。

作成プログラム

function test32() {
    var 表示場所 = "表示場所32";
    var コード = "";
    // ===== SVG要素
    var svg = document.getElementById("SVG3");
    コード += '<svg '
            + 'width="' + svg.getAttribute("width") + '" '
            + 'height="' + svg.getAttribute("height") + '" '
            + 'viewBox="' + svg.getAttribute("viewBox") + '" '
            + '>';
    // ====================== 子要素
    var 子要素個数 = svg.childElementCount;
    var 子要素 = svg.children;
    for (var i=0; i<子要素個数; i++) {
        var 図形 = 子要素[i].tagName;
        コード += '<' + 図形 + ' ';
        // =========== 必須属性
        if (図形 == "line") {
            コード += 'x1="' + 子要素[i].getAttribute("x1") + '" ' 
                    + 'y1="' + 子要素[i].getAttribute("y1") + '" '
                    + 'x2="' + 子要素[i].getAttribute("x2") + '" '
                    + 'y2="' + 子要素[i].getAttribute("y2") + '" ';
        }
        if (図形 == "rect") {
            コード += 'x="' + 子要素[i].getAttribute("x") + '" ' 
                    + 'y="' + 子要素[i].getAttribute("y") + '" '
                    + 'width="' + 子要素[i].getAttribute("width") + '" '
                    + 'height="' + 子要素[i].getAttribute("height") + '" ';
        }
        if (図形 == "circle") {
            コード += 'cx="' + 子要素[i].getAttribute("cx") + '" ' 
                    + 'cy="' + 子要素[i].getAttribute("cy") + '" '
                    + 'r="' + 子要素[i].getAttribute("r") + '" ';
        }
        // 他の図形についても適宜追加する
        // =========== オプション属性
        // 代表的オプション属性 適宜追加すればよい
        コード += 'stroke="' + 子要素[i].getAttribute("stroke") + '" ' 
                + 'fill="' + 子要素[i].getAttribute("fill") + '" '
                + 'stroke-width="' + 子要素[i].getAttribute("stroke-width") + '" '
                + 'stroke-dasharray="' + 子要素[i].getAttribute("stroke-dasharray") + '" ';
        コード += ' />';
    }
    コード += '</svg>';
    document.getElementById(表示場所).innerHTML = コード;
}

アニメーション

左上隅の赤玉を右方向・下方向に移動させます。

方向開始位置終了位置実行時間打切回数名称
右方向 SVG4animate1
下方向 SVG4animate2

次のインラインコードに相当するものを作成したいのです。
すなわち、既存の SMG3circle1 の子要素として SVG4animate1 と SVG4animate1 を作成、追加挿入します。

    <svg id="SVG4" width="200" height="200">
      <circle id="SMG3circle1" cx="10" cy="10" r="10" … >
        <animate id="SVG4animate1" attributeName="cx" from=10 to="190" dur="10" repeatCount="3" />
        <animate id="SVG4animate2" attributeName="cy" from=10 to="190" dur="5" repeatCount="6" />
      </circle>
    </svg>

ポイントとなる部分は、次のようになります。

       :
    // SVG4circle1
    var SVG4 = document.getElementById("SVG4");
    var SVG4circle1 = document.getElementById("SVG4circle1")

  // SVG4animate1
    var SVG4animate1 = document.createElementNS("http://www.w3.org/2000/svg", "animate");
    SVG4animate1.setAttributeNS(null, "attributeName", "cx");
   :
    SVG4circle1.appendChild(SVG4animate1);

  // SVG4animate1
    var SVG4animate2 = document.createElementNS("http://www.w3.org/2000/svg", "animate");
    SVG4animate2.setAttributeNS(null, "attributeName", "cy");
   :
    SVG4circle1.appendChild(SVG4animate2);