Snap.svgでsvgのパスを動かしたアニメーションを作ってみた

はやち


Snap.svgでsvgのパスを動かしたアニメーションを作ってみた

どうもですよ、はやちですよ( ˇωˇ)
今回はsvgのアニメーションの操作がカンタンにできるSnap.svgをご紹介致します( ˘ω˘)☞三☞シュッシュッ

▼目次

導入方法

さっそく、導入からご紹介いたします。まず、こちらのサイト(↓)からダウンロードします。
snap.svg

ダウンロードしたら、snap.svg-min.jsを読み込みます。

<script src="snap.svg-min.js"></script>

 

タスクランナーでのご使用の方
npmでも公開されています。
https://www.npmjs.com/package/snapsvg
npm install snapsvg でインストールまたは
bower install snap.svg でインストールします。

 

使用するjsに読み込ませたら準備完了です( ˇωˇ)☝

import snapsvg from 'snapsvg'

使用方法(口を動かしてみる)

次に、使用方法をご紹介いたします( ˇωˇ )

svgを用意する

svgを用意します( ˇωˇ)☝ いつものこいつを使います。

スクリーンショット 2017-02-26 20.03.33

動かしたい箇所だけ、js-svg-mouthにidをふります。

<svg id="js-svg" class="svg-body" xmlns="http://www.w3.org/2000/svg" x="0px"
     y="0px" viewBox="0 0 96.9 97.6">
//くちの部分
<path id="js-svg-mouth" d="M37.9,61.4c-3.8-0.2-7.1-1.6-9.9-4.2c-0.8-0.7-1.5-1.7-0.5-2.7c0.8-0.8,1.7-0.4,2.5,0.1c2.5,1.8,5.1,2.9,7.7,3.1c2.6,0.2,5.2-0.6,7.8-2.6c0.7-0.6,1.7-0.9,2.5,0c0.7,0.9,0.1,1.7-0.6,2.4C44.7,60,41.6,61.4,37.9,61.4z"/>
<path d="M75,35.4c0.1,1-0.2,1.8-1.1,1.8c-2.4,0-3.2-1.9-4-3.8c-0.3-0.8,0.1-1.7,0.9-1.7C73.2,31.9,74.1,33.9,75,35.4z"/>
<path d="M55.4,33.5c-5.2,0-9.2,5.2-9.1,12c0.1,6.1,3.8,10.2,9.2,10.2c5.8,0,10-5,9.9-11.8C65.4,38.4,60.7,33.5,55.4,33.5z
     M55.7,52.2c-3.8-0.1-5.7-2.3-5.7-6.7c-0.1-5,2.3-8.6,5.6-8.6c3.5,0,6.3,3.2,6.4,7.4C61.9,49.4,59.7,52.2,55.7,52.2z"/>
<path d="M20,33.8c-5.8-0.1-10.2,4.5-10.2,10.5c0,6.6,4.3,11.4,10,11.4c5.6-0.1,9.1-4.1,9.1-10.4C28.9,38.2,25.6,33.9,20,33.8z
     M19.3,52.2c-3.8,0-5.9-2.8-6-7.6c0-4.4,2.8-7.7,6.7-7.6c3.3,0.1,5.1,2.9,5.2,7.8C25.3,49.8,23.3,52.2,19.3,52.2z"/>
<path d="M56.7,46.5c-0.4,0.5-1,0.7-1.4,0.3c-1.1-1.2-0.6-2.5-0.1-3.7c0.2-0.5,0.9-0.8,1.3-0.3C57.6,43.9,57,45.3,56.7,46.5z"/>
<path d="M20.1,46.5c-0.4,0.5-1,0.7-1.4,0.3c-1.1-1.2-0.6-2.5-0.1-3.7c0.2-0.5,0.9-0.8,1.3-0.3C20.9,43.9,20.4,45.3,20.1,46.5z"/>
<circle class="st0" cx="48.4" cy="48.9" r="45.7"/>
</svg>

pathを用意する

動かしたい部分のpathを用意します。通常の口の形と変形した時の口の形。

おくち

//変形前↓
<path id="js-svg-mouth" d="M37.9,61.4c-3.8-0.2-7.1-1.6-9.9-4.2c-0.8-0.7-1.5-1.7-0.5-2.7c0.8-0.8,1.7-0.4,2.5,0.1c2.5,1.8,5.1,2.9,7.7,3.1c2.6,0.2,5.2-0.6,7.8-2.6c0.7-0.6,1.7-0.9,2.5,0c0.7,0.9,0.1,1.7-0.6,2.4C44.7,60,41.6,61.4,37.9,61.4z"/>

//変形後↓
<path id="js-svg-mouth" d="M36.9,57.4c-3.8-0.2-6.1,2.4-8.9-0.2c-0.8-0.7-1.5-1.7-0.5-2.7c0.8-0.8,1.7-0.4,2.5,0.1c2.5,1.8,4.1-1.1,6.7-0.9c2.6,0.2,6.2,3.4,8.8,1.4c0.7-0.6,1.7-0.9,2.5,0c0.7,0.9,0.1,1.7-0.6,2.4C44.7,60,40.6,57.4,36.9,57.4z"/>

実装

変数の定義

pathは変数でpathStartとpathEndの中に定義をしておきます。

