【Waypoints.js & Animate.css】スクロールでアニメーションしてみよう

## 目次
1. Waypoints.js
（1-1） 準備
（1-2） 基本的な使い方
2. Animate.css
（2-1）準備
（2-2）基本的な使い方
3. Waypoints.jsとAnimate.cssの組み合わせ
（3-1）要素をふわっとフェードインさせる方法
（3-2）要素の表示を遅延させる方法
（3-3）要素を表示したままにさせる方法

## 1. Waypoints.js

### 準備（Waypoints）

公式サイト：http://imakewebthings.com/waypoints/
![スクリーンショット 2023-12-03 20.19.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3576061/ac98ecfa-0094-cee0-a976-59901daefb4f.png)


読み込み方は、以下の２通りです。どちらでもいいです。
- ダウンロード
- cdn

#### ダウンロードする場合
公式サイトからzipファイルをダウンロードし、解凍してください。
![スクリーンショット 2023-12-03 20.20.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3576061/88a94528-fbd3-132a-4dfd-10b184279b5b.png)

zipファイルを展開したあと、「libフォルダ」内の`jquery.waypoints.js`か`jquery.waypoints.min.js`どちらかを読み込んで使用します。
＊今回はjquery.waypoints.min.jsとしてみましょう

このjsファイルをプロジェクト内に配置してください。`jsファイル`などを用意して、そこに配置しておくと良いでしょう。

あとは、bodyの閉じタグ直前で以下のようにjqueryを読み込み、
`jquery.waypoints.min.js`を読み込みましょう。
```html
<body>
    <!-- 中略 -->
    
    <script src="https://code.jquery.com/jquery-3.6.1.min.js"></script>
    <script src="jquery.waypoints.min.js"></script>
    <script src="main.js"></script>
</body>
```

#### CDNの場合
CDNとは「Contents Delivery Network」の略で、Webコンテンツを迅速に、効率よくユーザーに配信するためのネットワークです。以下のようにbodyの閉じタグ直前にcdnを読み込むだけです。

```html
<body>
    <!-- 中略 -->
    
    <script src="https://code.jquery.com/jquery-3.6.1.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/waypoints/3.0.0/jquery.waypoints.min.js"></script>
    <script src="main.js"></script>
</body>
```

### 基本的な使い方（Waypoints）
html要素を用意します（hogeというクラスを与えました）。
hogeに対してwaypointの関数を呼びます。

handlerが実行する処理を記述するオプションです。
handlerの中でスクロールの方向も定めます。
offsetが実行するタイミングを決めるオプションです。

```javascript
$('.hoge').waypoint({
  handler: function (direction) {
    if (direction === 'down') {
      // 下にスクロールした時の処理
      console.log('hoge is in the middle');
    }
  },
  // 要素が画面中央にきた時にhandlerを実行する
  offset: '50%',
});
```

## 2. Animate.css

### 準備(Animate.css)
公式サイト：https://animate.style/
![スクリーンショット 2023-12-03 23.23.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3576061/6c09761a-bda9-39ea-7b96-03f9835b8d80.png)


読み込み方は、以下の2通りです。どちらでもいいです。
- ダウンロード
- cdn

#### ダウンロードする場合
![スクリーンショット 2023-12-03 23.26.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3576061/e664562a-81bf-731e-3904-4243d8724413.png)

公式サイトの左上にあるgithubに移動します。githubからダウンロードします。
ダウンロードしたzipファイルを解凍後、`animate.css`または`animate.min.css`をプロジェクト内に配置します。cssフォルダなどを作ってそこに配置すると良いでしょう。

そのあと、HTMLのhead内で読み込みます。

```html
<head>
  <!-- 中略 -->
  <link rel="stylesheet" href="css/animate.css">
  <link rel="stylesheet" href="css/style.css">
</head>
```

#### cdnの場合

以下のようにcdnでリンクを読み込むだけです。

```html
<head>
  <!-- 中略 -->
  <link
    rel="stylesheet"
    href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css"
  />
</head>
```
### 基本的な使い方（Animate.css）

アニメーションを施したいhtmlの要素に`animate__animated`クラスをつけます。
```html
<div class="box animate__animated"></div>
<div class="box animate__animated"></div>
<div class="box animate__animated"></div>
<div class="box animate__animated"></div>
<div class="box animate__animated"></div>
```
アニメーションの種類はいっぱいあるので、公式サイトからコピペしてみてください。
![スクリーンショット 2023-12-04 16.30.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3576061/e3814b30-e9f6-39fe-12c2-08bab91a6924.png)

