Little Strange Software

スマホアプリの開発を行う LittleStrangeSoftware のブログです。

【SVG】SVGでアニメーションを指定してみる

 どうも!LSSです!!

 

 

に続き、今度はこの絵にアニメーションで動く「雲」を追加してみます!

 

 

SVGアニメーションを追加した絵

 

 

コード

<p>[]
<svg xmlns="http://www.w3.org/2000/svg" width="300" height="400">
 <defs>
  <radialgradient id="rg" cx="75%" cy="20%" r="20%">
   <stop offset="30%" stop-color="white"></stop>
   <stop offset="100%" stop-color="lightblue"></stop>
  </radialgradient>
  <radialgradient id="rgc" cx="50%" cy="50%" r="50%">
   <stop offset="0%" stop-color="#bbbbbbff"></stop>
   <stop offset="100%" stop-color="#bbbbbb00"></stop>
  </radialgradient>
  <lineargradient id="lg" x1="0%" y1="0%" x2="0%" y2="100%">
   <stop offset="0%" stop-color="lightgreen"></stop> 
   <stop offset="100%" stop-color="green"></stop>
  </lineargradient>
 </defs>
 <rect x="0" y="0" width="300" height="300" fill="url(#rg)"></rect>
 <rect x="0" y="300" width="300" height="100" fill="url(#lg)"></rect>
 <ellipse cx="330" cy="100" rx="100" ry="30" fill="url(#rgc)">
  <animate
    id="anm1"
    attributename="cx"
    attributetype="XML"
    from="400"
    to="-100"
    begin="0s" dur="5s"
    repeatcount="indefinite"
    fill="remove">
   </animate>

 </ellipse>
</svg>
[]</p>

 

赤文字部分が、今回追記したコードになります。

 

 

雲を楕円で描きます

コードで言うと、

<ellipse cx="330" cy="100" rx="100" ry="30" fill="url(#rgc)">
</ellipse>

 

この部分ですね。

 

cy="100" rx="100"
cxとcyは、楕円の中心位置を指定しています。
幅300・高さ400の画像枠の左上の角から見て、「右に330、下に100」の位置を中心としています。
※「右に330」のほうは後からアニメーション指定で上書きするのでここの指定は無意味になりますが。

 

rx="100" ry="30"
横長の楕円になるので、半径の指定は2つあります。
rxは横方向の半径、ryは縦方向の半径、という指定です。

 

fill="url(#rgc)"
fillで塗りつぶし方を指定しています。
fill="red"と書くと、赤で塗りつぶす事になるのですが、今回のように fill="url(#rgc)" という書き方をすると「別途rgcというidをつけて設定した塗りつぶし方」を指定する事になります。

 

 

またも円形グラデーション

その、「rgcというidをつけて設定した塗りつぶし方」を設定しているのが、 

<radialgradient id="rgc" cx="50%" cy="50%" r="50%">
 <stop offset="0%" stop-color="#bbbbbbff"></stop>
 <stop offset="100%" stop-color="#bbbbbb00"></stop>
</radialgradient> 

<defs>の中に書いた、この部分になります。

cx="50%" cy="50%" r="50%"

と指定しているので、横方向もど真ん中、縦方向もど真ん中、グラデ半径も中央から50%なので、「与えられた枠にぴったり収まる円形」のグラデーションになります。

 

<stop offset="0%" stop-color="#bbbbbbff"></stop>
<stop offset="100%" stop-color="#bbbbbb00"></stop>

グラデ―ションの始まりと終わりの色を指定しています。
円形グラデーションは「中央から外側に向かって広がる」グラデーションになるので、0%は始まり(中央)での色。
今回は、#bbbbbbffという色を指定しています。

 

この#と8つの英数字で指定する方法は、

【CSS】色指定 様々な方法(色名・RGB・HSLなど) - Little Strange Software

に書いたCSSでの色指定方法と同じもので、
「#bbbbbb(薄い灰色)という色を不透過度ff(最も不透過な状態=透過していないのと同じ状態)」
で表示するようにしています。

 

100%、グラデーションの終わり(一番外側)での色は、#bbbbbb00

