「Snap.svg」を使ってSVGをアニメーションしてみた

技術情報

Snap.svg – Home

JavaScriptでのSVGのアニメーションを楽にしてくれる「Snap.svg」というライブラリを知り、気になったので使ってみることにしました。

「Snap.svg」を導入する

トップページから「Snap.svg」をダウンロードして、「dist」フォルダにある「snap.svg-min.js」を使用します。

Downloadから「Snap.svg」をダウンロード
Downloadから「Snap.svg」をダウンロード

解凍して「dist」フォルダを開きます。

解凍して「dist」フォルダを開く

圧縮済みの「snap.svg-min.js」を使用します。

「snap.svg-min.js」を使用
「snap.svg-min.js」を使用

適当な名称のフォルダを作成し、「snap.svg-min.js」を入れて下記のような感じで読み込みます。

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

「Snap.svg」を使ってアニメーションをする

カメラのsvg画像をボタンをクリックした時にボタンとシャッターを変化させて元に戻すアニメーションを実装します。

カメラのsvg画像をアニメーション

svg画像は「icooon-mono」を利用しています。

サンプル

スクリプト

全体のスクリプトは下記にようになります。

window.onload = function() {

    // ボタンアニメーション前のパス
    var pathBtnStart = 'M 290.864 38.648 H 435.068 V 93.314 H 290.864 V 38.648 Z';
    // ボタンアニメーション後のパス
    var pathBtnEnd = 'M 290.864 68.648 H 435.068 V 93.314 H 290.864 V 38.648 Z';

   // シャッターアニメーション前のパス
    var pathShutterStart = 'M256.001,226.93c-35.532,0-64.438,28.904-64.438,64.436c0,35.53,28.906,64.434,64.438,64.434 c35.529,0,64.434-28.904,64.434-64.434C320.435,255.834,291.53,226.93,256.001,226.93z';
    // シャッターアニメーション後のパス
    var pathShutterEnd = 'M 255.228 281.429 L 191.563 291.366 L 256.001 304.393 L 320.435 291.366 L 255.228 281.429 Z';

    var duration = 2; // 時間
    var easing = mina.easein; // 動き

    var button = Snap('#button'); // ボタンを取得
    var shutter = Snap('#shutter'); // シャッターを取得

    var isButton = true; // 条件用

    button.click(function(){

      if (isButton) {

        button.animate({path: pathBtnEnd}, duration, easing);
        shutter.animate({path: pathShutterEnd}, duration, easing);

        setTimeout(function(){
          button.animate({path: pathBtnStart}, duration, easing);
          shutter.animate({path: pathShutterStart}, duration, easing);
        }, 400);

      } else {

        button.animate({path: pathBtnStart}, duration, easing);
        shutter.animate({path: pathShutterStart}, duration, easing);

      }

    });

}

ボタンとシャッターのアニメーションの前後のパスを変数にいれます。後のパスは事前に作成しておく必要があります。「Snap.svg」はanimateでアニメーションを行います。svgの作成や編集はChrome拡張の「Boxy SVG」が手軽でお勧めです。

// ボタンアニメーション前のパス
var pathBtnStart = 'M 290.864 38.648 H 435.068 V 93.314 H 290.864 V 38.648 Z';
// ボタンアニメーション後のパス
var pathBtnEnd = 'M 290.864 68.648 H 435.068 V 93.314 H 290.864 V 38.648 Z';

// シャッターアニメーション前のパス
var pathShutterStart = 'M256.001,226.93c-35.532,0-64.438,28.904-64.438,64.436c0,35.53,28.906,64.434,64.438,64.434 c35.529,0,64.434-28.904,64.434-64.434C320.435,255.834,291.53,226.93,256.001,226.93z';
// シャッターアニメーション後のパス
var pathShutterEnd = 'M 255.228 281.429 L 191.563 291.366 L 256.001 304.393 L 320.435 291.366 L 255.228 281.429 Z';

