Jump to content
GreenSock

iDad5

is there a ScrollTriger event for scrolling?

Moderator Tag
Go to solution Solved by mikel,

Recommended Posts

Situation: I have an animation sequence where at some point the user can take over control of the animation and scrub it (using ScrollTrigger of course).

I need the sequence to be finished to go on with the rest. So if the user takes control by scrolling, but does not finish the job (no onComplete callback) I have to watch for this inactivity and auto-play the associated timeline.

 

So I set up a timeout and if that is reached I just play the timeline. I just need to kill that timer when/if the user continues to scroll in that period. I can always listen to a generic JavaScript scroll event to accomplish this, but it would somehow feel more consistent to me if I could listen to a ScrollTrigger 'isScrolled' - or something like it - event. I could not find something like it in the docs and it might just not exist, but maybe one of you super Heros has a suggestion?

Link to comment
Share on other sites

Thanks @akapowl but that wouldn't work.

 

I need an event i can listen to with addEventListener. 

If that event isn't firing for (let's say) 2 seconds I play the timeline. 

 

Right now I'm using: 

ScrollTrigger.getById('stageOpenScrollTrigger').trigger.addEventListener('scroll', this.resetScrollInactivityTimer);

That works fine but is somehow hard to read. A SrollTriger('s instnace) native event would feel somehow clearer and saver to me. But probably that event does not exist as it would add to complexity and could potentially  cost performance.

Link to comment
Share on other sites

Yeah , I was about to suggest something similar to what mikel did.

I'm not sure if that is any more helpful than what you already did yourself there, though.

 

See the Pen KKZKeOQ by akapowl (@akapowl) on CodePen

  • Like 4
Link to comment
Share on other sites

Thank you both. I had seen the events 'scrollStart' and 'scrollEnd' and I likely misread their functionality and somehow I didn't like that they were static methods. I would have preferred it to be only connected to the scroll of the specific instance but that's very theoretical I guess).

 

I'll give it a try, especially as my solution actually didn't work. The scroll event on the target didn't fire. (I have a rather complex css construction and scrolling works, but I cannot figure out which element is actually scrolling - neither body or window worked.... One never ceases to learn)

  • Like 1
Link to comment
Share on other sites

Using ScrollTrigger.addEventListener('scrollStart') did the trick. I misunderstood the documentation, thinking that if worked more like the onEnter callback. Thanks for helping me out!

 

I share my additional learnings for maybe it'll help someone else to figure it out faster:

My solution didn't work for two reasons, the ScrollTrigger.trigger is the element that is 'moved' the scroll-event however is fired on the element that holds this element. I tried to solve this by targeting the .parentElement - but as i was using pining however the pin-spacer created by ScrollTrigger was that parent and the container element that received the scroll-event was the pin-spacers parent...



 

Link to comment
Share on other sites

11 hours ago, iDad5 said:
  • control of the animation and scrub it using ScrollTrigger
  • if the user takes control by scrolling, but does not finish the job
  • watch for this inactivity and auto-play the associated timeline

👍 I’ve thought about this scenario in the past also. When using ScrollTrigger scrub and wanting that scrub effect but then if the user stops at a certain % to finish the tween / timeline and yet accurately still retain all the scrub / ScrollTrigger features when the user recommences scrolling. I never really dove into it though (some things happened that averted my focus 🤕 ) to decide what would be best. It's still a bit of a mind puzzle as I try to rethink on it. 😂

 

  • Like 1
Link to comment
Share on other sites

@Shrug ¯\_(ツ)_/¯ I feel you. It is an intriguing concept, but it has some complexities. 

The way @GreenSock set ScrollTrigger up is totally genius especially all the (necessary) performance optimizations built into it.

In my (our) scenario though the fact that a lot of things are prepared when instantiating the ScrollTrigger(s) takes some mind bending for an old mind like mine. For technical and logical reasons ist simply often not possible to change a SrollTrigger instance on the fly, you have to kill and rebuild it - at lest that's what I found. Probably I was just using it the wrong way. 

