連載
» 2012年07月02日 00時00分 公開

Webグラフィックをハックする(3):SVGで図形やアニメを描画してみよう (3/5)

[伊藤千光,WebOS Goodies]

開始トリガーと複数アニメーション

 これまでの例はすべて開始・終了タイミングの指定を省略していたため、ドキュメントの読み込み時に自動的にアニメーションが始まっていました。また、アニメーション対象も単一の属性値である場合のみを扱ってきました。しかし、実際の利用シーンではユーザーのインタラクションでアニメーションを開始したり、複数の属性を同時にアニメーションしたりする場合が多いでしょう。

 以降では、SVGアニメーションの応用として、さまざまな開始・終了タイミングの指定方法と、複数の属性に対してアニメーションを適用する方法を取り上げます。

 開始トリガーの指定

 アニメーションの開始・終了の条件(開始・終了トリガー)は、begin/end属性でカスタマイズできます。begin属性とend属性の指定方法はまったく同じなので、以降はbegin属性について説明します。

 最も単純な開始トリガーは、ドキュメントの読み込みからの経過時間(オフセット時間)によるものです。begin属性にdur属性と同じ形式の時間指定を記述すると、この指定となります。以下に例を示します。

ドキュメント表示開始からのオフセット ドキュメント表示開始からのオフセット 実際のサンプルを見る

 赤青の2つの円はほぼ同じアニメーションが適用されていますが、青い円のみ「begin="3s"」の指定によってドキュメントの読み込みから3秒遅れて開始しており、位置が半周期分ずれています。ドキュメントをリロードすれば、青い円のみ遅れて動き出すのが確認できるでしょう。

 オフセット時間には負の値も指定できます。もちろん時間を過去にさかのぼるわけではなく、さも過去にアニメーションを開始していたように「頭出し」して再生する、という動作になります。上の例の「begin="3s"」を「begin="-3s"」に置き換えた例を以下に示します。動きは1つ前の例と同様ですが、ドキュメントをリロードすると、青い円は右端(開始から3秒後の位置)を初期位置として左に向けて動き出します。

負のオフセット 負のオフセット 実際のサンプルを見る

 begin属性の値として「<アニメーションタグのID>.<beginまたはend>[±<時間>]」を指定すると、指定したIDのアニメーションの開始・終了が開始トリガーになります。複数のアニメーションを同時に開始したり、順番に再生するのに使えます。省略可能な時間指定は開始トリガーからの遅延時間です。この機能を利用して2つのアニメーションを交互に実行する例を以下に示します。

他のアニメーションの終了と同時に開始 他のアニメーションの終了と同時に開始 実際のサンプルを見る

 1つ目のanimateタグのbegin属性では、「0s」(ドキュメント読み込み時に開始)と「endev2.end」の2つのトリガーを指定しています。このように、begin/endタグにはセミコロン区切りで複数のトリガーを併記できます。fill属性はアニメーション終了後の状態を「remove」(元の値を復帰する:デフォルト値)、「freeze」(アニメーション終了時の値を維持する)から選択するものです。これを指定しないと、2つ目のanimateタグのbegin属性で設定している1秒の遅延の間、円が初期位置(左端)に戻ってしまいます。

 begin属性を「<アニメーションタグのID>.repeat(<回数>[±<時間>])」に設定すると、特定のリピートの開始をトリガーにできます。以下の例は、円を左右に移動するアニメーションの繰り返しごとに、円の色を変化させています。

特定のリピート回数で開始 特定のリピート回数で開始 実際のサンプルを見る

 この例では、まだ説明していないsetタグを使っています。これは「アニメーションしないanimateタグ」ともいえるもので、開始トリガーを受けるとto属性の値をアニメーション対象の属性に単純に設定します。一部の属性(from/by/values等)が指定できないことを除き、使い方はanimateタグと同じです。上の例では3つのsetタグを用意し、begin属性をそれぞれ移動アニメーションの開始時、1回目のリピート時、2回目のリピート時に設定して円の色を変更しています。

 ここまでの例では時間的なタイミングを開始トリガーとしてきましたが、ユーザーのインタラクションをトリガーにすることも可能です。最も分かりやすいのは、単にリンクを設置する方法です。以下の例ではボタンに見立てたrectタグにanimateタグへのリンクを設定し、クリックでアニメーションを開始する例です。begin属性にはindefiniteを指定し、デフォルト動作(ドキュメント読み込み時にアニメーション開始)を抑制しています。

