<section class="panel">
  content
</section>
<section class="panel">
  content
</section>

<section class="module_3_wrapper scroll">
    <div class="module_3">
        <div class="slides">
            <div class="flex">
                <div class="flex-child one">
                    slide 1 left content
                </div>
                <div class="flex-child two">
                    slide 1 right content
                </div>
            </div>
        </div>
        <div class="slides">
            <div class="flex">
                <div class="flex-child one">
                    slide 2 left content
                </div>
                <div class="flex-child two">
                    slide 2 right content
                </div>
            </div>
        </div>
        <div class="slides">
            <div class="flex">
            <div class="flex">
                <div class="flex-child one">
                    slide 3 left content
                </div>
                <div class="flex-child two">
                    slide 3 right content
                </div>
            </div>
            </div>
        </div>

    </div>
</section>

<section class="panel">
  content
</section>


<section class="panel">
  content
</section>


<section class="panel">
  content
</section>
.module_3_wrapper {
    min-height: 100vh;
    background-image: url(assets/images/wrapper.background);
    background-size: 100% 100%;
    background-repeat: no-repeat;
    background-position: bottom center;
    overflow: hidden;
    background-color: grey
}

.module_3 {
    width: 300%;
    height: 100%;
    display: flex;
    flex-wrap: nowrap;
    flex-direction: row;
    /* align-items: center; */
    justify-content: center;
}

.module_3 .slides {
    align-items: center;
    display: inline-flex;
    width: 100vw;
    border: solid 2px red;
    padding: 0 0 0 0;
}

.panel {
  height: 100vh;
  width: 100vw;
}


.flex {
    flex-direction: row;
}

.flex-child {
    /* align-items: center; */
    justify-content: center;
    display: flex;
    flex: 50%;
}
gsap.registerPlugin(ScrollTrigger);
gsap.registerPlugin(ScrollToPlugin);

const tl2 = gsap.timeline({
  scrollTrigger: {
    trigger: ".module_3_wrapper",
    start: "center center",
    end: "center center",
    pin: ".module_3_wrapper",
    scrub: 1,
    pinSpacing: true
  }
});

let container = document.querySelector(".module_3");

let sections = gsap.utils.toArray(".module_3 .slides");

// create a timeline instead of a tween so we can space out incremental movement with pauses in between
let scrollTL = gsap.timeline({
  scrollTrigger: {
    trigger: ".module_3_wrapper",
    pin: true,
    start: "center center",
    scrub: true,
    invalidateOnRefresh: true,
    end: `+=${container.offsetWidth * 3}`
  }
});

// work out how much to move the container by each time
let increment =
  (container.scrollWidth -
    document.querySelector(".module_3_wrapper").clientWidth) /
  (sections.length - 1);

// loop round and add small spaced out movements to a timeline, if it's the last tween add an empty tween for padding
sections.forEach((section, index) => {
  if (index === sections.length) {
    // empty tween for padding
    scrollTL.to(
      sections,
      {
        ease: "none",
        duration: 0.1
      },
      "+=0.3"
    );
  } else {
    
    
    scrollTL.to(
      section.querySelector('.slides .flex-child.one'),
      {
        x: () => 150,
        ease: "none",
        duration: 0.1,
      }
    );
    
    
    scrollTL.to(
      sections,
      {
        x: () => `-=${increment}px`,
        ease: "none",
        duration: 0.1
      },
      "+=0.3"
    );
        
  }
});

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://cdnjs.cloudflare.com/ajax/libs/gsap/3.9.1/gsap.min.js
  2. https://cdnjs.cloudflare.com/ajax/libs/gsap/3.9.1/ScrollTrigger.min.js
  3. https://cdnjs.cloudflare.com/ajax/libs/gsap/3.9.1/ScrollToPlugin.min.js