つけたいアニメーションが決まったら、そのクラスを追加します。
今回は`animate__bounce`を追加してみました。
```html
<div class="box animate__animated animate__bounce"></div>
```
アニメーションを遅らせたい場合、`animate__delay-〇s`としてください。
```html
<div class="box animate__animated animate__bounce animate__delay-2s"></div>
```
アニメーションの速さを変えたい場合、以下のうちどれかを選んでください。
`animate__slow`は2秒
`animate__slower`は３秒
`animate__fast`は0.8秒
`animate__faster`は0.5秒
（デフォルトは１秒）

```html
<div class="box animate__animated animate__bounce animate__slow"></div>
<div class="box animate__animated animate__bounce animate__slower"></div>
<div class="box animate__animated animate__bounce animate__fast"></div>
<div class="box animate__animated animate__bounce animate__faster"></div>
```

アニメーションを繰り返したい場合、`animate__repeat-〇`としてください。
```html
<div class="box animate__animated animate__bounce animate__repeat-3"></div>
```

アニメーションを永遠リピートしたい場合、`animate__infinite`としてください。
```html
<div class="box animate__animated animate__bounce animate__infinite"></div>
```
このようにクラスを付与するだけなので簡単です。

## 3. Waypoints.jsとAnimate.cssの組み合わせ
あとはWaypointsとAnimate.cssを掛け合わせるだけです。
スクロールして要素が画面のある高さまで来たら、アニメーションのクラスを付与するだけです。

ここで最初にしておくべき重要な設定があります。
アニメーションを施す要素は最初に隠しておきましょう。
```css
.animate__animated { opacity: 0; }
```

アニメーションのクラスを付与すると勝手に`opacity: １`になって表示されます。

### 要素をふわっとフェードインさせる方法
要素が画面中央に来たら、`animate__fadeInUp`というAnimate.cssのクラスを付与しています。

```javascript
$('.box').waypoint({
  handler: function (direction) {
    if (direction === 'down') {
      // フェードインアップというクラスを付与してます
      $(this.element).addClass('animate__fadeInUp');
      
      // アニメーションが１回しか呼ばれないようにするためにdestroyしてます
      this.destroy();
    }
  },

  // 画面中央に来たらhandlerを実行する設定です
  offset: '50%',
});
```

### 要素の表示を遅延させる方法
以下のように三つ要素が横並びになっていたとします。
![スクリーンショット 2023-12-04 17.08.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3576061/4b3afd13-df15-902a-1bac-be975510df05.png)

これらの要素が画面の45%の高さまできたら、赤→オレンジ→黄色の順で`animate__fadeInUp`というクラスを付与したいと思います。

javascriptの方は先ほどまでと同じです。
```javascript
$('.box').waypoint({
  handler: function (direction) {
    if (direction === 'down') {
      $(this.element).addClass('animate__fadeInUp');
      this.destroy();
    }
  },
  offset: '45%',
});
```

cssの方で`animation-delay`プロパティの設定をしました。
```css
.box:nth-of-type(1) {
  background: red;
}
.box:nth-of-type(2) {
  background: orange;
  /* 0.3秒の遅延 */
  animation-delay: 0.3s;
}
.box:nth-of-type(3) {
  background: yellow;
  /* 0.6秒の遅延 */
  animation-delay: 0.6s;
}
```

ユーティリティクラスを付与することでanimationの遅延を実装することもできますが、私はこのようにcssの方で記述する方が分かりやすいと思ったのでこの方法を紹介しました。

### 要素を表示したままにさせる方法
Animate.cssのクラスを試していると、いくつかのアニメーションで表示されてから消えてしまうものがあったので、アニメーション後も表示したままにさせる方法をご紹介します。

```javascript
$('.box').waypoint({
  handler: function (direction) {
    if (direction === 'down') {
      $(this.element).addClass('animate__zoomIn');
      // opacityが０に戻らないように1に変更しました
      $(this.element).css('opacity', '1');
      this.destroy();
    }
  },
  offset: '20%',
});
```

## まとめ

Waypoints.jsとAnimate.cssを使えばスクロール時のアニメーションはとっても簡単です。

要素が画面のある高さまで来たら、クラスを付与するだけです。

是非使ってみてください〜