DEV Community

Cover image for Horizontal Scrolling Animation using GSAP and ScrollTrigger.
ksbisht
ksbisht

Posted on • Originally published at ksbisht.Medium

Horizontal Scrolling Animation using GSAP and ScrollTrigger.

We love animation. In the animated movies, video games, advertisements, etc. but here we are going to create a horizontal scrolling animation using GSAP and ScrollTrigger. As you guess by reading the title. So let’s get started.

Matching the look

The first thing I want to do with this component is to match the design. probably this will be the easiest part since there are no complicated graphics that will need SVG or icons.

Inside our component, I will start by creating the markup for the animation. The markup design divides into two sections, first design the very simple landing that appear at the first sight of the page and the second section appears on scrolling the page.

    <div class="demo-wrapper">
      <header class="df aic jcc">
        <div>
          <h1>ScrollTrigger</h1>
          <h2>demo</h2>
        </div>
      </header>
      <section class="demo-text">
        <div class="wrapper text">ABCDEFGHIJKLMNOPQRSTUVWXYZ</div>
      </section>
      <section class="demo-gallery">
        <ul class="wrapper">
          <li>
            <img
              height="317"
              src="https://source.unsplash.com/random/450x317?sig=128"
              width="450"
            />
          </li>
          <li>
            <img
              height="317"
              src="https://source.unsplash.com/random/450x317?sig=10"
              width="450"
            />
          </li>
          <li>
            <img
              height="317"
              src="https://source.unsplash.com/random/450x317?sig=91"
              width="450"
            />
          </li>
        </ul>
      </section>
      <section class="demo-gallery">
        <ul class="wrapper">
          <li>
            <img
              height="317"
              src="https://source.unsplash.com/random/450x317?sig=12"
              width="450"
            />
          </li>
          <li>
            <img
              height="317"
              src="https://source.unsplash.com/random/450x317?sig=20"
              width="450"
            />
          </li>
          <li>
            <img
              height="317"
              src="https://source.unsplash.com/random/450x317?sig=145"
              width="450"
            />
          </li>
          <li>
            <img
              height="317"
              src="https://source.unsplash.com/random/450x317?sig=22"
              width="450"
            />
          </li>
        </ul>
      </section>
      <section class="demo-gallery">
        <ul class="wrapper">
          <li>
            <img
              height="317"
              src="https://source.unsplash.com/random/450x317?sig=61"
              width="450"
            />
          </li>
          <li>
            <img
              height="317"
              src="https://source.unsplash.com/random/450x317?sig=70"
              width="450"
            />
          </li>
          <li>
            <img
              height="317"
              src="https://source.unsplash.com/random/450x317?sig=112"
              width="450"
            />
          </li>
        </ul>
      </section>
      <section class="demo-gallery">
        <ul class="wrapper">
          <li>
            <img
              height="317"
              src="https://source.unsplash.com/random/450x317?sig=88"
              width="450"
            />
          </li>
          <li>
            <img
              height="317"
              src="https://source.unsplash.com/random/450x317?sig=35"
              width="450"
            />
          </li>
          <li>
            <img
              height="317"
              src="https://source.unsplash.com/random/450x317?sig=92"
              width="450"
            />
          </li>
        </ul>
      </section>
      <section class="demo-text">
        <div class="wrapper text">ABCDEFGHIJKLMNOPQRSTUVWXYZ</div>
      </section>
    </div>
Enter fullscreen mode Exit fullscreen mode

Styling!

I know the page is looking ugly right now, let’s change that:

:root {
  font-size: 16px;
}
@media (max-width: 500px) {
  :root {
    font-size: 14px;
  }
}

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

::-moz-selection {
  background: #87cd33;
  color: white;
}

::selection {
  background: #87cd33;
  color: white;
}

body {
  overflow: hidden;
  font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Helvetica, Arial,
    sans-serif, Apple Color Emoji, Segoe UI Emoji;
}

h1 {
  font-size: 5rem;
}
h2 {
  font-size: 2rem;
}

img {
  width: 100%;
  height: auto;
  background: #f0f0f0;
}

ul {
  padding-left: 1rem;
  list-style: none;
}

li {
  flex-shrink: 0;
  width: clamp(500px, 30vw, 800px);
  padding-right: 1rem;
}

header {
  height: 100vh;
}
footer {
  height: 50vh;
}

:-webkit-any-link {
  color: #4e9815;
}

:-moz-any-link {
  color: #4e9815;
}

:any-link {
  color: #4e9815;
}

.df {
  display: flex;
}
.aic {
  align-items: center;
}
.jcc {
  justify-content: center;
}

.loader {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: black;
  color: white;
}

.demo-wrapper {
  overflow-x: hidden;
}

.wrapper {
  display: flex;
}

.demo-gallery:not(.last) {
  padding-bottom: 1rem;
}

.demo-text .text {
  font-size: clamp(8rem, 15vw, 16rem);
  line-height: 1;
  font-weight: 900;
}
Enter fullscreen mode Exit fullscreen mode

This is the final look of our page after styling!
Alt Text

Time To Logic

First, we need to include GSAP and ScrollTrigger in our project, for this example, we will use the unpkg, this needs to be added in the HTML inside a script tag.

<script src="https://unpkg.co/gsap@3/dist/gsap.min.js"></script>
<script src="https://unpkg.com/imagesloaded@4/imagesloaded.pkgd.min.js"></script>
<script src="https://unpkg.com/gsap@3/dist/ScrollTrigger.min.js"></script>
Enter fullscreen mode Exit fullscreen mode

Let’s trigger the animation when we scroll our web page. By using this script.

<script>
      gsap.registerPlugin(ScrollTrigger);
      const images = gsap.utils.toArray("img");
      const showDemo = () => {
        document.body.style.overflow = "auto";
        document.scrollingElement.scrollTo(0, 0);

        gsap.utils.toArray("section").forEach((section, index) => {
          const w = section.querySelector(".wrapper");
          const [x, xEnd] =
            index % 2
              ? ["100%", (w.scrollWidth - section.offsetWidth) * -1]
              : [w.scrollWidth * -1, 0];
          gsap.fromTo(
            w,
            { x },
            {
              x: xEnd,
              scrollTrigger: {
                trigger: section,
                scrub: 0.5,
              },
            }
          );
        });
      };

      imagesLoaded(images).on("always", showDemo);
    </script>
Enter fullscreen mode Exit fullscreen mode

Congratulation! We did it. This is the final look at our web page.

Alt Text

Okay guys, hope so you learn something new with me. By the way, this is my first blog ever. If you have any ideas on how to improve this I’d love to read them in the comments.

Thanks.

Discussion (1)

Collapse
mooh07 profile image
Tetbirt Mohamed Hassene

not sure if you need this advice after almost a year but when writing blogs you are trying to explain stuff to people, stuff they aren't comfortable with, try to make variable names more friendly so the reader can understand clearly your logic, or even better explain each part of the code and what it does, for example you can assume a reader is new to gsap and just state that, first argument is the object to be animated, second is the initial start position and third is the to position.

It might be clear to you but someone new might find this daunting.