【SMIL】SVGアニメーションでsvgのキャラ画像を動かそう!
この記事は最終更新から4年以上が経過しています。情報が古くなっている可能性があります。
前記事「【Illustrator】ラスタ画像からsvg画像を作る方法」に続いてsvg関連。
今度はsvgアニメーションを実装してみました。
svgアニメーションには、
- aminate要素(SMIL(スマイル))を用いる
- javascriptを用いる
- css3のアニメーションを用いる
この3つの方法があるそうです。
(1)に比べ、(2)、(3)のほうが高度なアニメーションが実装できるそうですが、今回は「わざわざjsやcssでアニメーションさせるほどじゃないけどちょっと動かしたいよね」という時に使える、SMILを用いたプチアニメをまとめました!
Contents
今回つくってみたもの
- 目をぱちぱち(aminate要素 path変化)
- ぴょんぴょんとジャンプ(animateTransform要素 並進(translate))
- 耳をぱたぱた(animateTransform要素 回転(rotate))
- (おまけ) ごろごろ回転移動(animateTransform要素 並進(translate), 回転(rotate))
下準備
全体に共通する方法として、まずアニメーションさせたいsvg画像を用意します。
*ラスタ画像をsvg画像化する方法については前記事で紹介しています。
次にsvg画像をブラウザ上で表示し、開発者ツールで動かしたい要素を特定します。
エディタでsvgのコードを開き、先ほど特定した動かしたい要素のタグを修正。
<!-- 修正前 -->
<path d="パスの中身"/>
<!-- 修正後 -->
<path d="パスの中身">
<animate>
</path><!-- 閉じタグを追加して、中にanimate要素等をいれる -->
このタグの中にSMIL言語のアニメーションを実装する要素を記載していきます。
今回はanimate要素もしくはanimateTransform要素を使います。
- SMIL…
- W3CがXMLをもとに規格化したマークアップ言語。SMILを利用することで、動画や音声、テキストなどの異なる形式のデータを、Webブラウザー上で同期をとって再生できる。animate要素やanimateTransform要素はこの言語の技術。
引用元)SMIL(すまいる)とは – コトバンク- animate要素…
- animate 要素は1個の属性/プロパティに対する時経過に伴うアニメーションに用いられる。
引用元)アニメーション – SVG 1.1 (第2版)- animateTransform要素…
- animateTransform 要素は対象要素の変換属性に対するアニメーションを行い、それによる並進, 拡縮, 回転, 斜傾などを制御するアニメーションを可能にする。
引用元)アニメーション – SVG 1.1 (第2版)
目をぱちぱち
こちらの記事をがっつり参考にさせていただきました。
変化前と変化後のパスを用意し、ぬるっとアニメーションさせる方法です。
- svg画像aと、目だけ細く変更したsvg画像bを用意
*このときアンカーの数を変えないように、とのこと。 - 画像bをブラウザで開き、どちらかの目の部分の要素を特定。Dから始まる文字列を控える
- 画像aをブラウザで開き、同じほうの目の部分の要素を特定。以下の形のコードに書き直す
<!-- 目のパスを特定 -->
<path fill="var(--color376, #201e18)" d="元のパス">
<animate attributeType="XML" attributeName="d" dur="5s" repeatCount="indefinite" values="元のパス; 変化後のパス; 元のパス"></animate>
</path>
完成!
目をぱちぱちする間隔は秒数とvalueの数で無理やり調整してみました。
See the Pen NyNdzb by BICOxxx (@BICOxxx) on CodePen.
ぴょんぴょんとジャンプ
今度はanimateTransform要素で並進させてジャンプのように見せます。
先ほどの瞬きと同じように秒数とvalueの数でそれっぽい動きにしてます。
1.画像をブラウザで開き、体全体のpathを特定。もしグルーピングするgタグがなければgで囲う。
<g><!-- ←gタグを追加 -->
<path fill="var(--color372, #fedc78)" d="Mxxx.xxx~"><!-- 体のパス -->
<path fill="var(--color372, #fedc78)" d="Mxxx.xxx~"><!-- 鼻のパス -->
<path fill="var(--color372, #fedc78)" d="Mxxx.xxx~"><!-- 目のパス -->
...(体を構成する全ての要素)
</g><!-- ←g閉じタグを追加 -->
2.このgタグの中に以下の形のコードを書き足す
<g>
<path fill="var(--color372, #fedc78)" d="Mxxx.xxx~">
<path fill="var(--color372, #fedc78)" d="Mxxx.xxx~">
<path fill="var(--color372, #fedc78)" d="Mxxx.xxx~">
<path fill="var(--color372, #fedc78)" d="Mxxx.xxx~">
<animateTransform xmlns="http://www.w3.org/2000/svg" attributeName="transform" attributeType="xml" type="translate" dur="6s" values="0 0;0 0;0 -3;0 -5;0 -6;0 -5;0 -3;0 0;0 -3;0 -5;0 -6;0 -5;0 -3;0 0;0 0" keyTimes="0;0.5;0.51;0.52;0.53;0.54;0.55;0.56;0.57;0.58;0.59;0.60;0.61;0.62;1" repeatCount="indefinite"/><!-- animateTransformを追加 -->
</g>
完成!
See the Pen pig jumping by BICOxxx (@BICOxxx) on CodePen.
耳をぱたぱた
次はanimateTransform要素の回転を使います。
耳のpathに対してアニメーションをかけていきます。
-
- 画像をブラウザで開き、耳のpathを特定。以下のコードに書き直す。
<!-- 左耳のパス -->
<path fill="var(--color374, #fec009)" d="Mxxx.xxx~">
<animatetransform attributetype="XML" attributename="transform" type="rotate" values="0,10,5;30,10,5;0,10,5" dur="2s" repeatcount="indefinite" additive="sum"/>
</path>
<!-- 右耳のパス -->
<path fill="var(--color375, #fec109)" d="M28.021 3.233c.834-.138 1.613.104 2.379.378 1.739.62 3.328 1.504 4.696 2.758.203.187.39.384.563.593l.008.01c1.286 1.562.956 3.066-.864 3.967l-.348.172c-.66-1.123-1.266-2.279-2.053-3.323-1.213-1.607-2.556-3.087-4.169-4.306-.078-.074-.148-.155-.208-.244l-.003-.005z">
<animatetransform attributetype="XML" attributename="transform" type="rotate" values="0,30,3;-30,30,3;0,30,3" dur="2s" repeatcount="indefinite" additive="sum"/>
</path>
完成!
See the Pen pig ear by BICOxxx (@BICOxxx) on CodePen.
ごろごろ回転移動
おまけ。animateTransform要素の並進と回転を合わせるとこんなこともできます。
See the Pen pig rolling by BICOxxx (@BICOxxx) on CodePen.
気になったところ
一定間隔を指定する方法
目の瞬きやジャンプを実装するときに調べましたが、「一定の時間をおいてアニメーションを実行」という命令はできなさそうです。
アナログで書くならこんな感じに。
<animate attributeType="XML" attributeName="d" dur="5s" repeatCount="indefinite" values="
元のパス;元のパス;元のパス;元のパス;元のパス;元のパス;
変化後のパス;
元のパス;
変化後のパス;
元のパス;元のパス
"></animate>
これだと、durに指定した5秒間で、valueに指定したパスが等間隔で表示されるので近い挙動になります。
こういう細かい動きはcssやjsでの領域になるのかもしれませんね。
ease等の滑らかな動きの再現方法
こちらは名称を使った設定こそできませんが、cssでのeaseといった名称がついている設定値を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.0 0.58 1.0 ease-in-out 0.42 0.0 0.58 1.0
引用元:svg要素の基本的な使い方まとめ > keySplines属性に設定する値について
まとめ
SMILはささやかなアニメーションであれば数行のコードで実装できるので、cssとjsとは違った用途に使えそうですね。
こちらの記事のような、がっつりとした変形アニメーションも面白そうです。
しかしこの記事を起こしてから知ったのですが、SMILは一度chromeで非推奨の動きがあったそうです。
chrome(blink)におけるSMILの非推奨警告の経緯
2015/7 chromeから非推奨の警告 公式記事
-
-
- Chrome 45 Beta版からSMILは非推奨、将来的には機能自体非対応になると発表
- SMILが設定されたSVGがページに表示されている場合、開発者ツールのコンソールに警告文を表示
-
2016/8 chromeから非推奨措置の保留
-
-
- 反対意見が多かったこと、まだcssのアニメーションではSMILの代替として十分でないとの理由で方針の保留を発表
-
参考)#35:SVGアイコン管理ツール、SMILの今後についてなど
2018/1現在、特に新しい発表はないようです。
こういうことがあったため、chromeで現在SMILが使えない訳ではありませんが、SMILの将来性が不安視されるため、cssやjsを主に使おうという意見が多いようです。
(*なおIE11・EdgeはそもそもSMIL非対応)
IE, MS Edgeでは依然としてSMILは非対応ですし(参考:Can I use)、もしも今後の仕様追加でCSS/Web Animationsで十分に代替できるようになれば再びSMILの見直しがされる可能性があります。
そういった点を鑑みて、可能であればアニメーションを設定する際にはSMILではなくJavaScript, CSS/Web Animationsで制作するのをお勧めします。
#35:SVGアイコン管理ツール、SMILの今後についてなど
SVG要素の一つであるanimateタグを使う。
SMIL(Synchronized Multimedia Integration Language)というらしい。
今後ブラウザがサポートしていくかどうか決定していないので非推奨。
SVGのアニメーション手段とその選び方
今回のSMILアニメーションは知識として頭にいれておき、
今後SVGアニメーションを実装する際はSMILではなくcss、js中心で組んでいこうと思います。
参考サイト
-
- SVGアニメーションで失敗したことを踏まえて丁寧に!動くロゴの作り方
- SVGでアニメーション(中編)
- svg要素の基本的な使い方まとめ