1
1

More than 1 year has passed since last update.

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

Last updated at Posted at 2021-08-24

初めに

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

スクリーンショット 2021-08-24 21.41.03.png

ここを参考に実装しました

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

まずはHTMLから

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>
#ここで1個目のアニメーションの塊終了。
  </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>

続いてCSS

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は右0!要するに一番右に配置ということです。
.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;1秒かけてにゅっと現れます。opacityに1秒かけます
.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;
}

Javascriptを書いていく

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

// 以下スクロールで検知します の記述
document.addEventListener("scroll",function(){
  // 4件分上からの距離を取得する for文で回す
  for (let i = 0; i < targetElement.length; i++){
  // 上からの距離と、その要素がある程度たっしてから 6割くらい見えたら
  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をつけます。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1