let $svg = $('#js-svg'), //全体を定義
    $svgMouth = Snap('#js-svg-mouth'), //動かしたい場所を定義
    pathStart = 'M37.9,61.4c-3.8-0.2-7.1-1.6-9.9-4.2c-0.8-0.7-1.5-1.7-0.5-2.7c0.8-0.8,1.7-0.4,2.5,0.1c2.5,1.8,5.1,2.9,7.7,3.1c2.6,0.2,5.2-0.6,7.8-2.6c0.7-0.6,1.7-0.9,2.5,0c0.7,0.9,0.1,1.7-0.6,2.4C44.7,60,41.6,61.4,37.9,61.4z', //戻した時のpath
    pathEnd ='M36.9,57.4c-3.8-0.2-6.1,2.4-8.9-0.2c-0.8-0.7-1.5-1.7-0.5-2.7c0.8-0.8,1.7-0.4,2.5,0.1c2.5,1.8,4.1-1.1,6.7-0.9c2.6,0.2,6.2,3.4,8.8,1.4c0.7-0.6,1.7-0.9,2.5,0c0.7,0.9,0.1,1.7-0.6,2.4C44.7,60,40.6,57.4,36.9,57.4z', //動かした後のpath
    SPEED = 100, //動く速さ,
    EASING = mina.easeout; //snap.svgに用意されているeasing

アニメーション

クリックしたら口が動く仕様にしました( ˇωˇ)☝
svgのアニメーションは、snap.svgのanimateメソッドを使用して動かします。

//クリッックイベント
$svg.on('click',(e) =>{
  
  //is-activeが付いてるときremoveして元のpathに戻す
  if($(e.currentTarget).hasClass('is-active')){
   $(e.currentTarget).removeClass('is-active');
   $svgMouth.animate({d:pathStart},SPEED,EASING);
  } 
  
  //is-activeが付いてるなかった時is-activeつけてpathを動かす
  else {
    $(e.currentTarget).addClass('is-active');
    $svgMouth.animate({d:pathEnd},SPEED,EASING);
  }
  
});

 

できあがったものはこちらになります( ˘ω˘)☞三☞シュッシュッ

svgをクリックしてみてくだされ↓

使用方法(体をむにむに動かしてみる)

次に、svgの身体がずっとむにむに動き続けているアニメーションの実装の仕方をご紹介します( ˇωˇ )

svgのパスを用意する

より滑らかに動かしたいので、pathを四種類用意しました( ˇωˇ)☝

むにむに

//1つめ
<path class="st0" id="js-svg-body" d="M48.4,3.2c25.2,0.1,45.7,20.5,45.7,45.7S73.6,94.6,48.4,94.6S2.7,74.1,2.7,48.9S23.2,3.1,48.4,3.2z"/>

//2つめ
<path class="st0" id="js-svg-body" d="M48.5,10.8C70.8-1.1,94.1,23.7,94.1,48.9S82.9,62,46.3,83.1c-21.4,11.4-44.8-9-43.6-34.2C3.8,25.6,29.3,20.9,48.5,10.8z"/>

//3つめ
<path class="st0" id="js-svg-body" d="M48.3,11.5c25.2,0.1,38.4,9.3,38.4,34.5S75,69.8,48.3,88.2C27.6,102.6,4.2,69.8,4.2,44.6S23.2,11.4,48.3,11.5z"/>

//4つめ
<path class="st0" id="js-svg-body" d="M48.3,5.2C73.6,5.4,86.8,20.8,86.8,46S73.6,88.2,48.3,88.2S4.2,85.7,4.2,60.5S23.2,5.1,48.3,5.2z"/>

実装

変数の定義

先ほどのpathたちは配列で管理します( ˇωˇ)☝

let $svgBody = Snap('#js-svg-body'), //動かしたいところを定義
    path =['M48.4,3.2c25.2,0.1,45.7,20.5,45.7,45.7S73.6,94.6,48.4,94.6S2.7,74.1,2.7,48.9S23.2,3.1,48.4,3.2z',
           'M48.5,10.8C70.8-1.1,94.1,23.7,94.1,48.9S82.9,62,46.3,83.1c-21.4,11.4-44.8-9-43.6-34.2C3.8,25.6,29.3,20.9,48.5,10.8z',
           'M48.3,11.5c25.2,0.1,38.4,9.3,38.4,34.5S75,69.8,48.3,88.2C27.6,102.6,4.2,69.8,4.2,44.6S23.2,11.4,48.3,11.5z',
           'M48.3,5.2C73.6,5.4,86.8,20.8,86.8,46S73.6,88.2,48.3,88.2S4.2,85.7,4.2,60.5S23.2,5.1,48.3,5.2z'], //変形されたpathを用意する
    SPEED = 500, //アニメーションのスピード調整
    EASING = mina.easein, //snap.svgに用意されているeasing
    i = 0; //最初にはじまるpathを定義

アニメーション

snap.svgのanimateメソッドでは、コールバックも使用できるので、AnimationSvg関数を再度呼んでアニメーションを繰り返しさせてます。

ついでに、pathの配列の順番の付け替えもその中で行って、実装をしました( ˇωˇ)☝

function AnimationSvg(){
  
  //パスを定義して1秒間動かした後にアニメーションが繰り返される
  $svgBody.animate({d: path[i] },SPEED,EASING,AnimationSvg);
  
  //pathの順番をつけかえ
  i++;
  
  //もしpathの付け替えで多くなってしまった時初めのかたちに戻る
  if(i === path.length){
    i = 0; //初めのpathに戻る
  }
}
//アニメーションスタート
AnimationSvg();

出来上がったアニメーションはこのようになります( ˘ω˘)☞三☞シュッシュッ

まとめ

いかがでしたか( ˇωˇ )
今回Snap.svgを使ってみて、animateメソッドがjQueryみたいに使いやすいなと思いました。

Snap.svgは、他にも実装できるものがあるので、色々試してみたいなと思っております( ˇωˇ )ではでは

はやち
この記事を書いた人
はやち

フロントエンドエンジニア

関連記事