mo.js -DOM Animation with SVG-

# SVGパスを使ったアニメーションライブラリ
 
mo.jsは非jQuery依存のシンプルなアニメーションライブラリです。http://mojs.io/
[公式デモ](http://codepen.io/sol0mka/full/yNOage/)がかなり軽量に動いていたので試しに触ってみました。
svgのパスを元にstyleをガシガシ書き換えてつくり込む感じ。


APIは公式を見ればあんまり説明必要なさそうだったので、webpack+babelでやってみたらこうなった、というコードを乗せておきます。凝った動きを作りこむためには沢山svgを用意しパスをゴネゴネする必要がありそうだったので、svgはsvg-inline-loaderで読み込み、GUIで演出に集中できる様にするのがゴールです。  

```webpack.config.js
loaders: [
      { test: /\.js$/, loaders: ['babel-loader'], exclude: /node_modules/ },
      { test: /\.svg$/, loader: 'svg-inline'}
    ]
```

こんな感じのsvgを用意しておきます。サイズは100px_100px。
バウンスのイージング曲線ですね。  
![animatePath.png](https://qiita-image-store.s3.amazonaws.com/0/59071/cd7f3fe9-aa87-9063-8500-c3a9a3d07638.png)

円を10個動かして何かしようとしてみました。

```script.js
import Circles from './circles';
new Circles('.circles',10).run();
```

せっかくの非jQuery依存なので、querySelectorとDOMParserで、importしたsvgからpath要素のd属性を拾います。そのd属性からTweenに渡すeasing関数を生成します。これでわざわざd属性をコピペしなくて済む様になりました。

```circles.js
import mojs from 'mo-js';
import Circle from './circle';
import AnimatePath from '../svg/animatePath.svg';

export default class Circles {
  constructor(selector, count) {
    this.circles = [];
    const dom = document.querySelector(selector);
    const svg = new DOMParser().parseFromString(AnimatePath,'text/xml');
    const d = svg.querySelector('path').getAttribute('d');
    const easing = mojs.easing.path(d);
    for (let i=0; i<count; i++) {
      const c = new Circle(easing,i);
      dom.appendChild(c.dom);
      this.circles.push(c);
    }
    return this;
  }
  run() {
    for (let i=0; i<this.circles.length; i++) {
      this.circles[i].run();
    }
    return this;
  }
}


```

せっかくのbabelなので、OOPに寄せていければいいなと。今のとこmojs.Tweenのoptionがかなり少ないので、setTimeoutでdelayを追加してみた。（今入っているoptionのdelayはアニメーションリピートのインターバルを指してる）公式のAPIsが非リンクだったので、まだこれからいろいろ実装するものだと思われる。

```circle.js
import mojs from 'mo-js';

export default class Circle {
  constructor(easing,x) {
    let div = document.createElement('div');
    div.setAttribute('class', 'circle');
    div.setAttribute('data-css-hide', 'true');
    this.dom = div;
    this.easing = easing;
    this.x = x;
    return this;
  }
  run() {
    setTimeout(() => {
      new mojs.Tween({
        repeat: 99999,
        delay: 0,
        duration: 2000,
        onUpdate: (progress) => {
          let value = this.easing(progress);
          this.dom.style.transform =
          `translateX(${20*this.x-100}px)
           translateY(${(1-value)*100}px)
           scale(${value})`;
        }
      }).run();
      this.dom.setAttribute('data-css-hide', 'false');
    }, this.x*30);
    return this;
  }
};

```

用意したstyleはこんな感じ。

```style.styl
@import 'nib';
global-reset();

.container {
  width: 100%;
  height: 100%;
  position: fixed;
  overflow: hidden;
}

.circles {
  top: 50%;
  left: 50%;
  position: fixed;
}

.circle {
  size = 10px;
  width: size;
  height: size;
  position: absolute;
  margin-left: @width*-.5;
  margin-top: @height*-.5;
  border-radius: @width*.5;
  background: #aaf;
  &[data-css-hide="true"] {
    display:none;
  }
}
```
これらをpackするとこんな残念な感じの:sob:[サンプル](http://codepen.io/Takepepe/pen/xVgRQW)ができます。  
~~これだったらcssAnimationだけで完結できるね…~~

# で、演出には集中できるの？
svgを保存する度にbrowserSyncとかで即確認、演出に集中しようっていう目的なのですが、svgファイルは一度閉じてしまうとIllustratorでは座標がずれてしまい、sketch.appでは直接編集出来ず、どちらも元ファイルから書き出ししなければいけない様子で、ここのフローは今後も調査が必要だなぁというお話でした。