anime.jsの使い方(callback/timeline/fade/blur)【vue(nuxt.js)】

実経験に基づき、anime.jsの使い方まとめです。callback、timeline、fade、blurなどの機能を試しました。

## JSのアニメーションライブラリ比較、anime.jsを採用した理由

まずJSのアニメーションライブラリ比較することから入りました。そのときの記事はこちらです。

[animejs/GSAP/JavaScriptのアニメーションライブラリおすすめは?【ライセンス比較】](https://ebookbrain.net/js-anime/)

そして、anime.jsを採用しました。軽量、ライセンス形態、公式や日本語ドキュメント、メンテナンスコストに加えて、実際に使っている人の口コミも参考にしました。


## vue(nuxt.js)でanime.jsをインストール

環境はnuxt(vue)で使っています。

```
npm install animejs
```

インストールしたのち、インポートします。

```javascript:test.vue
import anime from 'animejs'
```

### anime.jsのドキュメント

どうやらフランスのパリの方が作ったようです。日本のアニメという名前がついているのが興味深いです。軽量なライブラリなのでお手軽っぽいです。MITライセンスです。

ドキュメントはこちらから参照できます。クリックするとコードが表示されるため大変わかりやすいです。

[anime.jsドキュメント](https://animejs.com/documentation/)

githubです。

[anime.jsのgithub](https://github.com/juliangarnier/anime)

なにやら日本語ドキュメントもありました。

[anime.js日本語ドキュメント](https://tr.you84815.space/animejs/)

## vue(nuxt.js)でanime.jsの使い方(サンプル)

### フェードイン・アウトのアニメーション

サンプルは横移動などが多いですが、フェードインアウトをやりたかったのでそこから入ります。

cssのセレクターをtargetsに指定しアニメーションをかけるという仕組みです。vueの場合、mountedに置くと起動時アニメーションがかかります。

```javascript:test.vue
mounted() {
  anime({
    targets: '.text-anime', // 対象を指定
    opacity: [0, 1],
    duration: 3000, // ミリ秒指定
    easing: 'easeInOutCubic' // 加減速の種類
  })
}
```

フェードアウトの場合はopacityの0と1をひっくり返してください。

### アニメーションの終了待ち(callback)

callback関数はbrgin,complete,updateが用意されています。

アニメーションを終了待ちして次のアニメーションに遷移する場合completeを使います。

文字が表示されて次にロゴが表示される映画のオープニングみたいなものを作ってみます。

```javascript:test.vue
mounted() {

    anime({
      targets: '.logo-anime',
      opacity: 0 // 初期時ロゴは非表示
    })

    anime({
      targets: '.text-anime',
      opacity: [0, 1],
      duration: 3000,
      easing: 'easeInOutCubic',
      complete: () => {
        anime({
          targets: '.text-anime',
          opacity: [1, 0],
          duration: 3000,
          easing: 'easeInOutCubic',
          complete: () => {
            document.querySelector('.text-anime').style.display = 'none'
            anime({
              targets: '.logo-anime',
              opacity: [0, 1],
              duration: 3000,
              easing: 'easeInOutCubic'
            })
          }
        })
      }
    })
  }
}
```

しかし、少しコードがわかりにくいのと、アニメーションを終了待ちせず、ずらして動かしたい場合もあるはずです。

### タイムライン(timeline)

少し使ってわかったことですが、anime.jsはタイムラインの機能を兼ね備えています。anime.jsはcallback関数もあるのですが、基本的にタイムラインの方が制御しやすい気がしました。タイムラインでできないことはcallback関数を使います。

```javascript:test.vue
  mounted() {
    const openingAnime = anime.timeline({
      loop: false
      easing: 'easeInOutCubic'
    })

    openingAnime
      .add({
        targets: '.text-anime',
        keyframes: [
          {
            opacity: [0, 1],
            duration: 3000
          },
          {
            opacity: [1, 0],
            duration: 3000
          }
        ]
      })
      .add({
        targets: '.logo-anime',
        opacity: [0, 1],
        duration: 3000,
      })
}
```

この方がすっきりとします。初期時にロゴを非表示にする設定もいらず、入れ子にならないためこちらの方がコードが読みやすい気がします。オフセットを利用するとタイミングをずらすことができます。ディゾルブアニメーションのようなことができます。

### タイミング調整(delay、オフセット)

ウェイトです。

```javascript
delay: 10000,
```

後ろにずらすならdelayで問題なくいけます。

ただ、2つのアニメが重なるようなディゾルブ効果をつける場合、前にずらす必要があります。delayにマイナスをつけると動作がおかしなことになります。。

その場合はaddに2つ目の引数が取れるようです。もちろん、これでも後ろにずらすこともできます。

```javascript
.add(
  {
    targets: '.logo-anime',
    opacity: [0, 1],
  },
  '-=3000'
)
```

また若干わかりにくいかもですけど、stringではなくnumberで指定するとオフセットが絶対値になるようです。

```javascript
.add(
  {
    targets: '.logo-anime',
    opacity: [0, 1],
  },
  1000
)
```

### ブラー(blur)

blurについて調べると、ちょっと難しいという情報や次のようなコードがでてきました。

このコードはanim.progressが1〜100に動くため、そこで変化をつけます。

```javascript
update(anim) {
  document.querySelector('.logo-anime').style.filter = 'blur(' + 20 - anim.progress / 100 + 'px)'
}
```

たしかに上記でもできます。ただ公式サイトはそれっぽい情報はありませんでしたが、試したところもっと平易な書き方で普通にできました(できるようになった?)。

```javascript
.add({
  targets: '.logo-anime',
  opacity: [0, 1],
  filter: ['blur(20px)', 'blur(0px)'],
  duration: 5000
})
```

### html

おまけにhtmlのコードです。videoの上にアニメーションをのっける場合はこんな感じになりますかね。

```html
<div class="video-wrap">
    <video autoplay muted loop playsinline>
    <source src="~/assets/mov/opening.mp4" />
    </video>
    <div class="video-telop text-anime">alpha ver start</div>
    <b-img src="~/assets/images/logo/logo.svg" class="video-telop logo-anime" style="width: 280px;"> </b-img>
</div>
```

### SVGのアニメーションなどanime.jsでできること

他にもanime.jsでは背景スクロール、1文字ずつ動かす、SVGのアニメーション、マスクアニメーションなどができそうです。だいたい一通り網羅されており、いい感じな気がしました。

SVGのアニメーション、マスクアニメーションなど後半はこちらに執筆しました。

https://ebookbrain.net/svg-anime/

参考になれば幸いです。