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

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

[伊藤千光,WebOS Goodies]

SVGアニメーションの基礎

 SVGには非常に強力なアニメーション機能が実装されており、図形のほとんどの要素に対して時間的変化を与えられます。座標や色のような数値属性のみならず、stroke-linecapのような文字列を指定する属性やパスの形状さえもアニメーションの対象になります。強力なだけに使い方も多岐に渡るので、以降2ページに渡ってSVGのアニメーション機能を解説します。

 SVGでは、主にanimate、animateTransform、animateMotionの3つのタグでアニメーションを実現します。中でもanimateは基本となるもので、図形タグが持つほとんどの属性を制御できます。以下に使用例を示します。

シンプルなアニメーション シンプルなアニメーション 実際のサンプルを見る

 上記のコードでは、2つのanimateタグがそれぞれ異なる方法でアニメーション対象の要素を指定しています。1つ目のanimateタグにはxlink:href属性あり、この場合はそこで指定されたIDを持つ要素が対象になります。2つ目のanimateタグにはxlink:href属性がないので、直接の親要素(上の例であれば青いcircle)が対象となります。

 いずれの方法でも結果はまったく同じです。アニメーションを1カ所に集約したい場合は前者を、図形と一緒に管理したい場合は後者を使うとよいでしょう。この記事の以降のサンプルは、すべて後者で統一しています。

 animateタグ自体の記述に目を移すと、7つの属性を使ってアニメーションの動作を指定しているのが分かります。下表にそれぞれの属性の機能をまとめました。

属性名 説明
attributeType attributeName属性が指す属性の種類を「XML」(図形タグ自体の属性)「CSS」(CSS属性)のいずれかで指定する。
attributeName アニメーションの対象となる属性の名前。
dur アニメーションの1ループにかける時間。「hh:mm:ss」の形式、もしくはh(時)、min(分)、s(秒)、ms(ミリ秒)の単位の数値で指定する。
repeatCount リピート回数を表す0以上の数値。「indefinite」を指定すると無限に繰り返す。
from アニメーションの初期値。省略するとアニメーション適用前の値が初期値となる。
to アニメーションの目標値(終了時の値)。
by アニメーションの目標値を初期値からの差分で指定。

 従って、上の例の1つ目のanimationタグは、circleタグのcx属性が10から290まで3秒かけて変化するアニメーションを無限に繰り返す、という指定になります。

 初期値と目標値だけでなく、複数の経過点を指定したキーフレームアニメーションも可能です。この場合はfrom/to/byの代わりにvalues属性を用いて、各時点での値をコロン区切りで指定します。以下に例を示します。

キーフレームアニメーション キーフレームアニメーション 実際のサンプルを見る

 アニメーション可能な値は単純な数値だけに限りません。アニメーション可能な属性値であればなんでも指定できます。以下の例はfill属性(塗り潰しの色)をアニメーションさせる例です。

色のアニメーション 色のアニメーション 実際のサンプルを見る

 もう1つ例を示しましょう。今度はパスの形状をアニメーションさせます。アニメーションの対象をpathタグのd属性とし、各キーフレームの値としてパス定義そのものを記述すれば、徐々に形状が変化するアニメーションが実現できます。

形状のアニメーション 形状のアニメーション 実際のサンプルを見る

 以上のように、animateタグを用いることで多くの属性にアニメーションが適用できます。ただし、transform属性だけはanimateタグが使えず、代わりにanimateTransformタグを用います。以下に平行移動(translate)によるアニメーションの例を示します。

平行移動のアニメーション 平行移動のアニメーション 実際のサンプルを見る

 animateTransformタグの属性はanimate属性とほぼ同じですが、アニメーションさせる変換の種類を指定するtype属性の指定が必要です。type="translate"とすると平行移動のアニメーションとなり、値の形式はX、Y座標を空白・コンマ区切りで並べたものになります。

 同様に、type="scale"とすれば拡大・縮小のアニメーションになります。値の形式はX方向、Y方向の倍率を空白・コンマ区切りで並べたものです。拡大・縮小の中心はユーザー座標系の原点になるので、以下の例ではアニメーションの対象であるcircleタグをgタグで囲い、gタグのtransform属性で原点を円の中心に移動しています。

拡大・縮小のアニメーション 拡大・縮小のアニメーション 実際のサンプルを見る

 type="rotate"で回転のアニメーションになります。値の形式は回転角、回転中心のX、Y座標を空白・コンマ区切りで並べます。回転中心が指定できるので、scaleの時と違ってgタグによる座標変換は不要です。

回転のアニメーション 回転のアニメーション 実際のサンプルを見る

 type属性に「skewX」もしくは「skewY」を指定するとせん断変形のアニメーションとなります。前者なら横方向、後者なら縦方向のせん断です。値は軸の回転角です。拡大・縮小と同様に変換中心は原点となるため、必要に応じてgタグで座標変換を施す必要があります。

