スクロールするとコンテンツをフワっとアニメーションで表示する（javascript）

## はじめに

タイトルについて記事にしました。
この記事で得る内容は以下の通りです。

・ JavaScriptの基礎知識が増える
・ スクロールするとコンテンツをフワっとアニメーションで表示する方法

## JavaScript

① まずCSSセレクタを対象に要素を配列で取得します

```javascript:script.js
const targetElement = document.querySelectorAll(".animationTarget")
```

② 変数`targetElement`の対象の数だけ、for文で処理を繰り返します

```javascript:script.js
const targetElement = document.querySelectorAll(".animationTarget")

for (let i = 0; i < targetElement.length; i++) {}
```

③ `targetElement`の上からの距離と、要素の高さを取得して、現在どのくらいスクロールしているのかを比較する処理を記述します

```javascript:script.js
const targetElement = document.querySelectorAll(".animationTarget")

for (let i = 0; i < targetElement.length; i++) {
  const getElementDistance = targetElement[i].getBoundingClientRect().top
}
```

##### ・ getBoundingClientRect().topメソッド
対象の要素`.animationTarget`から、今見えているブラウザの上側の距離を取得するメソッド
現在ブラウザで見えている灰色の所と水色の`div.animationTarget.show`の引いた距離を取得します

![スクリーンショット 2020-12-07 15.20.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/772631/9f0ec3ee-f18b-84dc-dbb2-d5c36b88f298.png)

④ この処理をスクロールする度に取得する為、スクロールイベントを対象にした関数を定義して、先ほど記述したfor文を関数の中に移動します

```javascript:script.js
const targetElement = document.querySelectorAll(".animationTarget")

document.addEventListener("scroll", function () { 
  for (let i = 0; i < targetElement.length; i++) {
    const getElementDistance = targetElement[i].getBoundingClientRect().top
  }
});
```

⑤ `window.innerHeight`で現在のブラウザの高さを取得し、`if`文を使い、変数`getElementDistance`よりも画面の高さが高い時（対象の要素が見え始めた時）にクラスを付与します

```javascript:script.js
const targetElement = document.querySelectorAll(".animationTarget")

document.addEventListener("scroll", function () { 
  for (let i = 0; i < targetElement.length; i++) {
    const getElementDistance = targetElement[i].getBoundingClientRect().top
    if (window.innertHeight > getElementDistance) {
      targetElement[i].classList.add("show");
    }
  }
});
```

対象の要素が少し見えた時にクラスを付与しても、何が起きたのか分からないと思いますので、変数`getElementDistance`に処理を付け加えます

⑥ 変数`targetElement`から半分ほど高さを取得して調整します

##### ・ clientHeightプロパティ
対象の表示域の高さを取得するプロパティ

```javascript:script.js
const targetElement = document.querySelectorAll(".animationTarget")

document.addEventListener("scroll", function () { 
  for (let i = 0; i < targetElement.length; i++) {
    const getElementDistance = targetElement[i].getBoundingClientRect().top + targetElement[i].clientHeight * 0.6
    if (window.innertHeight > getElementDistance) {
      targetElement[i].classList.add("show");
    }
  }
});
```

これで要素の半分〜6割程見えたところでアニメーションすると思いますが、高さをいくつかけるかはアニメーションの内容等で微調整が必要です

## haml

続いてhamlとscssを書いていきます
アニメーションさせたい要素の親として`.animationTarget`を配置します

```haml:index.haml
.animationTarget
  .container-contact#CONTACT
    %p.top Contact
    .header-line.middle
```

## scss

基本は予め透明にして、`show`クラスがついたら透明を解除して`transition`でふわっとアニメーションをさせて表示させます

上下左右からアニメーションして表示する場合は`trasform: translate()`で予め要素を移動させておいて
`transform: none;`で移動させた要素を元に戻すという流れです

```scss:index.scss

// 基本形

.container-contact {
  opacity: 0;
  transform: translateY(50px);
  transition: 1s;
}

.animationTarget.show .container-contact,
.animationTarget.show .language__block,
.animationTarget.show .picture,
.animationTarget.show .work,
.animationTarget.show .work.translateXscroll {
  opacity: 1;
  transform: none;
}

// 以下参考

// コンテンツの左から右に行くにつれ遅く見せる

.language__block {
  opacity: 0;
  transform: translateY(30px);
}
.language__block.delay1 {
  transition: 1s;
}

.language__block.delay2 {
  transition: 1.2s;
}

.language__block.delay3 {
  transition: 1.4s;
}

.language__block.delay4 {
  transition: 1.6s;
}
.language__block.delay5 {
  transition: 1.8s;
}

// 画像だけ遅れて表示させる

.picture {
  opacity: 0;
  transition: 1s 0.5s; // 0.5秒遅れて1秒かけてアニメーションする
}

// 左右対象に表示する

.work {
  opacity: 0;
  transform: translateX(60px);
  transition: 1.5s;
}
.work.translateXscroll {
  opacity: 0;
  transform: translateX(-60px);
  transition: 1.5s;
}
```