<div class="reveal">
      Hello, World!
    </div>
    <div class="reveal">
      <div class="cover"></div>
      Welcome to the show!
    </div>
    <div class="reveal">
      <div class="cover"></div>
      This is a test.
    </div>

      body,
      html {
        height: 300%;
      }
      .reveal {
        position: relative;
        top: 200px;
        width: 50%;
        margin: 200px auto;
        font-size: 30px;
        overflow: hidden;
		font-weight: bold;
      }
      .cover {
        position: absolute;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        background-color: black;
        clip-path: inset(0 0% 0 0); /* 初期状態でカバーが全面にあるように */
      }
document.addEventListener("DOMContentLoaded", function () {
  const observer = new IntersectionObserver(
    (entries) => {
      entries.forEach((entry) => {
        if (entry.isIntersecting) {
          const cover = entry.target.querySelector(".cover");
          const duration = 300; // アニメーションの継続時間 (ミリ秒)
          let start = null;

          function step(timestamp) {
            if (!start) start = timestamp;
            const progress = timestamp - start;
            const percentage = Math.min(100, (progress / duration) * 100);
            cover.style.clipPath = `inset(0 0 0 ${0 + percentage}%)`;
            if (progress < duration) {
              window.requestAnimationFrame(step);
            } else {
              observer.unobserve(entry.target); // アニメーション完了後に監視を停止
            }
          }

          window.requestAnimationFrame(step);
        }
      });
    },
    {
      threshold: 1, // 要素が50%表示された時にトリガー
    }
  );

  const elements = document.querySelectorAll(".reveal");
  elements.forEach((element) => observer.observe(element));
});
Run Pen

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.