トップへ戻る
BLOGS

JS カーテンアニメーションの作り方

JS カーテンアニメーションの作り方

さて今回はスクロールアニメーション+カーテンアニメーションを造ります。

いわゆるそのコンテンツの場所に来たらアニメーションを開始し

カーテンが開くようにマスクが開いて

中のコンテンツが見えるような感じにしたいと思います。

まずHTMLはこちら

<main>
    <div class="button animation-target">
      <a href="">もっと見る</a>
    </div>

    <div class="picture animation-target">
      <div></div>
    </div>

    <div class="button animation-target">
      <a href="">もっと見る</a>
    </div>

    <div class="picture animation-target">
      <div></div>
    </div>

    <div class="button animation-target">
      <a href="">もっと見る</a>
    </div>

    <div class="picture animation-target">
      <div></div>
    </div>
    
    <div class="button animation-target">
      <a href="">もっと見る</a>
    </div>

    <div class="picture animation-target">
      <div></div>
    </div>
  </main>

作りとしてはシンプルに

「もっと見る」のボタン

これから背景画像を設定する空のdivタグ

これらをそれぞれanimation-targetというクラスをつけて

JSで操作できるようにしておきます

後は簡単に見た目を整えるためにCSSを書きましょう

main {
  max-width: 1000px;
  width: 100%;
  margin: 50px auto;
  background-color: #eee;
}

main .button {
  width: 200px;
  height: 40px;
  margin-top: 100px;
}

main .button > a {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 5px;
  border: 1px solid #555;
  background-color: #fff;
}

main .picture {
  width: 700px;
  height: 200px;
  margin-top: 100px;
}

main .picture > div {
  height: 100%;
  background: url(../img/teien1.jpg);
  background-size: cover;
  background-repeat: no-repeat;
  background-position: center;
}

.picture:nth-of-type(even) {
  margin-left: auto;
}

はい。

これで準備ができたので

javascriptでこのタグを操作していこうと思います

const showElements = document.querySelectorAll(".animation-target");

window.addEventListener("scroll",function() {
  for (let i = 0; i < showElements.length; i++) {
    const elementDistance = showElements[i].getBoundingClientRect().top + showElements[i].clientHeight * .5;
    if (window.innerHeight > elementDistance){
      showElements[i].classList.add("show");
    }
   }
})

説明していきます。

querySelectorAllで要素の情報を取得します

window.addEventListenerでスクロールした際のイベントを追加します。

for (let i = 0; i < showElements.length; i++)

取得した要素の数分ループを回してshowElements[i]で出力していきます。

.getBoundingClientRect().topで要素の画面上部までの距離を取得し変数に入れておきます

window.innerHeightで現在の画面の高さが取得できるため

それをif分の条件でトリガーにします。

if (window.innerHeight > elementDistance){
}

そして中にshowElements[i].classList.add(“show”);

入れてクラスを付与するという処理を書きます。

最後に要素の高さの半分をelementDistanceに足してあげることで

ちょうどよい処理タイミングを図ります

+ showElements[i].clientHeight * .5;

CSSアニメーションを追加する

さて総仕上げとしてこのクラス付与を利用して

CSSアニメーションを作成します。

まずカーテンとしてのマスクをデザインします。

main .animation-target::before {
  content: '';
  display: block;
  position: absolute;
  left: 0%;
  top: 0%;
  z-index: 1;
  width: 100%;
  height: 100%;
  background-color: #333;
  transform: translateX(-100%);
}

こちらは疑似要素にabsolateで重ねていますので

もちろん親要素にposition:relative;はマストですね

次にこのマスクをスライドするアニメーションを用意します。

@keyframes slideMask {
  0% {
    transform: translateX(-100%);
  }
  45%, 55% {
    transform: translateX(0%);
  }
  100% {
    transform: translateX(100%);
  }
}

ここでのポイントとしては

45%, 55% {
transform: translateX(0%);
}

によって一時的にマスクが重なった瞬間だけ

その場に留まる瞬間を作っています

main .animation-target.show::before {
  animation: slideMask 1.8s forwards;
}

そしてアニメーションですが

こちらのポイントはforwards;で通り過ぎた後の

位置をキープするようにしています。

仕上げにマスクが重なるまで要素を見えなくしておきます。

@keyframes showElements {
  0% {
    opacity: 0;
  }
  100% {
    opacity: 1;
  }
}

main .animation-target a,
main .animation-target div {
  opacity: 0;
}

main .animation-target.show a,
main .animation-target.show div {
  animation: showElements .1s .9s forwards;
}

最後のポイントは

  • すぐに現れるようにすること
  • マスクが重なるまでアニメーションさせないこと
  • アニメーション後は表示を見えるようにすること

それを踏まえると

showElements .1s .9s forwardsこれくらいの感覚がベストでしたね。

今回は以上になります

お疲れさまでした

コメントをお待ちしております

お気軽にコメントをどうぞ。

CAPTCHA