LoginSignup
10
8

More than 5 years have passed since last update.

Snap.svgでsvgパスを動かそう! ①入門編

Posted at

概要

個人ポートフォリオサイト を作っている中で、何か シャレオツ な動きを入れたいなーと思いザッと調べてみたところ、SVGパスを動かすことができる Snap.svg というライブラリを見つけ、触り程度ですが動かしてみました。

Snap.svgとは?

jQueryライクでのSVG内のパス指定が可能で、サイズや色、さらにはアニメーションまで設定することが出来るライブラリです。

似たようなsvg操作用ライブラリ

  • Raphaël.js
    Snap.svgと同じ製作者のライブラリです。Snap.svgの前身のようなものなので、今から学ぶのであればSnap.svgで良いと思います。

  • SVG.js
    こちらもjQueryライクのSVG操作が可能です。こちらは、「The lightweight library for manipulating and animating SVG.」と言っている通り、SVGを操作したりアニメートさせたりするための軽量なJavaScriptライブラリとなっています。

  • BonsaiJS
    こちらはキーフレームアニメーションを設定することが可能なライブラリです。また、フィルター処理やモーフィングも可能とのことです。

使い方

完成例

今回は非常にシンプルな以下のようなアニメーションを実現してみます。

snap.gif

SVGファイルはこんな感じです。

logo.svg
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 21.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
<svg version="1.1" id="レイヤー_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px"
     y="0px" viewBox="0 0 184.3 184.3" style="enable-background:new 0 0 184.3 184.3;" xml:space="preserve">
<g id="all">
    <g id="back">
        <polygon id="box" points="4.9,44.8 4.9,140.8 93.3,182 179.8,139 179.8,44.8 92.4,2.3         "/>
    </g>
    <g id="front">
        <g id="colors">
            <polygon id="blue" points="10.9,52.4 10.6,90.9 10.9,136.1 9.4,137 89.9,173.9 89.9,90.9          "/>
            <polygon id="green" points="174.7,50.6 95.7,90.6 95.1,90.2 94.9,90.9 94.9,173.9 174.7,135.9 174.9,90.9          "/>
            <polygon id="red" points="169.5,45.9 92.4,8.5 15.1,45.9 10.9,45.9 92.4,85.1 173.7,45.9          "/>
        </g>
    </g>
    <g id="frames">
        <path id="frame" d="M92.4,2.3L4.9,44.8v96L93.3,182l86.5-43V44.8L92.4,2.3z M53.9,157v-27.4l-5-3.1v28.2l-38-17.7V52.5l38,18.5
            v24.4l5,2.9V73.4l36,17.5v24.4l-18.8,7.4L89.9,142v31.7L53.9,157z M92.4,85.2L14.2,47L92.4,9l78,38l-18.2,8.9h-42l9.9,15.8
            L92.4,85.2z M139.9,152v-26.3l-5.5,3.7l0.4,25.1l-39,19V90.9l78-39.4v45.7l-23.5,12.1l23.5,14.2v12L139.9,152z"/>
        <polygon id="red_box_under" points="47.5,57.3 69.9,68.2 91.4,57.3 69.4,46.8         "/>
        <polygon id="red_box_over" points="91.5,35.8 113.9,46.8 135.4,35.8 113.4,25.3       "/>
        <polygon id="green_box_over" points="131.1,111.4 153.3,100.1 152.5,76.4 130.9,87.6      "/>
    </g>
</g>
</svg>

手順

ダウンロード

公式 から最新のZipをダウンロードします。

読み込み

snap.svg-min.jsファイルを読み込みます。

screencapture- 2017-12-13 23.16.27.png

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

流し込むタグを用意

以下のsvgタグに挿入します。

index.html
・・・
<script type="text/javascript" src="snap.svg-min.js"></script>
・・・
<div>
  <img>
    <svg id="target"></svg>
  </img>
</div>
・・・

JavaScriptの実装

最終的にこんな感じ

animate.js
jQuery(document)
    .ready(
        function() 
        {
            var snap = Snap("#target"); //流し込み対象のDOMを取得
            var grop = snap.group(); //Groupの作成

            Snap.load("logo.svg", function(data) //SVGファイルを読み込んでコールバック関数で処理
                      {
              grop.append(data); //データをDOMに追加

              var all = Snap.select("#all"); //一番外側のグループを取得
              var allBbox = all.getBBox(); //描画領域の短形範囲を取得
              var box = Snap.select("#box"); //最初に表示する黒背景の6角形パスを取得(途中で縮小)
              var frames = Snap.select("#frames"); //後から表示する黒枠フレームのパスを取得(途中で拡大)
              var red = Snap.select("#red"); //赤エリアのパスを取得(途中で拡大)
              var blue = Snap.select("#blue"); //青エリアのパスを取得(途中で拡大)
              var green = Snap.select("#green"); //緑エリアのパスを取得(途中で拡大)

              box.transform("s0"); //初期非表示化
              frames.transform("s0"); //初期非表示化
              red.transform("s0"); //初期非表示化
              blue.transform("s0"); //初期非表示化
              green.transform("s0"); //初期非表示化

              var redFunc = function() //赤エリアのパスのアニメーション定義
              {
                red.animate({
                  transform: 's1',
                  fill: "#FF0000"
                }, 3000, mina.bounce)
              };

              var blueFunc = function() //青エリアのパスのアニメーション定義
              {
                blue.animate({
                  transform: 's1',
                  fill: "#0000FF"
                }, 3000, mina.bounce)
              };

              var greenFunc = function() //緑エリアのパスのアニメーション定義
              {
                green.animate({
                  transform: 's1',
                  fill: "#39B44A"
                }, 3000, mina.bounce)
              };

              var colorsFunc = function() //赤,青,緑エリアのパスのアニメーションの順番定義
              {
                redFunc();
                setTimeout(function() {
                  blueFunc();
                  setTimeout(function() {
                    greenFunc();
                  }, 500);
                }, 500);
              }

              var boxFunc = function() //全体的なアニメーションの順番定義
              {
                box.animate({ 
                  transform: 's1' 
                }, 2000, mina.bounce, function() {
                  colorsFunc();
                  frames.transform("s1");
                })
              };

              boxFunc(); //実行
            }
       });
    );

わからないこと

  • animate関数の第一引数のtransformに指定する値のルールがいまいち理解出来ていない。
  • もっとダイナミックに動かす方法
  • パスのモーフィング出来る?

この辺はまた機会があれば別記事にてまとめようと思います!

10
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
8