リンクによる開始 リンクによる開始 実際のサンプルを見る

 クリック以外のユーザーアクションをトリガーとしたい場合は、DOMイベントが使えます。begin属性に「<タグのID>.<イベント名>[±<時間>]」を設定することで、指定したタグで指定したイベントが発生した際にアニメーションが開始されます。以下はmouseupイベントを監視することで、rectタグ上でマウスボタンが離された際にアニメーションを開始する例です。

DOMイベントによる開始 DOMイベントによる開始 実際のサンプルを見る

 SVGがサポートするDOMイベントについては以下のページを参照してください。基本的なものはHTMLと共通です。

 上記2つの例で使っているrestart属性は、2回目以降の開始トリガーの処理を選択するものです。「always」(常に開始する:デフォルト値)、「whenNotActive」(アニメーション中でなければ開始する)、「never」(2回目以降は開始しない)のいずれかが指定できます。リンクによる開始の例ではalwaysを、イベント開始の例ではwhenNotActiveを指定しているので、挙動の違いを確認してください。

 ここまで、5通りのアニメーション開始(終了)トリガーを取り上げましたが、SVGの仕様ではアクセスキー(ショートカットキー)による開始と実時刻指定(2012年1月1日の0時0分に開始など)も定義されています。原稿執筆時点で筆者が確認した限り、前者はFirefoxのみサポート、後者はサポートブラウザなしという状況ですが、興味のある方は仕様を参照してください。

 複数のアニメーション

 SVGで複数のアニメーションを同時実行する方法は、とても直感的です。それぞれのアニメーションタグは完全に独立・並列で動作するので、単純に複数のanimateタグを並べて書けば、すべてが並列で処理されます。以下はcircleタグのcx属性とfill属性を同時にアニメーションさせる例です。

異なる属性を同時にアニメーション 異なる属性を同時にアニメーション 実際のサンプルを見る

 複数のアニメーションで同じ属性をアニメーションさせると、通常は最後のアニメーションタグのみが有効になり、他は無視されます。それぞれのアニメーションがタグの(見た目上の)属性値を上書きしていくためです。

 この挙動はadditive属性で変更できます。additive属性はアニメーションで計算された値を属性値に反映させる処理を指定するもので、「replace」(上書き:デフォルト値)、「sum」(元の値に加算する)のいずれかが指定できます。以下の例は、「additive="sum"」によって1つの属性に2つのアニメーションを適用する例です。

同じ属性に複数のアニメーションを適用 同じ属性に複数のアニメーションを適用 実際のサンプルを見る

 この指定が特に重要なのが、animateTransformタグによる変形アニメーションです。移動・回転・スケーリング・せん断が同じtransform属性に集約されているため、複数の変形アニメーションを同時に適用するためには「additive="sum"」の指定が必須です。

複数のanimateTransformを適用 複数のanimateTransformを適用 実際のサンプルを見る

 少し話がずれますが、additive属性に似た機能としてaccumulate属性があります。これはアニメーションのリピート時の動作を指定するもので、こちらも「replace」と「sum」が指定できます。デフォルトはreplaceですが、sumを指定すると繰り返し時のアニメーション開始位置が前のアニメーションの終了位置になります。以下にボールがバウンドしながら進んでいくようなアニメーションをaccumulate属性で実現する例を示します。

accumulate属性の効果 accumulate属性の効果 実際のサンプルを見る

 このように、SVGのアニメーションタグは複数を組み合わせることを前提にして設計されており、それによってより多彩な動きを表現できるようになっています。これらの機能を活用すれば、これまでになくダイナミックなWebページが簡単に実現できるでしょう。

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。