iDad5 Posted March 13, 2022 Posted March 13, 2022 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?
akapowl Posted March 13, 2022 Posted March 13, 2022 Do you mean something like this @iDad5 ? https://greensock.com/docs/v3/Plugins/ScrollTrigger/static.isScrolling()
iDad5 Posted March 13, 2022 Author Posted March 13, 2022 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.
Solution mikel Posted March 13, 2022 Solution Posted March 13, 2022 21 minutes ago, iDad5 said: I need an event i can listen to with addEventListener. Hey @iDad5, You could use ScrollTrigger.addEventListener. Here an example See the Pen c1099fe6d3d8c43ec2b928f006551450?editors=1010 by mikeK (@mikeK) on CodePen. Happy scrolling ... Mikel 5
akapowl Posted March 13, 2022 Posted March 13, 2022 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. 4
iDad5 Posted March 13, 2022 Author Posted March 13, 2022 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) 1
iDad5 Posted March 13, 2022 Author Posted March 13, 2022 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...
Shrug ¯\_(ツ)_/¯ Posted March 13, 2022 Posted March 13, 2022 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. ? 1
iDad5 Posted March 13, 2022 Author Posted March 13, 2022 @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 :-). 2
Shrug ¯\_(ツ)_/¯ Posted March 13, 2022 Posted March 13, 2022 ¯\_(ツ)_/¯ Maybe @GreenSock will shed some of his genius upon the subject in addition to the nice thoughts both @mikel & @akapowl provided. ? 1
GreenSock Posted March 14, 2022 Posted March 14, 2022 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. 2
iDad5 Posted March 14, 2022 Author Posted March 14, 2022 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.
GreenSock Posted March 15, 2022 Posted March 15, 2022 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.
iDad5 Posted March 15, 2022 Author Posted March 15, 2022 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. 1
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now