アニメーションにかかる時間と動きを設定します。

var duration = 2; // 時間
var easing = mina.easein; // 動き

アニメーションを用に記述するボタンとシャッターのidを取得します。条件用の変数の「isButton」を作成します。

var button = Snap('#button'); // ボタンを取得
var shutter = Snap('#shutter'); // シャッターを取得

var isButton = true; // 条件用

ボタンがクリックされた時にボタンとシャッターのパスを取得してアニメーションを行っています。

button.click(function(){

  if (isButton) {

    button.animate({path: pathBtnEnd}, duration, easing);
    shutter.animate({path: pathShutterEnd}, duration, easing);

    setTimeout(function(){
      button.animate({path: pathBtnStart}, duration, easing);
      shutter.animate({path: pathShutterStart}, duration, easing);
    }, 400);

  } else {

    button.animate({path: pathBtnStart}, duration, easing);
    shutter.animate({path: pathShutterStart}, duration, easing);

  }

});

「isButton」の時にボタンとシャッターの変更されたパスを表示しています。pathで各パスの状態を取得、durationはかかる時間、easingはmina.easeinとなっています。setTimeoutで変更される前の通常のボタンとシャッターの表示に戻しています。

button.animate({path: pathBtnEnd}, duration, easing);
shutter.animate({path: pathShutterEnd}, duration, easing);

setTimeout(function(){
  button.animate({path: pathBtnStart}, duration, easing);
  shutter.animate({path: pathShutterStart}, duration, easing);
}, 400);

「else」で「isButton」以外の時に通常のボタンとシャッターを表示しています。

button.animate({path: pathBtnStart}, duration, easing);
shutter.animate({path: pathShutterStart}, duration, easing);

css

fillでsvgのカラー、cursorでボタン部分のパスに対してアイコンをポインターに変えています。

.st0 {
  fill: #4B4B4B;
}

.btn {
  cursor: pointer;
}

svg

svgは下記のようになっています。

<svg style="width: 256px; height: 256px" viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg">
  <path id="button" class="st0 btn" d="M 290.864 38.648 H 435.068 V 93.314 H 290.864 V 38.648 Z"/>
  <path id="shutter" class="st0" d="M256.001,226.93c-35.532,0-64.438,28.904-64.438,64.436c0,35.53,28.906,64.434,64.438,64.434 c35.529,0,64.434-28.904,64.434-64.434C320.435,255.834,291.53,226.93,256.001,226.93z"/>
  <path class="st0" d="M440.599,114.603h-20.197H276.198H71.401C32.129,114.603,0,146.732,0,186.006v215.946
c0,39.27,32.129,71.401,71.401,71.401h369.198c39.272,0,71.401-32.131,71.401-71.401V186.006 C512,146.732,479.871,114.603,440.599,114.603z M88.817,241.732c-20.199,0-36.572-16.375-36.572-36.571
c0-20.199,16.373-36.574,36.572-36.574c20.197,0,36.57,16.375,36.57,36.574C125.387,225.357,109.014,241.732,88.817,241.732z
M256.001,392.374c-55.698,0-101.008-45.313-101.008-101.008s45.311-101.008,101.008-101.008 c55.694,0,101.006,45.312,101.006,101.008S311.695,392.374,256.001,392.374z"/>
</svg>

ボタンとシャッター部分にidを記述して、アニメーションに利用しています。

<path id="button" class="st0 btn" d="M 290.864 38.648 H 435.068 V 93.314 H 290.864 V 38.648 Z"/>
<path id="shutter" class="st0" d="M256.001,226.93c-35.532,0-64.438,28.904-64.438,64.436c0,35.53,28.906,64.434,64.438,64.434 c35.529,0,64.434-28.904,64.434-64.434C320.435,255.834,291.53,226.93,256.001,226.93z"/>

全体

