AOSを使ったアニメーションでNext.jsページをいい感じにする

# AOSを使ったアニメーションでページをリッチな感じにする

ページになぁ〜んか物足りなさを感じる...
ちょっとしたアニメーションを入れたいなぁ...
でも自分でCSSとか書くのは流石にめんどくさい...
そこで、[AOS](https://michalsnik.github.io/aos/)というAnimate On Scroll Libraryを使ってアニメーションを設定することに。

## 導入
パッケージマネージャー、またはscriptタグで読み込んで使います。
以下それぞれの手順。

- パッケージマネージャーの場合

```
yarn add aos@next

or

npm install --save aos@next
```
`AOS.init()`は、SSR関連の理由からuseEffectにラップする形で記述します。
_app.jsに以下を追加してください。

```js:_app.js
import React from 'react'
import '../styles/globals.css'
import AOS from 'aos'; // 追加
import 'aos/dist/aos.css';  // 追加

function MyApp({ Component, pageProps }) {
  React.useEffect(() => {  // 追加
    AOS.init();
  },[]);

  return <Component {...pageProps} />
}

export default MyApp
```
- scriptタグを使う場合

```js:index.js
<Head>
  <link rel="stylesheet" href="https://unpkg.com/aos@next/dist/aos.css" /> {/*追加*/}
</Head>
```
公式ではbodyの閉じタグの直前に以下のコードを追加するように、とあります。
  
```
<script src="https://unpkg.com/aos@next/dist/aos.js"></script>
<script>
  AOS.init();
</script>
```

しかしNext.jsはデフォルトのファイル構成ではbodyタグをカスタマイズすることはできないので、
`/pages/`配下に`_document.js`というファイルを定義し、そこに記述します。

```js:_document.js
import Document, { Html, Head, Main, NextScript } from 'next/document'

class MyDocument extends Document {
  static async getInitialProps(ctx) {
    const initialProps = await Document.getInitialProps(ctx)
    return { ...initialProps }
  }

  render() {
    return (
      <Html>
        <Head />
        <body>
          <Main />
          <NextScript />
          <script src="https://unpkg.com/aos@next/dist/aos.js"></script> <!--ここから追加-->
          <script>
            AOS.init();
          </script>
        </body>
      </Html>
    )
  }
}

export default MyDocument
```

### とりあえず使ってみる
導入が完了したのでとりあえず動かしてみましょう。
アニメーションさせたい要素に対して`data-aos`属性でアニメーション名を指定します

```html
<div data-aos="fade-in"></div>
```

こんな感じです。
![aosTest.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/924580/31097d5c-e871-f228-b6fa-e1c1ca55f494.gif)
か、かんたんすぎる...!

## カスタマイズ
ここまででアニメーションの適用は出来ました。
次はアニメーションの速度などカスタマイズしていきます。 
デフォルトの設定は以下のようになっているようです。

```js
AOS.init();

AOS.init({
  // Global settings:
  disable: false, // 以下の値を受け入れます。phone', 'tablet', 'mobile', boolean, expression or function
  startEvent: 'DOMContentLoaded', // AOSが初期化すべき、ドキュメントにディスパッチされたイベントの名前
  initClassName: 'aos-init', // 初期化後に適用されるクラス
  animatedClassName: 'aos-animate', // アニメーションに適用されるクラス
  useClassNames: false, // trueの場合、スクロール時に `data-aos` のコンテンツをクラスとして追加します。
  disableMutationObserver: false, // 変異の自動検出を無効にする（上級者向け)
  debounceDelay: 50, // ウィンドウのサイズ変更時に使用するデバウンスの遅延時間（上級者向け)
  throttleDelay: 99, // ページをスクロールする際のスロットルの遅延時間 (上級者向け)
  

  // `data-aos-*` 属性で要素ごとにオーバーライドできる設定です。
  offset: 120, // 元のトリガーポイントからのオフセット(px単位)
  delay: 0, // 0から3000までの値を、50msステップで設定
  duration: 400, // 0～3000の値を、50msステップで設定
  easing: 'ease', // AOSアニメーションのデフォルトイージング
  once: false, // - スクロールダウン中に、アニメーションを一度だけ行うかどうか 
  mirror: false, // スクロール中に要素をアニメーションさせるかどうか
  anchorPlacement: 'top-bottom', // ウィンドウに対する要素のどの位置がアニメーションのトリガーとなるかを定義します。
});
```
よくわからないとこもいくつかあるんですが...。  
これらのパラメータを`data-aos-***`属性を用いてカスタマイズしていきます。

```html
<div
  data-aos="fade-up"
  data-aos-delay="50" アニメーションの遅延設定
  data-aos-duration="1000"  アニメーションの長さ
  data-aos-easing="ease-in-out" イージングの設定
>
</div>
```

カスタマイズありなしで比べてみましょう。
![testAOScus.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/924580/37b20d07-2a1e-6917-2319-e1ac1e10a0fe.gif)

こんな感じで、これまた簡単にアニメーションのカスタマイズをすることが出来ました。
素晴らしい。

ということで以上です。