Jump to content
Search Community

ScrollTrigger + scrub setting - Mousewheel vs scrollbar

shanemielke test
Moderator Tag

Recommended Posts

I'm building a super long scrolling site that involves multiple absolutely positioned bits of text that aren't scrolling with the page but triggered by  scrolling elements. The codepen is just a quick demo to capture the essence of what is happening. In the real project the timing of the text is much more spread out. I LOVE the ScrollTrigger "scrub" setting when using the mouse wheel. But If I physically grab the scrollbar and make a big scroll movement, I get all of my text timelines completing out with the scrub time setting and the effect is a bunch of text all being seen at once that then fades out. Is there a way to have the scrub setting for a scrollTrigger only work on mousewheel but grabbing the scrollbar does not use this setting?

 

I've also tried playing with toggleActions but adding "complete" does not seem to do handle this.

See the Pen QWyqKzy by shanemielke (@shanemielke) on CodePen

Link to comment
Share on other sites

ScrollTrigger just watches the scroll position - it doesn't care HOW that gets changed (mouse wheel, dragging the scrollbar, using the keyboard, touchpad swiping, JavaScript, whatever). I think it'd be kinda weird if it behaved differently for one input than another but maybe I'm weird. Anyway, all that's to say that no, you can't say "use scrub: 1 for everything except when the users drags the scrollbar...in that case use scrub: true". 

 

But if your goal is to prevent all the text from bunching up like that, you could just add a simple ScrollTrigger that's a certain amount beyond the end of each timeline's ScrollTrigger that forces the playhead to the end and kills the scrub tween, like this: 

 

// once it gets 100px past the bottom of the tl1 scrollTrigger, force tl1 to finish and kill the tween of the progress.
ScrollTrigger.create({
  trigger: ".orange",
  start: "bottom top-=100",
  onEnter: () => tl1.progress(1) && gsap.killTweensOf(tl1)
});

And you could do the same for scrolling in the opposite direction with onEnterBack. 

 

Fork:

See the Pen 923b9c472cd39e6ae853605c3cd24063?editors=0010 by GreenSock (@GreenSock) on CodePen

 

 

You could easily automate that setup with a function - let me know if you need any help with that. 

 

By the way, toggleActions are useless when you have a "scrub"  setting. The progress is either linked to the scroll position directly OR it merely toggles the playback state of the animation. Logically it can't be both. In other words, a ScrollTrigger can EITHER scrub OR have toggleActions. 

 

Thanks for providing a reduced test case - super helpful!

 

Happy tweening Shane!

  • Like 1
Link to comment
Share on other sites

Thanks for the insight! Jack....you're not weird! Scrolling is scrolling. I was simply describing the visual in my head. My only end goal is to craft something that looks as I want regardless of what is going on behind the scenes :)

 

Weird your demo didn't work for me. But I understand the concept of it. It gives me some ideas !!!

Link to comment
Share on other sites

2 hours ago, shanemielke said:

Thanks for the insight! Jack....you're not weird! Scrolling is scrolling. I was simply describing the visual in my head. My only end goal is to craft something that looks as I want regardless of what is going on behind the scenes :)

 

Weird your demo didn't work for me. But I understand the concept of it. It gives me some ideas !!!

Hm, maybe I misunderstood what you wanted. When you scroll super fast/far in my demo, are you still seeing the text all visible at the SAME time at the end? It doesn't for me. I only see one. I though that's what you wanted. 

 

What exactly is off about the demo provided? What should act differently? 

Link to comment
Share on other sites

So imagine the above demo didn't have scrub enabled. If you took the scrollbar and went from the top of the document to the bottom of the document very quickly, you would NOT see any of the timeline animations at all. No fade ins. No animations. You might see a tiny little flash or something. But you wouldn't see much else. I want to visually NOT see any of the animations that might happen in the red, orange or purple sections like if you had scrolled with the mouse.

 

It's quite possible that I need to just make everything fromTo...and then possibly add some basic sets in timelines that happen before/after different timelines. I will be exploring my options today.

Link to comment
Share on other sites

I just updated the CodePen and I think it does what you're asking (right?)

 

See the Pen 923b9c472cd39e6ae853605c3cd24063?editors=0010 by GreenSock (@GreenSock) on CodePen

 

Here's a helper function: 

function addKiller(animation, offset) {
  // add one below (as far as the offset) to force the animation to the end.
  ScrollTrigger.create({
    start: () => animation.scrollTrigger.end + offset,
    end: "+=1",
    onEnter: () => animation.progress(1) && gsap.killTweensOf(animation)
  });
  // add one above (as far as the offset) to force the animation to its start.
  ScrollTrigger.create({
    start: () => animation.scrollTrigger.start - offset,
    end: "+=1",
    onEnterBack: () => animation.progress(0) && gsap.killTweensOf(animation)
  });
}

Then all you've gotta do is feed in your animation (the one with the ScrollTrigger) and an offset value which is how far past the end (and above the start) it'll force the animation either to completion or to its start (depending on the scroll direction). 

 

// usage:
addKiller(tl1, 100);
addKiller(tl2, 100);

Does that help at all? 

  • Like 2
Link to comment
Share on other sites

  • 2 weeks later...

This was a big help and has got me started! One thing I noticed though is that I can't seem to console log the the start/end variables for a particular animation inside of your function.

 

See the Pen eYJGMNQ by shanemielke (@shanemielke) on CodePen

 

If you view the console you will see undefined for start/end variables. The reason why I am trying to check the start/end values this is because helper function seems to be triggering early when apply it to animations that have percentage based offsets like the following. 

scrollTrigger: {
	trigger: "#target",
	start: "top bottom",
	end: "bottom top-=100%",
	scrub: 1.5
},

 

Link to comment
Share on other sites

Yep, that's because timelines wait one tick before having the ScrollTrigger do its refresh() logic (which is where it calculates the start and end numbers). 

 

Why?

 

Timelines are very unique in the sense that they're populated AFTER they're created. When you call gsap.timeline({...scrollTrigger:{...}}), the timeline is completely empty. Zero duration. The ScrollTrigger waits for one tick to perform its refresh() so that there's actually data in there to work with and calculate things properly (otherwise setting the progress of the animation, for example, couldn't work). This is a GOOD thing. It's not necessary for individual tweens because they don't get populated after instantiation, thus they can refresh() right away. 

 

It waits for 1 tick because there's no way of automatically knowing how much you're gonna add to that timeline on the current tick. But in your case, you know when you're done adding to it, so you can simple call refresh() on the ScrollTrigger instance manually to have it calculate the start/end values. 

 

So the short answer is to add this to the top of your addKiller() function: 

animation.scrollTrigger.refresh();

Make sense? 

  • Like 1
Link to comment
Share on other sites

THANK YOU. It makes complete sense. It was tripping me out that I could see the start/end in the console log of the animation but not when targeting the attribute directly. Congrats on the latest updates. They look amazing! I'll be poking at them tonight!

  • Thanks 1
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...