All videos
Infinite marquee animation on scroll

Infinite marquee animation on scroll

In this leson, you’ll build a looping text marquee from scratch using duplicate content, flexbox layout, and precise animation settings. Then, you’ll take it further by using scroll trigger actions to control when the animation plays, pauses, and reverses, keeping your site both polished and performant.

Video transcript

[Cassie] We’re going to be creating an infinitely looping marquee using Webflow interactions, powered by GSAP’s ScrollTrigger.

[Grímur] Cassie, is it really infinite?

[Cassie] You can keep an eye on it and let me know if it stops.

We’ll start by creating the marquee animation and looping it, and then we’ll show how you can use trigger actions to control the animation state as it scrolls in and out of view.

Now, I think animation is pretty magical, but to be honest, 90% of the magic here is in the setup.

Here we have a marquee track with duplicate marquee content elements inside. These marquee content elements are lined up in a row with flexbox, and the marquee element has overflow hidden set to hide the content that’s overflowing.

As we animate the marquee content to the left, we need the visible area to stay filled at all times, and a single content group can’t do that. Once it moves across and off the screen, there’s a big blank gap before it loops back. With two groups, by the time the first group has moved offscreen, the second one has filled the view, and we can snap the animation back to the start position without anyone noticing.

[Grímur] That does sound like magic.

[Cassie] It does, doesn't it? Right, let’s set this up using Webflow interactions. With the marquee selected, we’ll open the Interactions panel and create a new scroll trigger. Let’s rename this interaction to “text marquee.” If we open the trigger settings, you can see that the marquee is the trigger element. And if we move down here, you’ll see there are two options: “Scrub on scroll” and “Trigger actions.”

Scrubbed interactions are tied to scroll progress. Scrolling down advances the animation, and scrolling back up reverses it.

Triggered scroll interactions fire off when you cross a threshold. When a trigger element passes a start point, the animation will play through on its own.

We’ll come back to these settings to demystify them in a bit, but for now, let’s just choose “Trigger actions.” The default settings are all we need, so let’s close this and set up our action.

We’ll choose an animate action and rename this to “move marquee content.” Let’s set up the action target, and we want to target both of our marquee content elements by using the shared class. You’ll notice that the filter is set to within the trigger element, so we’re only targeting the elements within the trigger, which is the marquee.

We just need the Move X property here, so we’ll remove these others. If we animate both of our elements 100% of their width to the right, you can see what happens if there’s no duplicate element waiting to fill the space. We’ll scrub the timeline at the bottom here, and oop, there’s that awkward gap.

But if we animate 100% of their width to the left, so minus 100% here, our duplicate element moves in to fill the space.

Now if we scrub the timeline playhead, we can see that we get a seamless animation. Because the start and the end of the animation are identical, we can just repeat this and we’ll get a seamless loop.

In our action settings, we’ll set the repeat to infinite. If we press play, this will seamlessly loop now. It’s a little fast, so let’s set the duration to 5 seconds and click play to preview it.

Almost there, but notice how it’s speeding up and slowing down before every repeat. This is because we have the default ease of power1.out selected. This is doing what it does best, controlling the progress over time, speeding it up at the start and then easing it out at the end. But this isn’t what we want for a marquee. We want a marquee to advance continuously, so we’ll choose a linear ease.

Let’s hit play, and that’s much better. Five seconds is still a bit fast, so let’s go for 15 seconds. That’s much better.

So that was our marquee animation, but we can take this further with trigger controls.

Let’s go back out and open up our trigger settings and look at how the start and end positions work.

Right now, it’s playing when the top of the marquee element hits the bottom of the viewport. If we show scroll markers, you can see that the start point is when these little green markers align.

This looks exactly how we want, but stick with me. The end position and these other options exist for a reason. For demo purposes, let’s move the start and end points a little further into the page. We’ll say start when the top of the marquee hits 80% of the way down the viewport, and end when the bottom of the marquee hits 20% of the way down the viewport.

Now we can see the scroller start and scroller end markers have moved further into the canvas.

So with our current trigger actions set up, we’re just saying play this animation when it comes into view, but nothing else happens when it passes out of our trigger scroll area.

When we have an infinitely looping animation, it’s good practice to pause it when it’s out of view so that it’s not continuously animating and using up browser resources. We can do that with trigger actions. Let’s say when the marquee element leaves, when it passes through the end scroll markers, pause the animation. Now when we scroll past the end, the animation pauses. Perfect.

Let’s use enter back to choose how it behaves when it comes back into view. We can choose reverse to play the animation in reverse, so now it’s animating to the right.

And lastly, we’ll set leave back to pause when we leave while scrolling in the other direction.

Let’s scroll through this marquee slowly and note the changes we made. As the element enters the scroll area, our animation plays. When it leaves, the animation pauses. When the element enters back again, it will play in reverse. And finally, when it leaves back out of the bottom, it will pause.

These trigger action controls let you fine-tune how your animation behaves as each of these four scroll points is passed.

Let’s reset our start and end positions back to the default, and now we have a lovely marquee animation that loops infinitely.

It looks great, but it’s also set up responsibly by pausing when it’s out of view to keep your site nice and performant.

Grímur, is it still looping infinitely for you?

[Grímur] No, it’s not.

[Cassie] Oh okay, let’s look at it again.

[Grímur] It’s because my laptop died.

[Cassie] Alright. Let’s find you a charger.