これは「色は最初と同じ#bbbbbbのままだけど、不透過度00(最も透過した状態=完全に透明な色)」です。

 

これにより、「中央から外にいくにつれて、薄くなっていく雲」を表現するグラデーションになります^^

 

 

ここからアニメーションの話

SVGの場合、アニメーションに関する記述は「アニメーションさせたい対象のタグの内側」に書きます。

 

つまり、今回は<ellipse>タグで描いた雲を動かすので、

<ellipse cx="330" cy="100" rx="100" ry="30" fill="url(#rgc)">
 <animate
   id="anm1"
   attributename="cx"
   attributetype="XML"
   from="400"
   to="-100"
   begin="0s" dur="5s"
   repeatcount="indefinite"
   fill="remove">
  </animate>
</ellipse>

こんな風に<ellipse>と</ellipse>の間に書く事になります。

 

アニメーションの設定項目について、順に見ていくと、

 

id="anm1"
アニメーションにもid(名前)をつけます。
今回は別に他から呼び出したりしていませんで、任意の名前としてanm1としておきました。(任意の名前=好きに名付けてOK)


attributename="cx"
「アニメーションで変化させるものは何か?」を指定します。

今回は、楕円を横に移動させたいので、楕円の中心の横座標である「cx」を指定しました。


attributetype="XML"
ここは「XML」か「CSS」のどちらかを指定します。

今回変化させる対象として指定した「cx」はCSSプロパティではなく、SVGのプロパティなので、「XML」の方を指定します。(SVGXML形式の一種)


from="400"
アニメーション開始時の値を指定します。
今回の場合「最初の楕円の中心位置」ですね。
画面右端(x="300")よりも半径(r="100")分、右にずらした位置にしておいて、
「最初はギリギリ見えない右の位置」
から始まるようにしました。

 

to="-100"
アニメーション終了時の値を指定します。
今回の場合「最後の楕円の中心位置」ですね。
画面左端(x="0")よりも半径(r="100")分、左にずらした位置にしておいて、
「最後はギリギリ見えない左の位置」
から始まるようにしました。

この from と to の指定によって、
「画面右から徐々に表れて、画面を左に横切り、画面左に消えていく」
という雲の動きになります^^


begin="0s"
アニメーションが始まるまでの待ち時間を指定します。
待たなくていいので「0s(0秒)」を指定しています。

 

dur="5s"
一回のアニメーションにかける時間を指定します。
今回は「5s(5秒)」にしました。


repeatcount="indefinite"
アニメーションの繰り返し回数を指定します。
例えば「repeatcount="3"」と指定すると、3回だけアニメーションが再生されて止まります。
で、今回指定した「"indefinite"」だと無限繰り返しになります。

ここ、ちょっと引っ掛かりました。
CSSアニメーションにも同様の指定がありますが、
CSSの場合 infinite
SVGの場合 indefinite
と、似ているのに ちょっと違うスペルなんですね。
試しに英語での意味を調べてみると、infinite=無限、indefinite=不定、という意味だそうです。

  

fill="remove"

SVGでは fill は塗りつぶし…ですが、<animate>タグ内では違う意味になります。
ここで指定する候補は「freeze」か「remove」。
違いは「アニメーション終了後、そのままの状態にする(freeze)か、最初に戻す(remove)か」を指定します。
※今回は無限繰り返しなので意味が無かったですね^^;

 

 

あとがき

今回は、SVGアニメーションを試してみました。

…とはいっても、SVGアニメーションは他にも何種類かあるらしく、そのうち一番基本的なものを試しただけですが^^;

 

他の種類として、例えば

 

<animateTransform>
「拡大縮小・回転・傾き」などをアニメーションさせる
CSSでは今回のようなプロパティ変更と同列に扱われていましたが、SVGでは分けられてるんですね)

 

<animateMotion>
「パス(線)に沿って移動」するアニメーション
(パスの指定にベジェ曲線も指定できてしまうあたり、CSSには真似できない動きが作れそう)

 

…などがあり、それに加えてCSSアニメーションをSVGに適用する」なんて事もできるとか。 

 

中でも、<animateMotion>は試してみたいですね^^

 

 

 

ってなとこで、今回はこのへんで!

次回もまた、よろしくお願いします^^