サンプルページの全体となります。

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Snap.SVG</title>
<meta name="viewport" content="width=device-width,initial-scale=1" />
<script type="text/javascript" src="./snap.svg-min.js"></script>

<script>
window.onload = function() {

    // ボタンアニメーション前のパス
    var pathBtnStart = 'M 290.864 38.648 H 435.068 V 93.314 H 290.864 V 38.648 Z';
    // ボタンアニメーション後のパス
    var pathBtnEnd = 'M 290.864 68.648 H 435.068 V 93.314 H 290.864 V 38.648 Z';

   // シャッターアニメーション前のパス
    var pathShutterStart = 'M256.001,226.93c-35.532,0-64.438,28.904-64.438,64.436c0,35.53,28.906,64.434,64.438,64.434 c35.529,0,64.434-28.904,64.434-64.434C320.435,255.834,291.53,226.93,256.001,226.93z';
    // シャッターアニメーション後のパス
    var pathShutterEnd = 'M 255.228 281.429 L 191.563 291.366 L 256.001 304.393 L 320.435 291.366 L 255.228 281.429 Z';

    var duration = 2; // 時間
    var easing = mina.easein; // 動き

    var button = Snap('#button'); // ボタンを取得
    var shutter = Snap('#shutter'); // シャッターを取得

    var isButton = true; // 条件用

    button.click(function(){

      if (isButton) {

        button.animate({path: pathBtnEnd}, duration, easing);
        shutter.animate({path: pathShutterEnd}, duration, easing);

        setTimeout(function(){
          button.animate({path: pathBtnStart}, duration, easing);
          shutter.animate({path: pathShutterStart}, duration, easing);
        }, 400);

      } else {

        button.animate({path: pathBtnStart}, duration, easing);
        shutter.animate({path: pathShutterStart}, duration, easing);

      }

    });

}
</script>

<style type="text/css">
.st0 {
  fill: #4B4B4B;
}

.btn {
  cursor: pointer;
}
</style>

</head>
<body>

  <svg style="width: 256px; height: 256px" viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg">
    <path id="button" class="st0 btn" d="M 290.864 38.648 H 435.068 V 93.314 H 290.864 V 38.648 Z"/>
    <path id="shutter" class="st0" d="M256.001,226.93c-35.532,0-64.438,28.904-64.438,64.436c0,35.53,28.906,64.434,64.438,64.434 c35.529,0,64.434-28.904,64.434-64.434C320.435,255.834,291.53,226.93,256.001,226.93z"/>
    <path class="st0" d="M440.599,114.603h-20.197H276.198H71.401C32.129,114.603,0,146.732,0,186.006v215.946
    c0,39.27,32.129,71.401,71.401,71.401h369.198c39.272,0,71.401-32.131,71.401-71.401V186.006 C512,146.732,479.871,114.603,440.599,114.603z M88.817,241.732c-20.199,0-36.572-16.375-36.572-36.571
    c0-20.199,16.373-36.574,36.572-36.574c20.197,0,36.57,16.375,36.57,36.574C125.387,225.357,109.014,241.732,88.817,241.732z
    M256.001,392.374c-55.698,0-101.008-45.313-101.008-101.008s45.311-101.008,101.008-101.008 c55.694,0,101.006,45.312,101.006,101.008S311.695,392.374,256.001,392.374z"/>
  </svg>

</body>
</html>

まとめ

  • 「snap.svg-min.js」を読み込む。
  • svgの前と変更後のパスを用意する。
  • 各pathを変数に入れてanimateでアニメーションを行う。

「Snap.svg」は噂通りjQueryのような感じで手軽に使えるライブラリだと思います。気になった方は利用を検討してみてはいかがでしょうか。

スポンサーリンク
技術情報
スポンサーリンク
シェアする
ボヘミアンをフォローする
この記事が気に入ったら
いいね!しよう
最新情報をお届けします。
スポンサーリンク

コメント