web-dev-qa-db-ja.com

SVGでの<path>データのスクリプト化(読み取りと変更)

誰か本当に助けてくれませんか? SVGのスクリプトを実行する方法を探しています。しかし、私が手に入れたものはすべて一致しません!また、そのコードセットを使用した理由が十分に含まれていません。たとえば、1つはevent.targetを使用し、もう1つはevent.getTarget()を使用し、もう1つはevent.target.firstchild.dataを使用しました。誰でも助けてくれますか?

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

パスsvgの例は正しいですか?私が必要なのは、それらの座標を取得し、おそらく変数に入れて、別のSVGの座標として使用することです。どうすればそれができますか?別のことは、インターフェイスに数値を入力することで、これらの座標をどのように変更できるかです。

だから私は答えを探そうとしましたが、私が言ったように、私は必要な情報を見つけられなかったか、多分私はそれが私に示したものを理解しなかったかもしれません。

27
Lei Leyba

次の4つの質問があるようです。

  1. SVGファイル内にスクリプトを埋め込むにはどうすればよいですか?
  2. SVGファイル内でスクリプトを実行するにはどうすればよいですか?
  3. スクリプトから_<path>_要素のデータにアクセスするにはどうすればよいですか?
  4. スクリプトから_<path>_要素のデータを操作するにはどうすればよいですか?

一度に1つずつ取り組みましょう。


SVGファイル内にスクリプトを埋め込むにはどうすればよいですか?

SVG仕様 で説明されているように、ドキュメントに_<script>_要素を配置してJavaScriptコードを含めることができます。最新のSVG仕様によれば、スクリプトに対して type属性を指定する必要はありません です。デフォルトは_type="application/ecmascript"_です。

  • その他の一般的なMIMEタイプには、_"text/javascript"_、_"text/ecmascript"_(SVG 1.1で指定)、_"application/javascript"_、および_"application/x-javascript"_があります。これらすべてのブラウザのサポート、またはtype属性を完全に省略することに関する詳細な情報はありません。私はいつも_text/javascript_で大成功を収めています。

HTMLと同様に、スクリプトコードをドキュメントに直接配置するか、外部ファイルを参照することができます。後者を行う場合、href名前空間の属性とともに、src属性(xlinkではなく)をURIに使用する必要があります。

_<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>
_

SVGファイル内でスクリプトを実行するにはどうすればよいですか?

HTMLと同様に、SVGドキュメントに含まれるコードは、検出されるとすぐに実行されます。 _<script>_要素をドキュメントの残りの上に配置すると(HTMLドキュメントの_<script>_に_<head>_を配置するときのように)、ドキュメント要素はどれも利用できなくなります。コードが実行されています。

これを回避する最も簡単な方法は、ドキュメントの下部に_<script>_要素を配置することです。

_<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>
_

または、ドキュメントの上部にコールバック関数を作成し、ドキュメントの残りの準備ができたときにのみ呼び出すことができます。

_<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>
_

スクリプトから_<path>_要素のデータにアクセスするにはどうすればよいですか?

SVGの要素に関するほとんどの情報にアクセスするには、2つの方法があります。標準のDOMレベル1コアメソッド getAttribute() を使用して文字列として属性にアクセスするか、 SVG DOMオブジェクトとメソッド 。両方を見てみましょう。

getAttribute()を介したパスデータへのアクセス

getAttribute()を使用すると、ソースを表示したときと同じ文字列が返されます。

_<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>
_
  • 長所:呼び出すのは非常に簡単です。あなたはSVG DOMについて何も知る必要はありません
  • 欠点:文字列を取得するため、属性を自分で解析する必要があります。 SVG _<path>_データの場合、これは耐え難い場合があります。

SVG DOMメソッドを介したパスデータへのアクセス

_<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>
_

上記のスクリプトは、次の出力を生成します。

_Move to 150 0
Line to 75 200
Line to 225 200
Close Path
_
  • 長所:パスデータが解析されます。 API自体から正確な数値を取得します。 normalizedPathSegListを使用すると、相対コマンドが使用され、それらが絶対になります。 SMILアニメーションがパスデータを変更している場合、アニメーション化されていないpathSegListを使用すると、getAttribute()を介して利用できないアニメーション化されていない基本情報にアクセスできます。

  • 短所:甘いチンパンクは炎で、そのコードを見てください!そして、利用可能なすべてのパスセグメントを処理するわけでもありません。

SVG DOMのW3C仕様を読むのは難しい場合があるため、何年も前に、存在するプロパティとオブジェクトを閲覧するためのオンラインツールを作成しました。ここで使用できます: http://objjob.phrogz.net/svg/hierarchy


スクリプトから_<path>_要素のデータを操作するにはどうすればよいですか

上記と同様に、新しい文字列を作成してsetAttribute()を使用してオブジェクトに押し込むか、SVG DOMを操作できます。

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>
_

SVG DOMを使用したパスデータの操作

_<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>
_

一般に、さまざまなSVGPathSegサブクラスインスタンスのプロパティを変更するだけです。変更はすぐにDOMで行われます。 (上記の例では、最後のポイントがわずかに上に移動するため、元の三角形が斜めになります。)

新しいパスセグメントを作成する必要がある場合は、 var newSegment = myPath.createSVGPathSegArcAbs(100,200,10,10,Math.PI/2,true,false) などのメソッドを使用してから、いずれかのメソッドを使用してこのセグメントをリストに貼り付ける必要があります。 segments.appendItem(newSegment)

96
Phrogz

JavascriptとCssをサポートするSVGの動的パス要素

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

jsfiddleのデモ

5
Godly Mathew