It was a bit tricky and certainly not cost efficient (at least in my use-case it was more 'l'art pour l'art') but in the end it's always just impressing what magic greensock tools have built into. Also humbling :-).  

  • Like 2
Link to comment
Share on other sites

16 hours ago, iDad5 said:

My solution didn't work for two reasons, the ScrollTrigger.trigger is the element that is 'moved' the scroll-event however is fired on the element that holds this element. I tried to solve this by targeting the .parentElement - but as i was using pining however the pin-spacer created by ScrollTrigger was that parent and the container element that received the scroll-event was the pin-spacers parent...

 

I think you were looking for the ScrollTrigger's "scroller", not "trigger". 

 

6 hours ago, Shrug ¯\_(ツ)_/¯ said:

¯\_(ツ)_/¯ Maybe @GreenSock will shed some of his genius upon the subject in addition to the nice thoughts both @mikel & @akapowl provided. 😉

Here's an idea: 

let autoScrollSpeed = 100, // pixels per second
    scrollTimeout = gsap.delayedCall(2, () => { // use a delayed call for however long you want to wait after scrolling stops (2 seconds here)
      if (tl.progress() < 1) { // if it's not done, 
        gsap.to(window, {
          scrollTo: tl.scrollTrigger.end, 
          duration: (tl.scrollTrigger.end - tl.scrollTrigger.scroll()) / 100 * autoScrollSpeed
        });
      }
    }).pause(); // pause it initially
ScrollTrigger.addEventListener("scrollStart", () => scrollTimeout.pause());
ScrollTrigger.addEventListener("scrollEnd", () => scrollTimeout.restart(true));

 

7 hours ago, Shrug ¯\_(ツ)_/¯ said:

👍 I’ve thought about this scenario in the past also. When using ScrollTrigger scrub and wanting that scrub effect but then if the user stops at a certain % to finish the tween / timeline and yet accurately still retain all the scrub / ScrollTrigger features when the user recommences scrolling. I never really dove into it though (some things happened that averted my focus 🤕 ) to decide what would be best. It's still a bit of a mind puzzle as I try to rethink on it. 😂

 

This sounds like a tricky logic challenge unless I'm misunderstanding. What you're describing sounds like "it's linked...but then I want to unlink it....and then it gets totally out of sync and I want to re-synchronize it gradually" but what if the user scrolls forward and it starts re-syncing and then they scroll backwards? What if they resize the page partway through or refresh? I mean I suppose with enough elbow grease you could animate a virtual scrubber like that but it doesn't sound simple. 

  • Like 2
Link to comment
Share on other sites

4 hours ago, GreenSock said:

I think you were looking for the ScrollTrigger's "scroller", not "trigger". 

 

That should have jumped on me and bitten in my behind...

Thanks for pointing it out.

 

For reasons I don't fully understand I had to change my code to use the JS native scroll-event on the scroller eventually. Yesterday using ScrollTrigger's scrollStart event seem to work fine, today however. It seems the scrollStart Event doesn't fire reliably or maybe not fast enough for shorter waiting times. Most likely though I guess I messed something up. 

Link to comment
Share on other sites

18 hours ago, iDad5 said:

For reasons I don't fully understand I had to change my code to use the JS native scroll-event on the scroller eventually. Yesterday using ScrollTrigger's scrollStart event seem to work fine, today however. It seems the scrollStart Event doesn't fire reliably or maybe not fast enough for shorter waiting times. Most likely though I guess I messed something up. 

Are you saying that scrollStart doesn't fire consistently for you? Got a minimal demo we could check? I don't see any issues. 

Link to comment
Share on other sites

I’m pretty sure that it’s not so much a problem with ScrollTrigger as it used to work well, when I first implemented it. 
As I said the whole system is rather complex and I have to kill and rebuild the ScrollTrigger according to user behavior. That might be causing issues and I might have made a logical error somewhere. 
For the moment I’m fine with my solution but if I find the time to revisit the potential issue I will. 
If I find that there is an actual problem with the ScrollTrigger event I will try to build a ‘minimal’ demo, as I like a challenge. 

  • 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.
×