ふわっと出てくるアニメーション　Javascript HTML CSS

<h2>初めに</h2>
今回は、スクロールすると、ふわっと要素が出てくるアニメーションを実装しました。
スクロールすると「画像」「記事の閲覧と検索」「説明文」がふわっと出てきます。
こういうのが下に４つくらい続くイメージです。

![スクリーンショット 2021-08-24 21.41.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1633266/b5f8c7ad-b30a-605a-2d3d-3933e2b51c77.png)

<h2>ここを参考に実装しました</h2>

以下のyoutubeを見て実装しました。
私の記事は自分で忘れないようにまとめてるだけなので、
実装したいかたは以下の動画を見ていただくと良いかと思います。
また、youtubeで紹介されてるものと私のコードは完全一致しておらず、
所々変えていますのでご注意ください！！！

https://www.youtube.com/watch?v=zJZ3B4QKzZI&t=442s

<h2>まずはHTMLから</h2>


```perl:homes/top.html.erb
#ひとまずコンテナーで囲む
<div class="container mt-5">
  <h4 id="how_to_use" class="text-center">How to use</h4>
#全体をulで囲み、アニメーションひとつひとつはliタグで囲む
<ul class="contents">
#animationTargetはのちにJavascriptで使うのでスペルミス注意！
  <li class="animationTarget">
#asset_pathは本番環境対応のために記載しています。img-fluidで画像もレスポンシブ対応
    <%= image_tag asset_path("show2.jpg"),class:"img-fluid"%>
#テキスト全体をcontentsTextで囲みます。
    <div class="contentsText">
#タイトル
      <h2>記事の閲覧と検索</h2>
#説明文の箇所
      <p>Postの一覧ページでは投稿記事の一覧が見れます。<br>
      <strong>タグでの検索/ランキング/並び替え/検索</strong>ができます。<br>
      <strong>検索機能（インクリメンタルサーチ)</strong>を使用して<br>
      投稿を探しましょう。<br>
      参考になった投稿には、いいねやコメントをしましょう</p>
    </div>
#ここで１個目のアニメーションの塊終了。
  </li>

  <li class="animationTarget">
    <%= image_tag asset_path("show3.png"),class:"img-fluid"%>
    <div class="contentsText">
      <h2>マイページ</h2>
       <p><strong>Activity</strong>ではあなたのmy portでの活動をグラフにして表示します。<br>
        記事にいいねがつくと<strong>TEU(ポイント）</strong>が溜まっていきます。</p>
    </div>
  </li>
  <li class="animationTarget">
    <%= image_tag asset_path("show4.png"),class:"img-fluid"%>
    <div class="contentsText">
      <h2>勉強会</h2>
      <p>社内での<strong>勉強会</strong>の開催をお知らせできます。<br>
      詳細ページから勉強会への参加、退出ができます。<br>
      管理者はメンバーに<strong>メール</strong>での一斉通知が可能です。</p>
    </div>
  </li>

  省略
</div>
```

<h2>続いてCSS</h2>

```perl:app/assets/stylesheets/homes.scs

#how_to_use{
  color:rgba(70, 130, 180,.8);
  font-family: Chalkduster, "Bradley Hand", Courier, "Segoe Print", sans-serif
}

li{
  margin:0;
  list-style:none;}
#子要素を親要素を基準に配置したいので親要素にはrelative記載します。
.contents li {
  position: relative;

}
#最初のli以外にmargin-topを効かせます。これないとギュッとしてしまいます。
.contents li:not(:first-of-type){
  margin-top: 50px;
}
#奇数のliタグの.contentsTextは右０！要するに一番右に配置ということです。
.contents li:nth-of-type(odd) .contentsText{
  right: 0;
}
#偶数タグについてはflex-startを使用し左寄せです。この指定がないとpタグがずれます。
.contents li:nth-of-type(even) .contentsText{
  align-items:flex-start;
}
#インライン要素なので、display:block;を指定しないとマージンききません。
.contents li:nth-of-type(even) .img-fluid{
  display:block;
  margin-left: auto;
}

#flex-direction:column;は上から下なので要素は縦に並びます。
#align-items:flex-end;で右よせ
#position:absolute;で上から○％の位置というのを指定します。
.contentsText{
  display:flex;
  flex-direction:column;
  align-items:flex-end;
  position:absolute;
  top:30%;
}

#white-sapce:nowrap;で改行はしないようにします。
#opacity: 0;で表示されなくなります。
#transform: translateY(20px);は最初20px下に配置しておきます。x軸y軸のxyです。
#transition: 1s;１秒かけてにゅっと現れます。opacityに１秒かけます
.contents h2{
  font-size:50px;
  font-weight:bold;
  white-sapce:nowrap;
  background-color:rgba(135, 206, 250,.8);
  padding:10px 20px;
  border-radius:5px;
  opacity: 0;
  transform: translateY(20px);
  transition: 1s;
}

.contents p{
  line-height: 1.6;
  font-size:15px;
  max-width:500px;
  padding:15px;
  margin-top:30px;
  border-radius:5px;
  background-color:rgb(224, 255, 255);
  opacity: 0;
  transform: translateX(20px);
  transition: 1s;
}

.img-fluid{
  opacity: 0;
  transform: translateX(-20px);
  transition: 1s;
}


#transform:noneは下やら左に配置していたものを元に戻すという記述です。
#opacity:1で表示されます。
#クラスにshowをつけるのはjavascriptで行います。

.contents li.show h2,
.contents li.show p,
.contents li.show .img-fluid{
  transform:none;
  opacity:1;
}
```

<h2>Javascriptを書いていく</h2>

```js
// 以下で、４つの要素を取得している
const targetElement = document.getElementsByClassName("animationTarget");
// ４件取得できる
// console.log(targetElement);
console.log("画面の高さ",window.innerHeight)

// 以下スクロールで検知します　の記述
document.addEventListener("scroll",function(){
  // ４件分上からの距離を取得する　for文で回す
  for (let i = 0; i < targetElement.length; i++){
  // 上からの距離と、その要素がある程度たっしてから　６割くらい見えたら
  const getElementDistance = targetElement[i].getBoundingClientRect().top + targetElement[i].clientHeight *.6
  // console.log(getElementDistance);
// いまのブラウザの高さ取得
//   if (i === 1){
//     console.log(getElementDistance)
// }
  if(window.innerHeight > getElementDistance) {
    // これにより、表示されたanimation targetのクラスにshowがつく
    targetElement[i].classList.add("show")
  }
  }
})
```

```if(window.innerHeight > getElementDistance)```でクラスに
showをつけています。
これは、画面の高さ（スクロールしてきた長さ）が、ここで出てきてと指定した長さより
大きくなったらshowをつけます。