Illustratorから書き出したSVGをjQueryとVelocity.jsでアニメーション

## 更新 Firefox　での動作について 2016.9.29

こちらで紹介している方法が、Firefoxで安定して動かないようでobjectタグでsvgを読み込むのではなく、直接svgタグを埋め込むことによって期待する動きに**近づき**ました。

Firefoxでも動いている例は[こちら](http://webya.in/w2/)

現時点ではこれだという決定打を出せていないので、解決次第、再度更新します。

## 概要・経緯

タイトルの通り、Illustratorから書き出したSVGをVelocity.jsで動かします。件の経緯として、運営しているサイトのロゴを動くものにしたかったのでやってみたよ


## 環境、バージョン

* Mac OS X El Capitan
* Adobe Illustrator CC
* jQuery 3.1.0
* Velocity.js 1.3.0


## DEMO

[Demoはここからどうぞ。](http://webya.in/qiita/svg/index.html)

## 今回用意したベクター

とりあえず適当なオーナメントを用意してみた。

![スクリーンショット 2016-09-23 1.49.10.png](https://qiita-image-store.s3.amazonaws.com/0/9988/54e0d407-b7a4-cddc-3db9-504fac057a37.png)

ちなみにこのオーナメントは、今進めてるリニューアルのデザイン上ではこんな感じでつかってます（下の方にちょろっと）。

![footer_logo.png](https://qiita-image-store.s3.amazonaws.com/0/9988/d0589eeb-27b1-3868-7372-66841ba1319c.png)

今回はこのオーナメントだけをアニメーションさせるよ

### SVGに吐き出す

「ファイル」から、「保存(もしくは別名で保存)」を選択します

![スクリーンショット 2016-09-23 1.49.38.png](https://qiita-image-store.s3.amazonaws.com/0/9988/9bfd9ba7-3c31-6b89-f854-894cc36ecd76.png)

次に、保存の形式を「SVG」を選択

![スクリーンショット 2016-09-23 1.49.59.png](https://qiita-image-store.s3.amazonaws.com/0/9988/b4b8e027-be51-7d79-6294-d396339fc2b4.png)

こんな感じで

![スクリーンショット 2016-09-23 1.51.06.png](https://qiita-image-store.s3.amazonaws.com/0/9988/8398009d-4913-c3ad-124d-b89233387eaa.png)

このウィンドウで「保存」をクリックすると、各種設定画面がでます。今回は以下のように設定しています。（）

![スクリーンショット 2016-09-23 1.52.42.png](https://qiita-image-store.s3.amazonaws.com/0/9988/96d2b6e1-ec21-eeea-012d-8849dc1a94a2.png)

「OK」を押せばSVGファイルの出来上がりです。

![スクリーンショット 2016-09-23 2.16.44.png](https://qiita-image-store.s3.amazonaws.com/0/9988/e84ce1e8-1835-7c9b-d661-02d4759a37a0.png)


エディタで開いてみるとこんな感じに。

```xml:ornament.svg
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 20.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 398 398" style="enable-background:new 0 0 398 398;" xml:space="preserve">
<style type="text/css">
	.st0{fill-rule:evenodd;clip-rule:evenodd;fill:none;stroke:#000000;stroke-miterlimit:10;}
</style>
<path class="st0" d="M42.3,302.4c65.6-26.5,148.4-97.8,176.6-129.5l-1.1-1.1C142.4,223,77.9,252.9,49.2,249.5
	c4.6-18.4,6.9-39.1,9.2-52.9c89.7,0,155.3-42.6,173.7-61l-1.1-1.1c-49.5,17.3-124.2,25.4-165.6,18.5c5.8-19.5,6.9-43.7,8.1-56.4
	c108.1,34.5,170.2,13.7,208.2-1.2c-6.9-13.8-5.7-33.3,8.1-47.1c17.3-17.3,44.9-17.3,61-1.2c17.3,17.3,17.2,44.9,0,62.1
	c-13.8,13.8-33.4,15-47.1,8.1c-15,38-35.7,100.1-1.2,208.2c-12.6,1.2-36.8,2.3-56.4,8.1c-8-42.6,1.2-116.2,18.5-165.6l-1.1-1.1
	c-18.4,18.4-61,84-61,173.7c-13.8,2.3-34.5,4.6-52.9,9.2c-3.4-28.8,26.5-93.2,77.7-168.5l-1.2-1.2c-31.6,28.2-103,111-129.4,176.6
	c-14.9,1.2-43.7,4.6-65.6,10.4C36.5,344.9,41.1,317.3,42.3,302.4z"/>
</svg>

```

xml宣言、コメント、styleタグを消し、idとクラス名を変えたものがこちら。消したスタイルはpathに突っ込んだ。単一のパスならばこれでおっけい。もし、モヤッとするならば最低でも以下のことはやったほうが良いかも

* xml宣言は消す（HTMLに埋め込む）
* svgタグに日本語で定義されてしまったidを英語に

```xml:ornament.svg
<svg version="1.1" id="ornament" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px"
	 y="0px" viewBox="0 0 398 398" style="enable-background:new 0 0 398 398;" xml:space="preserve">
<path class="ornamentPath" d="M42.3,302.4c65.6-26.5,148.4-97.8,176.6-129.5l-1.1-1.1C142.4,223,77.9,252.9,49.2,249.5
	c4.6-18.4,6.9-39.1,9.2-52.9c89.7,0,155.3-42.6,173.7-61l-1.1-1.1c-49.5,17.3-124.2,25.4-165.6,18.5c5.8-19.5,6.9-43.7,8.1-56.4
	c108.1,34.5,170.2,13.7,208.2-1.2c-6.9-13.8-5.7-33.3,8.1-47.1c17.3-17.3,44.9-17.3,61-1.2c17.3,17.3,17.2,44.9,0,62.1
	c-13.8,13.8-33.4,15-47.1,8.1c-15,38-35.7,100.1-1.2,208.2c-12.6,1.2-36.8,2.3-56.4,8.1c-8-42.6,1.2-116.2,18.5-165.6l-1.1-1.1
	c-18.4,18.4-61,84-61,173.7c-13.8,2.3-34.5,4.6-52.9,9.2c-3.4-28.8,26.5-93.2,77.7-168.5l-1.2-1.2c-31.6,28.2-103,111-129.4,176.6
	c-14.9,1.2-43.7,4.6-65.6,10.4C36.5,344.9,41.1,317.3,42.3,302.4z" style="fill-rule:evenodd;clip-rule:evenodd;fill:none;stroke:#000000;stroke-miterlimit:10;"/>
</svg>
```

## HTMLに埋め込む

今回は、objectタグを使ってみます。HTMLの用意の仕方は各々てきとーにどうぞ。

```html
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8">
    <title>svg sample</title>
  </head>
  <body>
    <div id="svg_area">
      <object id="svg_ornament" data="images/ornament.svg" type="image/svg+xml"></object>
    </div>
  </body>
</html>
```

これをブラウザで表示するとひたすらでかいsvgが表示されるはず。

![スクリーンショット 2016-09-23 2.35.36.png](https://qiita-image-store.s3.amazonaws.com/0/9988/9ae8d6f9-0933-feaf-0cd0-fb95e82b4070.png)


## JSとCSSを用意

現時点でCSSは空っぽ。

```html
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8">
    <title>svg sample</title>
    <link rel="stylesheet" href="css/index.css">
    <script src="https://code.jquery.com/jquery-3.1.0.min.js"></script>
    <script src="js/Velocity.js"></script>
    <script src="js/design.js"></script>
  </head>
  <body>
    <div id="svg_area">
      <object id="svg_ornament" data="images/ornament.svg" type="image/svg+xml"></object>
    </div>
  </body>
</html>
```

とりあえずobjectタグの高さを120pxくらいにします。

```css
#svg_ornament {
  height: 120px;
}
```

ちょっと不安なくらい大きかったのが随分としおらしくなった

![スクリーンショット 2016-09-23 2.47.06.png](https://qiita-image-store.s3.amazonaws.com/0/9988/37eb4cf6-dfbe-d946-3504-c2f41cb0e9ea.png)

続いてJS。このコードは [velocity.jsでぐにゃぐにゃSVGを描く](http://qiita.com/nekoneko-wanwan/items/f7bd86e41439aeaac33f)を参考にした。

```js:design.js

(function($){
  var SvgUtil = {
    addStyle: function(paths, color, fill, strokeWidth)
    {
      paths.each(function(){
        // getTotalLength はパスの長さを取得することができる。
        // + 30 は firefox 対策だそうです
        // 参考：velocity.jsでぐにゃぐにゃSVGを描く　http://qiita.com/nekoneko-wanwan/items/f7bd86e41439aeaac33f
        var path_length = $(this)[0].getTotalLength() + 30;
        $(this).css({
          'strokeDasharray': path_length,
          'strokeDashoffset': path_length,
          'stroke': color,
          'fill': fill,
          'strokeWidth': strokeWidth
        });
      });
    }
  };

  $(window).on('load', function() {
      var contentDocument   = document.getElementById('svg_ornament').contentDocument;
      var paths = $(contentDocument).find(".ornamentPath");

      SvgUtil.addStyle(paths, '#584044', 'none', 1);
      paths
           .velocity({ strokeDashoffset : 0 }, 1000 , "linear")
           .velocity({ fill: "#584044" }, 1000 , "linear");
  });
}(jQuery));

```

velocityについての詳しいことは会社にいるベロシティおじさんにでも聞いてください。また、`strokeDasharray`と`strokeDashoffset`についても会社のCSSおじさんにでも聞いてください

これで上記で示した[DEMO](http://webya.in/qiita/svg/index.html)の状態にはなります。

## リンクを貼る

このsvgにリンクを貼ってみた

```html
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8">
    <title>svg sample</title>
    <link rel="stylesheet" href="css/index.css">
    <script src="https://code.jquery.com/jquery-3.1.0.min.js"></script>
    <script src="js/Velocity.js"></script>
    <script src="js/design.js"></script>
  </head>
  <body>
    <div id="svg_area">
      <a class="svg_link" href="http://webya.in">
        <object id="svg_ornament" data="images/ornament.svg" type="image/svg+xml"></object>
      </a>
    </div>
  </body>
</html>
```

当然動かないわけです。動かないんだけど、CSSであっさり解決。aタグをブロック系の要素にし、オブジェクトタグに`pointer-events: none` を設定するとよい。（参考：[Retina対応にSVGを使う方法とリンクを張る時の注意点](http://dresscording.com/blog/svg/retina_svg.html)）

```css:index.css
#svg_ornament {
  height: 120px;
  pointer-events: none;
}
.svg_link {
  display: inline-block
}
```

参考にした記事を丸パクリした感じになっちゃったけど、jsの`addStyle`辺りは再利用出来るようにしてみた。なんか久々にフロントやってて知らないことが多かった（とくにCSSまわり）ので勉強になりましたよっと。以上、SVGでモテモテ講座でした。