せん断変形のアニメーション せん断変形のアニメーション 実際のサンプルを見る

 アニメーションを行うタグの最後の1つであるanimateMotionタグは、パスで定義した軌跡をなぞって移動する、いわゆるモーションパスアニメーションを実現するものです。以下に例を示します。

パスに沿ったアニメーション(1) パスに沿ったアニメーション(1) 実際のサンプルを見る

 animateMotionタグは移動の軌跡をパスで定義するため、from/to/byやvalues属性は指定できません。代わりに子要素としてmpathタグを記述し、そのxlink:href属性でモーションパスとして使用するパスを定義したpathタグを参照します。durやrepeatCountなどの残りの属性はanimateタグと同じです。

 pathタグで定義したパスを参照する方法のほかに、animateMotionタグのpath属性でモーションパスを直接定義する方法もあります。モーションパスを表示したくない時に使います。

パスに沿ったアニメーション(2) パスに沿ったアニメーション(2) 実際のサンプルを見る

 また、animateMotionタグには回転処理の指定を行うrotate属性もあります。数値を指定すればアニメーション対象の図形がその角度だけ回転し、「auto」ならX軸が移動方向を、「auto-reverse」なら反対を向くように自動的に回転されます。車をコースに沿って走らせる、というようなアニメーションには非常に便利な機能です。

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

※ 上の例で灰色の線で表示しているモーションパスは、分かりやすさのためにコード例とは別に描画しています。

 キーフレームの制御

 values属性によるアニメーションは、デフォルトでは各キーフレーム間を一定の変化量で補完する、いわゆる線形補間となります。この処理はcalcMode属性に「linear」(デフォルト)、「discrete」、「spline」、「paced」のいずれかを指定することにより変更できます。例えばdiscreteを設定すると、補完処理を行わずにワープするように移動するような効果になります。

calcMode="discrete" calcMode="discrete" 実際のサンプルを見る

 「spline」を指定すると、三次ベジェ曲線による補完になります。この場合はkeySplines属性によってベジェ曲線の制御点を指定します。値は空白・コンマ区切りの数値4つを組として、それをコロン区切りで(キーフレームの数-1)個記述します。各数値は1つ目の制御点のX、Y座標と2つ目の制御点のX、Y座標です。

calcMode="spline" calcMode="spline" 実際のサンプルを見る

 参考までに、第一回で取り上げたCSSアニメーションでのcurve(timing-function)の指定に対応するkeySplines属性の値を表にまとめました。指定の際の目安にしてください。

CSSでの指定 keySplines属性の値
ease 0.25,0.1 0.25,1.0
linear 0.0,0.0 1.0,1.0
ease-in 0.42,0 1.0,1.0
ease-out 0,0 0.58,1.0
ease-in-out 0.42,0 0.58,1.0

 最後の「paced」は少々特殊で、区間の距離によらずアニメーション全体にわたって一定の速度で移動するという指定です。別の表現をすると、アニメーションの時間が、それぞれの区間の距離に比例して割り当てられるようになります。以下に例を示します。

calcMode="paced" calcMode="paced" 実際のサンプルを見る

 赤青2つの円には、いずれも区間距離が均等でないキーフレームアニメーションが適用されています。calcModeを指定していない赤の円は、区間ごとに時間が均等に割り振られるため、区間によって移動速度が異なっています。それに対して、calcMode="paced"を指定した青の円は、区間距離に応じて時間が割り当てられるため、全区間にわたって一定の速度で移動しています。

 上記のような区間ごとの時間の調整は、keyTimes属性によって明示的に行うことも可能です。属性値としては、各キーフレームに対応する時間を空白・コンマ区切りで指定します。時間はアニメーションの開始時点を0.0、終了時点を1.0とした小数点値です。以下は上の例のcalcMode="paced"と同じ効果をkeyTimes属性で実現したものです。

keyTimesの効果 keyTimesの効果 実際のサンプルを見る

 calcMode属性およびkeyTimes属性は、animateTransform、animateMotionタグにも同様に指定できます。ただし本来モーションパス上にキーフレームは存在しないので、keyPoints属性使って明示的にキーフレームを設定しなければなりません。属性値はモーションパス全体の長さを1.0として、各キーフレームの開始点からの距離をセミコロン区切りで並べます。このそれぞれの値がキーフレームになるため、keyTimes属性に指定する値の数はkeyPointsと同じでなければなりません。

 以下にanimateMotionタグにkeyTimes属性を適用した例を示します。モーションパスは単純に矩形の輪郭上を移動するだけのものですが、keyPoints属性を使用して初期位置の対角にキーフレームを設定し、区間ごとの速度を変化させています。animateMotionタグのcalcMode属性のデフォルトはpacedであるため、calcMode="linear"を明示的に指定している点にも注意してください。

animateMotionへのKeyTimesの適用 animateMotionへのKeyTimesの適用 実際のサンプルを見る

 次のページでも引き続きSVGのアニメーション機能を解説していきます。

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

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

メールマガジン登録

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