JavaScriptでスクロール時にふわっと表示させる方法まとめ

# 概要
webサイトなどを見ていると、スクロールした時に要素がふわっと現れるやつありますよね
実装方法はいろいろあって比較検討したかったので、備忘録も兼ねて以下の三つの方法をまとめます

- [AOS](#AOS)
- [ScrollReveal.js](#ScrollReveal.js)
- [生のJavascript](#生のJavascript)

# AOS
AOS(Animation On Scroll library)とは、スクロールに連動してアニメーションを簡単に実装できるJavaScriptのプラグインです。
AOSを導入すると、HTML要素にクラスを追加、数行のJavaScriptを書くだけで、スクロールアニメーションを実装することができます。また、軽量であるため、パフォーマンスの観点からも導入がしやすいです。

### 実装方法
**1 AOSの導入**

パッケージのインストール

```
npm install --save aos@next
```

スクロールアニメーションを追加したいファイル内でimport

```js
import AOS from 'aos';
import 'aos/dist/aos.css';
// ..
AOS.init();
```

**もしくは**HTMLファイルの\<head>部分に以下を追加
※パッケージのインストールじゃないやり方

```html
<!-- css -->
<link rel="stylesheet" href="/aos/dist/aos.css">

<!-- javascript -->
<script src="/aos/dist/aos.js"></script>
<script>
  AOS.init();
</script>
```

**2 スクロールアニメーションの追加**

```html
<!-- data-aos でどんなアニメーションか指定する -->
<div data-aos="fade-right">
  TEST
</div>

<!-- data-aos-○○ でアニメーションをカスタマイズ可能 -->
<div
  data-aos="fade-up"
  data-aos-offset="200"
  data-aos-delay="50"
  data-aos-duration="1000"
  data-aos-easing="ease-in-out"
  data-aos-mirror="true"
  data-aos-once="false"
  data-aos-anchor-placement="top-center"
>
  TEST2
</div>
```
data-aos で指定できるアニメーション

| タイプ | 効果 |
| ----| ---- |
| Fade | フェード表示。ふわっとさせる |
| Flip | 回転表示 |
| Zoom | ズーム表示。強調したいとき |
| Slide | スライド表示。スライドインしてくる感じ |

この他にも様々なカスタマイズができるので、ご興味ある方は以下のgithubや公式サイトをご覧ください
[aosのgithub](https://github.com/michalsnik/aos)
[公式サイト](https://michalsnik.github.io/aos/)

# ScrollReveal.js
ScrollRevealはスクロール時にふわっと表示させることを簡単に実装できるJavascriptのライブラリです。
基本的にやれることはAOSと似ていて軽量で使い易いライブラリです。

### 実装方法
**1 ScrollRevealの導入**

パッケージのインストール

```
npm install scrollreveal
```

スクロールアニメーションを追加したいファイル内でimport

```js
import ScrollReveal from 'scrollreveal'
```

**もしくは**HTMLファイルの\<head>部分に以下を追加
※パッケージのインストールじゃないやり方

```html
<script src="https://unpkg.com/scrollreveal"></script>
```

**2 スクロールアニメーションの追加**

```html
<!-- アニメーションをつけたい要素に適当なクラスを付与する -->
<h1 class="fuwa">
  TEST
</h1>

<!-- JS部分 -->
<script>
  // htmlで付与したクラス単位で、アニメーションを追加する
  ScrollReveal().reveal('.fuwa');

  // オプションを追加し、アニメーションをカスタマイズ可能
  ScrollReveal().reveal('.fuwa', { 
    duration: 1000, // アニメーションの完了にかかる時間
    reset: true   // 何回もアニメーション表示するか
  });
</script>
```
オプションに関しては、他にもいろんなものがあるので、ご興味ある方は以下の公式サイトをご覧ください
[公式サイト](https://scrollrevealjs.org/api/delay.html)

# 生のJavascript
生のJavascriptでやる場合はこんな感じに書けます

```html:html
<div>
  <p class="fuwa">TEST</p>
</div>
```

```css:css
.fuwa {
  opacity: 0;
  visibility: hidden;
  transform: translateX(30px);
  transition: all 1s;
}
.fuwa.show {
  opacity: 1;
  visibility: visible;
  transform: translateX(0px);
}
```

```js:js
function showElementAnimation() {
  const elements = document.getElementsByClassName('fuwa');
  
  const showTiming = window.innerHeight > 768 ? 200 : 40; 
  const scrollY = window.pageYOffset;
  const windowH = window.innerHeight;

  for (let i=0;i<elements.length;i++) {
    // 要素の寸法と、そのビューポートに対する位置を取得
    const clientRect = elements[i].getBoundingClientRect();
    const elemY = scrollY + clientRect.top;
    if(scrollY + windowH - showTiming > elemY) {
      elements[i].classList.add('show');
    } else if(scrollY + windowH < elemY) {
      // スクロールを上に戻して再度非表示にする場合はこちらを記述
      elements[i].classList.remove('show');
    }
  }
}
showElementAnimation();
window.addEventListener('scroll', showElementAnimation);

```

# まとめ
個人的には上記の三つの中では、ScrollReveal.jsが一番良いかなと感じました。
理由としては、クラス単位でカスタマイズが可能なので同じコードを何回も書かなくて済むからです
要素ごとにいろんなパターンのアニメーションを書きたい場合はめんどくさいかも、、

ほかにもいろんなライブラリがあると思うので、もっと使いやすいやつを見つけたら追記していこうと思います。