JavaScript(脱jQuery)

スクロールで要素をフェードインさせる:再アニメーション(何度でも発火)するバージョン

・要素はあらかじめ非表示にしておく

・スクロールしたらフェードインさせる要素にクラス付与する

下からフェードイン

▼▼▼▼▼ スクロール ▼▼▼▼▼

左からフェードイン

▼▼▼▼▼ スクロール ▼▼▼▼▼

右からフェードイン

▼▼▼▼▼ スクロール ▼▼▼▼▼

左右からフェードイン

▼▼▼▼▼ スクロール ▼▼▼▼▼

javascript
                  
// フェードイン(再アニメーション対応)

//「.in-fade-up」下からら
//「.in-fade-left」左から
//「.in-fade-right」右から

document.addEventListener('DOMContentLoaded', function () {
  const boxes = document.querySelectorAll('.in-fade-up,.in-fade-left,.in-fade-right');

  const options = {
    root: null,
    rootMargin: '0px 0px -10% 0px',
    threshold: 0
  };

  const observer = new IntersectionObserver(function (entries) {
    entries.forEach(entry => {
      if (entry.isIntersecting) {
        // 画面に入った → アニメーション開始
        entry.target.classList.add('is-active');
      } else {
        // 画面外へ出た → アニメーションをリセット
        entry.target.classList.remove('is-active');
      }
    });
  }, options);

  boxes.forEach(box => observer.observe(box));
});

                  
                
CSS
                  
/* 下からフェードイン */
.in-fade-up {
  opacity: 0;
  visibility: hidden;
  transform: translateY(40px);
  transition: opacity 0.8s ease, transform 0.8s ease;
}
.in-fade-up.is-active {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
}

/* 左からフェードイン */
.in-fade-left {
  opacity: 0;
  visibility: hidden;
  transform: translateX(-100%);
  transition: opacity 0.8s ease, transform 0.8s ease;
}
.in-fade-left.is-active {
  opacity: 1;
  visibility: visible;
  transform: translateX(0);
}

/* 右からフェードイン */
.in-fade-right {
  opacity: 0;
  visibility: hidden;
  transform: translateX(100%);
  transition: opacity 0.8s ease, transform 0.8s ease;
}
.in-fade-right.is-active {
  opacity: 1;
  visibility: visible;
  transform: translateX(0);
}