ScrollTrigger, move element down, fade out, then start horizontal scroll

I’ve been experimenting with ScrollTrigger in order to achieve a multistep animation.

In short, here is my expected behaviour / what I’m trying to achieve:
 

  1. User scrolls down the page and .horizontalScroller__intro pins and moves down to the center of my .horizontalScroller which I’ve currently defined as end: "+=30%").
  2. Once it has reached the end, as the user continues to scroll down, I now want .horizontalScroller__intro to fade out slowly.
  3. Once .horizontalScroller__intro has faded out completely, I now want to fade in .horizontalScroller__items which has an opacity of 0 in the css.
  4. Once .horizontalScroller__items has faded in completely, I want the user to be able to scroll horizontally.
  5. Then the reverse when the user is scrolling back up
     

Current results:

  1. .horizontalScroller__intro starts to fade out immediately (and is completely gone by the end position). I’m looking for .horizontalScroller__intro to start fading out after it has reached its end position. 

  2. I have a separate scrollTrigger defined for the horizontal scroll (which just contains an image). When this trigger is used alongside the .horizontalScroller__intro trigger, the .horizontalScroller__intro jumps. Cannot get the .horizontalScroller__items to fade in (unsure if it doesn’t like it because it’s defined in the css?)

 
What have I tried?

 const tl = gsap.timeline( {
  scrollTrigger: {
    trigger: ".horizontalScroller__intro",
    start: "top",
    end: "+=30vh",
    scrub: true,
    // markers: true,
    toggleActions: "play reverse play reverse",
  }

});

tl
  .to('.horizontalScroller__intro', { autoAlpha: 1, duration: 0.5 })
  .to('.horizontalScroller__intro', { autoAlpha: 0, duration: 0.5 }, 0.5);

Appreciate I’ve asked a few questions in this post. Any help would be appreciated 🙂

Demo:

$(function() {

  let container = gsap.utils.toArray(".horizontalScroller__items");

  gsap.to(container, {
    x: () => -(document.querySelector('.horizontalScroller__items').scrollWidth - document.documentElement.clientWidth) + "px",
    xPercent: -100 * (container.length - 1),
    ease: "none",
    scrollTrigger: {
      trigger: ".horizontalScroller",
      // markers: true,
      pin: true,
      anticipatePin: 1,
      scrub: true,
      invalidateOnRefresh: true,
      refreshPriority: 1,
      end: () => "+=" + document.querySelector('.horizontalScroller__items').offsetWidth,
      onToggle: scrollTrigger => {
        scrollTrigger.refresh()
      },
    }
  });


  const tl = gsap.timeline( {
    scrollTrigger: {
      trigger: ".horizontalScroller__intro",
      start: "top",
      end: "+=30vh",
      scrub: true,
      // markers: true,
      toggleActions: "play reverse play reverse",
    }

  });

  tl
    .to('.horizontalScroller__intro', { autoAlpha: 1, duration: 0.5 })
    .to('.horizontalScroller__intro', { autoAlpha: 0, duration: 0.5 }, 0.5);


});
.spacer {
  height: 100vh;
  background: lightblue;
}

.horizontalScroller {
  padding: 60px 0;
  height: 100vh;
  position: relative;
  overflow: hidden;
}
@media (min-width: 768px) {
  .horizontalScroller {
    padding: 140px 0 80px 0;
  }
}
@media (min-width: 1200px) {
  .horizontalScroller {
    padding: 114px 0 80px 0;
  }
}
.horizontalScroller__intro {
  margin-bottom: 90px;
}
.horizontalScroller__header {
  margin-bottom: 17px;
}
.horizontalScroller__scroll {
  position: absolute;
  overflow: hidden;
  top: 0;
}
.horizontalScroller__items {
  position: relative;
  height: 100vh;
  width: 100%;
}
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js" integrity="sha512-894YE6QWD5I59HgZOGReFYm4dnWc1Qt5NtvYSaNcOP+u1T9qYdvdihz0PPSiiqn/+/3e7Jo4EaG7TubfWGUrMQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>

<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.9.1/gsap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.9.1/ScrollTrigger.min.js"></script>

<section class="spacer"></section>

<section class="horizontalScroller">

  <div class="container">
    <div class="row justify-content-center">
      <div class="col-12 col-md-8 col-xxl-10">
        <div class="horizontalScroller__intro text-center index-top">
          <h2 class="horizontalScroller__header">This is the header</h2>
          <p class="horizontalScroller__standfirst mb-0 display--1">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
        </div>
      </div>
    </div>
  </div>

  <div class="horizontalScroller__scroll">
    <div class="horizontalScroller__items" id="horizontal-scroll">
      <img src="https://i.imgur.com/jlXz4II.png" alt="test" />
    </div>
  </div>

</section>

<section class="spacer"></section>

Note: if you comment out the second scrollTrigger you will see the pin of the intro somewhat working.