BodymovinでSVGアニメーション


## 下準備

公式
https://github.com/bodymovin/bodymovin

まずAfterEffectsにAdd-onを入れる
こちら（[Bodymovin](https://creative.adobe.com/addons/products/12557#.WMqFMBKLSL8)）からだとうまく同期されなかったのでコマンドを叩くことに

`/Contents/Mac OS/ExManCmd --install <file name of extension>.zxp`
https://helpx.adobe.com/jp/x-productkb/global/installingextensionsandaddons.html

^よく見たら公式のgithubにインストールの仕方が書いてあったのでそちらを参考にした方がいい

> 参考
[AfterEffectsで作成したアニメーションをJSONで書き出してみた](http://www.sonicjam.co.jp/blog/hitori/001484/)

## AEで詰まった点

モードの「除外」が効いていなかったので、
トラックマットの「アルファマット」で対応。

他にも使えないAEの機能はあると思っておいた方がいい。

### 使えない

- パスの結合
- バンク・膨張
- パペットピンツール
- エクスプレッション（jsだけどerror吐く）

### 使える

- マスク
- トラックマット
- シェイプトリミング
- キーフレーム
- イージング
- 画像

※消えているもの（マスクをかけているもの）も書き出すチェックを入れないと反映されない


## 実装

ざっと雛形

```javascript:CustomBodymovin.js
// AEで書き出したanimationDataを外部で管理
import { left01 } from '../animation/left01.js';
import { right01 } from '../animation/right01.js';
import { center01 } from '../animation/center01.js';

export default class CustomBodymovin {
  constructor(opts={}) {
    this.elm = opts.elm || document.createElement('div');
    this.animationData = opts.animationData;
    this.WIDTH = 1920;
    this.HEIGHT = 1080;
    this.init();
    this.initListener();
  }

  init() {
    this.selectAnimationData();
    this.anim = bodymovin.loadAnimation({
      container: this.elm,
      renderer: "svg",
      loop: false,
      autoplay: false,
      autoloadsegments:true,
      rendererSettings:{
        progressiveLoad:false
      },
      animationData: this.data
    });
  }

  initListener() {

    this._onResize();
    window.addEventListener('resize', () => {
      this._onResize();
    },false)

    this.anim.addEventListener('complete', () => {
      console.log('complete')
    })
    this.anim.addEventListener('loopComplete', () => {
      // loopが終わるたびに発火
      console.log('loopComplete')
    })
    this.anim.addEventListener('enterFrame', () => {
      // 毎フレームごとに発火するが誤差はあり
      console.log('enterFrame')
    })
    this.anim.addEventListener('segmentStart', () => {
      console.log('segmentStart')
    })

  }

  selectAnimationData() {
    switch (this.animationData) {
      case 'left01': this.data = left01; break;
      case 'right01': this.data = right01; break;
      case 'center01': this.data = center01; break;
    }
  }

  play(){
    this.anim.play();
  }
  stop(){
    this.anim.stop();
  }
  pause(){
    this.anim.pause();
  }
  destroy(){
    this.anim.destroy();
  }
  setSpeed(int){
    this.anim.setSpeed(int);
  }

  _onResize() {
    const ww = window.innerWidth;
    const wh = window.innerHeight;
    const ratio = ww / this.WIDTH;
    const scaleY = wh / (this.HEIGHT * ratio);
    const $svg = $(this.elm).find('svg');
    $svg.css('transform', `translate(-50%, -50%) scale3d(1, ${scaleY}, 1)`);
  }

}
```

```javascript:script.js
import CustomBodymovin from './lib/CustomBodymovin.js';

const animLeft = new CustomBodymovin({
  elm: document.getElementById('bodymovinLeft'),
  animationData: 'left01'
})

// たとえばボタンを押してスタート
$('#button').on('click', () => {
  animLeft.play();
})
```

```css:svgだから色は変えられる
path{
  fill: rgba(250,200,150,1);
}
```

## 相性のいいプラグイン

[Newton 2](http://www.flashbackj.com/motionboutique/newton/)


> 参考
[bodymovinで簡単アニメーション実装！](https://try-m.co.jp/blog/html/2733/)
[svg / canvas出力ができるbodymovinの紹介](http://techblog.kayac.com/bodymovin-svg-canvas)