Dummy Area

Libraries

  • GSAP v3.12.5
  • GSAP Plugins - ScrollTrigger v3.12.5

Sample Code

Libraries

<script src="https://cdn.jsdelivr.net/npm/gsap@3.12.5/dist/gsap.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/gsap@3.12.5/dist/ScrollTrigger.min.js"></script>

index.html

<div class="p-panel-scroll">
  <div class="p-panel-scroll__images">
    <div class="p-panel-scroll__images-inner js-panelItemContainer">
      <div class="p-panel-scroll__item"></div>
      <div class="p-panel-scroll__item js-panelItem"></div>
      <div class="p-panel-scroll__item js-panelItem"></div>
      <div class="p-panel-scroll__item js-panelItem"></div>
      <div class="p-panel-scroll__item js-panelItem"></div>
    </div>
  </div>
  <div class="p-panel-scroll__placeholder"></div>
</div>

style.css

@charset "UTF-8";
.p-panel-scroll {
  --panel-aspect-ratio: 600 / 1280; /* パネル表示領域のアスペクト比 */
  --panel-aspect-ratio-percent: calc(
    var(--panel-aspect-ratio) * 100%
  ); /* アスペクト比のパーセンテージ */
  --panel-width-percent: 35.234375%; /* パネルの幅 */
  --panel-gap-percent: calc(
    var(--panel-width-percent) / 2
  ); /* パネル同士の半分の重なり */
}

.p-panel-scroll__images {
  position: sticky;
  top: 0;
  padding: calc((100vh - var(--panel-aspect-ratio-percent)) / 2) 0;
}

.p-panel-scroll__images-inner {
  overflow: hidden;
  position: relative;
  width: 100%;
  height: 0;
  padding-bottom: var(--panel-aspect-ratio-percent);
}

.p-panel-scroll__item {
  position: absolute;
  top: 0;
  width: var(--panel-width-percent);
  aspect-ratio: var(--panel-aspect-ratio);
}

.p-panel-scroll__item:nth-of-type(1) {
  left: 0;
  background-color: var(--color-primary);
}

.p-panel-scroll__item:nth-of-type(2) {
  left: calc(var(--panel-gap-percent));
  background-color: var(--color-secondary);
}

.p-panel-scroll__item:nth-of-type(3) {
  left: calc(var(--panel-gap-percent) * 2);
  background-color: var(--color-tertiary);
}

.p-panel-scroll__item:nth-of-type(4) {
  left: calc(var(--panel-gap-percent) * 3);
  background-color: var(--color-quaternary);
}

.p-panel-scroll__item:nth-of-type(5) {
  right: 0;
  background-color: var(--color-quinary);
}

.p-panel-scroll__placeholder {
  height: 150vh;
}

index.js

document.addEventListener("DOMContentLoaded", () => {
  // デバッグモードを有効にする
  const DEBUG_MODE_ENABLED = true;

  // コンテナごとに処理を実行
  const containers = document.querySelectorAll(".js-panelItemContainer");

  containers.forEach((container) => {
    // コンテナ内のパネルを取得
    const panels = container.querySelectorAll(".js-panelItem");

    // タイムラインを作成し、スクロールトリガーと連携させる
    const timeline = gsap.timeline({
      scrollTrigger: {
        trigger: container,
        start: "top center",
        end: () => "+=" + container.offsetHeight, // コンテナの高さに基づいてend位置を設定
        scrub: 0.7,
        markers: DEBUG_MODE_ENABLED,
      },
    });

    // 各パネルに対してアニメーションを追加
    panels.forEach((panel) => {
      timeline.from(
        panel,
        {
          x: "15%",
          opacity: 0,
          duration: 1,
        },
        "+=0.5",
      ); // 前のアニメーションが終了してから0.5秒後に次のアニメーションを開始
    });
  });
});