JavaScriptアニメーション

SVGスタンダードで定義されている説明的アニメーション・エレメントを利用したのでは、思ったようなアニメーションを作成できないこともあります。たとえば、SVGエレメントのノン・スカラー属性をアニメーション化しようとする場合、あるいは属性値をランダムに変化させたり、ノン・リニア・フォーミュラにしたがって変化させようとする場合などです。このような場合には、SVGドキュメントへのJavaScriptアクセスとDOMアクセスを組み合わせることにより、エフェクトを作成することができます。

JavaScriptアニメーションの実例を次にあげます。画像がアニメーションにならない場合には、ここをクリックしてください

上のアニメーションは紫<path>エレメントの“d”属性を時間に沿って変化させることによって、作られています。

アニメーションに必要とされるJavaScriptのコードはすべて、SVGドキュメント自体の中で定義されています。このため、どのようなWebページにでも、アニメーション化された画像を容易に組み込むことができます。

このアニメーションは<svg>タグのonloadイベントがトリガーとなって開始されます。onloadハンドラは全体的変数中のSVGドキュメントにポインタをセーブします。次に、setIntervalというシステム関数を呼び出し、ブラウザがnext_frameを繰り返し呼び出すようにします。

関数 on_load (イベント)
{
  // Save a pointer to the SVGDocument object
  // so that we can use it to retrieve various
  // named elements inside the animation function.
  svgdoc = event.getCurrentNode().getOwnerDocument();
  // Start the animation loop.
  setInterval ('next_frame()', 100);
}

これは極度に単純化されたアニメーションへのアプローチであることにご注意ください。next_frame関数が正確に千分の百秒ごとに呼び出されるという保証はありません。呼び出しと次の呼び出しの間の実際の経過時間は、クライアントのシステムの性能やリソースの利用可能性によって異なります。また、インターバルの値は千分の何秒にでも設定することが可能です。数字を大きくすると、アニメーションがスローになり、荒くなります。数値を小さくするとアニメーションが速くなり、スムーズに流れるようになります。

上の実例はJavaScript駆動型のアニメーションの基礎です。next_frame関数の中にsvgdoc変数を使うことにより、思いのままにSVGドキュメント内のあらゆるエレメントにアクセスしたり、エレメントを修正することができます。次をご覧ください。これは特にこの実例のnext_frame関数について、詳細に説明するためのものです。


アニメーション化されるパスの部分は三次元ベジェ曲線で、SVGドキュメントの横幅全体にわたっています。三次元ベジェ曲線は2つのコントロールポイントを必要とします。このアニメーションは終点を一定にしたまま、これら2つのコントロールポイントを絶えず変化させることによって作られています。コントロールポイントの座標用に“ターゲット”値をランダムに生成し、ターゲット値に一致するまで、現在の座標を次第に増加ないし縮小させます。

next_frame関数の内部では、4つの全体的変数が利用されています。x0およびy0は第1のコントロールポイント用で、x1およびy1は第2のコントロールポイント用です。さらにターゲット値を保持するためにも、tx0ty0tx1およびty1という4つの全体的変数を用いています。

next_frame関数はまず、DOM方式を使って<path>エレメントがアニメーション化されるハンドルと、on-loadイベント中にSVGドキュメントを設定するsvgdocハンドルを引きだします。

  var linenode = svgdoc.getElementById ('line');
  if (!linenode)
    return;

次に、もし必要な場合には、コントロールポイントのx、y座標用の新たなターゲット値を生成します。これは最初の呼び出し(ターゲット値は-1)あるいは、すべての現在座標がターゲット座標と一致したときに行われます。

  if (tx0 < 0
  || (tx0 == x0 && ty0 == y0 && tx1 == x1 && ty1 == y1))
  {
    tx0 = Math.floor (400*Math.random());
    ty0 = Math.floor (300*Math.random());
    tx1 = Math.floor (400*Math.random());
    ty1 = Math.floor (300*Math.random());
  }

さらに現在座標をターゲット値に向けて+/-10ピクセルの範囲で変更します。これはコードを簡単に読めて維持できるように、個別の関数を利用して行います(SVGのソースを参照してください)。

  x0 = change_coord (x0, tx0);
  y0 = change_coord (y0, ty0);
  x1 = change_coord (x1, tx1);
  y1 = change_coord (y1, ty1);

最後に新たな座標を利用するために、パス・エレメントの“d”属性を変更します。この属性にはパスの座標セットのすべてが含まれていることを思い出してください。つまり3次元ベジェ曲線の、始点、2つのコントロールポイント、終点に加えて、その他のあらゆる点です。

  linenode.setAttribute
    ('d', 'M0,300L0,150C'+x0+','+y0
    +','+x1+','+y1+',400,150L400,300z');

次のレッスン:マウス・イベント

Copyright ©2000 Adobe Systems Incorporated. All rights reserved.
Terms of Use
Online Privacy Policy