本文へジャンプ

「Snap.svg」で、ぐにゃっとアニメーションさせてみた。

Posted by MONSTER DIVE

「Snap.svg」で、ぐにゃっとアニメーションさせてみた。

ふと気づくと、やってみたいなぁと思う演出は大抵「ぐにゃっ」としていまして、「私だってぐにゃっとさせたい」と言ったら、先日、kentaro先生がSVGを制御できるJSライブラリ・Snap.svgについての勉強会を開いてくれました。
今回はそれを受けて、Snap.svgについて簡単にまとめてみたいと思います。

Snap.svgとは

Snap.svgは、Adobeが提供しているオープンソースです。
Webブラウザ上でベクターデータが描画できるSVGの制御に特化したライブラリで、複雑なSVGタグの記述を簡略化して扱うことができる他、

  • パスの制御
  • フィルタ・マスク・クリッピング処理
  • アニメーション機能

等、様々な機能が提供されています。

用意されているメソッドもjQueryと似ていて、取り入れやすそうなところも良いですね。
今回使ってみたところ、少し重いかも?という印象はありましたが、やはりパスを制御できるというのはとても魅力的です。
そう、私はぐにゃっとさせたいのだから。

但し、もちろんSVGが使える環境(ブラウザ)での実装に限ります。

Snap.svgの使い方

公式サイトからはサンプルを含めたファイル一式、GitHubでは必要なファイルを選んでダウンロードすることができます。
実際読み込んで使用するのは、snap.svg-min.js(snap.svg.js)です。

ひとまず、基本的なSVGの表示から

  • 普通のタグはこちら
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="60" height="60" viewBox="0 0 60 60">
<circle cx="30" cy="30" r="30" fill="#F00"></circle>
</svg>

  • Snap.svgを使った記述はこちら
<svg id="hoge" style="width:60px;height:60px;"></svg>
<script src="js/snap.svg-min.js"></script>
<script>
Snap("#hoge").circle(30, 30, 30).attr({fill:"#F00"});
</script>

同じ結果ですが、Snap.svgを使うと、これだけの記述で済んでしまいます。
JSライブラリさえ読み込んでしまえばたったの1行。

なお、Snap(width, height)で要素の幅、高さを入れますが、「Snap('#hoge')」として#hogeを持つ空のSVGタグをbody内に入れ、CSSで#hogeのwidthとheightを指定しても同じことになります。

ちなみに、Snap.svgからはこのようなタグが生み出されていました。

<svg height="60" version="1.1" width="60" xmlns="http://www.w3.org/2000/svg">
<desc>Created with Snap</desc>
<defs></defs>
<circle cx="30" cy="30" r="30" fill="#ff0000"></circle>
</svg>

desc=descriptionが入るようですね。

それではいよいよパスを制御

2つのSVG画像(パス)を用意して、それを行き来させる...所謂モーフィングです。
今回、SVG画像をイラストレーターで作成しましたが、path要素でのアニメーションにしますので、SVGのタグがcircleやrectにならないよう、オブジェクトは「複合パスを作成」としてからSVG形式で保存しました。
※Snap.svgで定義して制御しますので、必要なのはpathタグの中の「d=」からのコードになります。

<script>
// アニメーション前のパス
var pFrom = 'M110,60c0,27.6-22.4,50-50,50c-27.6,0-50-22.4-50-50c0-27.6,22.4-50,50-50c13.8,0,26.3,5.6,35.4,14.6C104.4,33.7,110,46.2,110,60z';
// アニメーション後のパス
var pTo = 'M110,60c0,27.6-22.4,50-50,50c-27.6,0-50-22.4-50-50c0-27.6,22.4-50,50-50c13.8,0,13.1,18.8,22.2,27.8C91.2,46.9,110,46.2,110,60z';

var duration = 1000; // アニメーション時間
var easing = mina.easein; // Snap.svgで定義されているイージング関数

var s = Snap('#hoge'); // Snap.svgを定義
var isCir = false; // フラグを用意

var path = s.path(pFrom).attr({fill: '#e4007f'});

s.click(function () {
if (!isCir) {
path.animate({path: pTo}, duration, easing);
isCir = true;
} else {
path.animate({path: pFrom}, duration, easing);
isCir = false;
}
});
</script>

Written by Kentaro.Otsuka

※要素をクリックするとアニメーションします。

位置情報を持ったひとつひとつのパスからパスへのアニメーションとなるため、どうやらアニメーションさせるそれぞれの要素のパス数は合わせたほうが美しい動きになるようです。
単純な丸や四角でも、アニメーション前後の形に合わせてパスを追加しておきましょう。

ぐにゃっとさせてみる

1年前に作ったこちらを少しアレンジしてみました。
登場人物の年齢設定を知ると一通り複雑な気分になるでお馴染み、某国民的アニメのエンディングをモチーフに。
※ぐにゃっとする要素以外の動きはCSSアニメーションを使っていますので、IE9でご覧の方はごめんなさい。ぐにゃっとはすると思います。

サンプルはこちら

ぐにゃっとさせてみたかったんです。これを。

まとめ

個人的な事情としてJSという高いハードルはあるものの、SVGを簡単な記述で効果的に動かせるというのはやはり魅力的です。
単純な拡大縮小や回転はもはやCSS3でできますが、端末の解像度もどんどん上がっていっている昨今、Snap.svgを使って「ぐにゃっ」だの「どろ〜〜」だのをSVGで自由に表現できたら面白いコンテンツが実現できそうですね。

Recent Entries
MD EVENT REPORT
What's Hot?