VanillaなJSでスクロールに応じて要素をアニメーション

Ads

Result

ここ何年かすっかり定着しましたが、スクロールに応じて要素がアニメーションする、みたいなの。

デモのようなシンプルなものなら割と少ないコードで作れます。

javascript

const scrollElements = document.querySelectorAll(".js-scroll");//ターゲット指定

const elementInView = (el, dividend = 1) => {
  const elementTop = el.getBoundingClientRect().top;

  return (
    elementTop <=
    (window.innerHeight || document.documentElement.clientHeight) / dividend
  );
};

const elementOutofView = (el) => {
  const elementTop = el.getBoundingClientRect().top;//ページの上部から要素の距離を取得

  return (
    elementTop > (window.innerHeight || document.documentElement.clientHeight)//ビューポートの高さを取得
  );
};

const displayScrollElement = (element) => {
  element.classList.add("scrolled");//スクロールで表示されたら要素にクラス名を割り当てる
};

const hideScrollElement = (element) => {
  element.classList.remove("scrolled");//スクロールで非表示になったら要素からクラス名を除去する
};

const handleScrollAnimation = () => {
  scrollElements.forEach((el) => {
    if (elementInView(el, 1.25)) {
      displayScrollElement(el);
    } else if (elementOutofView(el)) {
      hideScrollElement(el)
    }
  })
}

window.addEventListener("scroll", () => { 
  handleScrollAnimation();
});

基本的には検出及びclassの追加のみで、エフェクトはCSSで管理します。

Ads

css

.js-scroll {
  opacity: 0;
  transition: opacity 500ms;
}

.js-scroll.scrolled {
  opacity: 1;
}

.scrolled.fade-in {
  animation: fade-in 1s ease-in-out both;
}

.scrolled.fade-in-bottom {
  animation: fade-in-bottom 1s ease-in-out both;
}

.scrolled.slide-left {
  animation: slide-in-left 1s ease-in-out both;
}

.scrolled.slide-right {
  animation: slide-in-right 1s ease-in-out both;
}

@keyframes slide-in-left {
  0% {
    -webkit-transform: translateX(-100px);
    transform: translateX(-100px);
    opacity: 0;
  }
  100% {
    -webkit-transform: translateX(0);
    transform: translateX(0);
    opacity: 1;
  }
}

@keyframes slide-in-right {
  0% {
    -webkit-transform: translateX(100px);
    transform: translateX(100px);
    opacity: 0;
  }
  100% {
    -webkit-transform: translateX(0);
    transform: translateX(0);
    opacity: 1;
  }
}

@keyframes fade-in-bottom {
  0% {
    -webkit-transform: translateY(50px);
    transform: translateY(50px);
    opacity: 0;
  }
  100% {
    -webkit-transform: translateY(0);
    transform: translateY(0);
    opacity: 1;
  }
}

@keyframes fade-in {
  0% {
    opacity: 0;
  }
  100% {
    opacity: 1;
  }
}

エフェクトは便宜変更してください。

html

<section class="scroll-container">
  <div class="scroll-element js-scroll slide-left">

  </div>
  <div class="scroll-caption">
    フェード+スライドしながら左から入ってくる
  </div>
</section>

.js-scrollクラスでアニメーションのターゲットに指定し、任意のエフェクトのclassを割り当てます。

以下で分かりやすく解説されています。

via

How to Animate on Scroll With Vanilla JavaScript