Jump to content
Search Community

ScrollTrigger.kill() sometimes not working

iDad5 test
Moderator Tag

Go to solution Solved by OSUblake,

Recommended Posts

Sorry, I cannot provide a CodePen in this case, it happens only occasionally, and i a complex environment.

 

I have a page with panels that is controlled by a ScrollTrigger. All in all that works very well.

If the user resizes the page, I need to to some recalculations and therefore need to (temporarily) reset everything to its' initial state. The only workable way I found was to kill my one and only ScrollTrigger instance reset everything, do my calculations and then rebuild. 

 

This is how I do it:

 

private handleResize = (e:Event):void => { //is triggerd delayed 500 ms after window.rezize
		console.log('resize to handle');
		....
		try{
			this.scrolTrigger.kill();
		} catch {
			console.log('No scrollTrigger?');
			console.log(this.scrolTrigger);
		} finally {
			console.log('All scroll triggers:' + JSON.stringify(ScrollTrigger.getAll()));
		}
		this.scrolTrigger = null;
		....
	}

 

There is only one ScrollTrigger instance ever present.  This instance logs onToggle and onSnapComplete events (there is an inconsistency I have a workaround for).

 

In some cases I get this console:

main.ts:648 resize to handle
main.ts:680 Uncaught TypeError: Converting circular structure to JSON
    --> starting at object with constructor 'Window'
    --- property 'window' closes the circle
    at JSON.stringify (<anonymous>)
    at MMHR22Manager.handleResize (main.ts:680)
    at dispatchDelayedEvent (mmUtil.ts:30)
MMHR22Manager.handleResize @ main.ts:680
dispatchDelayedEvent @ mmUtil.ts:30
setTimeout (async)
runer @ mmUtil.ts:24
main.ts:923 toggle @: panel0 id: 0
main.ts:923 toggle @: panel0 id: 0
main.ts:923 complete @: panel0 id: 0

the error on main.ts 680 is in the finally block and usually/mostly reports: 'All scroll triggers:[]' - as is to be expected.

 

(if I use 'ScrollTrigger.getAll().length' instead of JSON.stringify for reporting I don't get the TypeError, but 1 if the kill-process seems to fail and 0 as expected if everything works - I just thought the error might help tracking things down.)

 

main.ts:923 is the callBack from the ScrollTrigger onToggle and onSnapComplete events, that surely should not fire after the ScrollTrigger is killed.

 

I know that it is hard to help me here without a simple CodePen, but as I said it only happens in a more complex environment, I (almost) never happens when I do resizing without having scrolled before.

 

It seems to me, that scrollTrigger.kill() under certain circumstances cannot be used synchronously? Is there a surefire ©llBack) way to be sure that a scrollTrigger is 'dead' before proceeding?  (I do some waiting for animation frames in my following calculations already, but if the kill isn't working, even after at least 3 animationFrames ScrollTrigger-Remains interfere with my layout.)

 

 

 

 

 

 

 

 

 

 

 

Link to comment
Share on other sites

7 minutes ago, Cassie said:

Also -maybe your situation calls for killing the scrollTrigger - but I always recommend using invalidateOnRefresh and functional values when possible! It may make your life a little easier.

I tried that, but in my case it is actually not helpful, thanks. I really need scrollTrigger not to da anything at all while doing my own (re-)calculations.

One thing I have to to is move the window to its' top (window.scroll(0,0)) to get workable positions from some elements. This will trigger any 'living' and will likely mess up things for me.
I like you functional values approach a lot, but I also do love how the combination of Timeline and ScrollTrigger works so well in almost all cases with simple values and CSS. I can finetune even complex animations most of the time by changing 2 or 3 parameters and one or two css-values - funktional values often require more reprogramming. 
I'm often baffeled how good gsap 'reads my mind'... :-)

Programming callbacks to dynamically set values during animations is a cool possibility when necessary, but in my experience, it is often harder for me to understand what I have done when I have to revisit my cobe month later - but that is probably me getting older. 
 

Link to comment
Share on other sites

3 minutes ago, Cassie said:

Maybe you can adjust this demo to give us some more context?

As I said, I don't think that my issue is reproducible in a simple CodePen, as it only occurs randomly in a more complex environment and also mostly when the browser is at its' animation limits.

 

Concerning you example (thank you for that btw.) I actually do kill (only) the scrollTrigger, not the tween (Timeline in my case)

I do build a simple Timeline when the page is loaded, looping over the number of panels. This timeline is stored in a variable and when I create the scrollTrigger said timeline is referenced as the scrollTriggers' animation.

 

I then kill the scrollTrigger after resize, do my calculations and recreate the scrollTrigger with actually the same values using the same timeline as animation. (If you ask me now, why I do not just disable and enable the scrollTrigger, my only answer is that that didn't work in a lot more instances, but as i'm struggling with this thing for ages now, I'm not sure if there have been any other reasons.)

 

That kill and rebuild approach works +95% of the time as intended. Actually even if it doesn't the effects aren't totally catastrophic and it probably can be deployed that way, but I hate it when there are reproducible problems and I don't understand how they happen.

 

Actually I would like to concentrate on the fact, that in those rare cases, after I call kill() on my only scrollTrigger instance, i still have a ScrollTrigger.getAll().length of  (and a ScrollTrigger running around and doing stuff for at least some amination-frames)

 

So scrollTrigger.kill() seems to have some asynchronous components or my understanding of javascript needs to be updated.

 

If ScrollTrigger.kill() relies on something asynchronous I would like to know what to wait for. If my understanding is fundamentally incorrect I'd love to be educated.

 

Link to comment
Share on other sites

11 minutes ago, iDad5 said:

Actually I would like to concentrate on the fact, that in those rare cases, after I call kill() on my only scrollTrigger instance, i still have a ScrollTrigger.getAll().length of  (and a ScrollTrigger running around and doing stuff for at least some amination-frames)


If we can't recreate it it's really quite hard to help. I've tried killing scrollTriggers a bunch of different ways and can't see any issues.

Maybe @GreenSock can shine some light on this?

See the Pen qBPdmRL?editors=1011 by GreenSock (@GreenSock) on CodePen

  • Like 1
Link to comment
Share on other sites

  • Solution
1 hour ago, iDad5 said:

So scrollTrigger.kill() seems to have some asynchronous components or my understanding of javascript needs to be updated.

 

Killing is synchronous. The only things that are asynchronous are events like refresh as it debounces resize events, so your window resize event probably won't be in sync with ScrollTrigger's refresh event.

 

Have you tried to kill everything just to see.

ScrollTrigger.getAll().forEach(t => t.kill());

 

I would probably also try killing your timeline too. When I kill something, I like to kill everything else associated with it just so I know everything is fresh and exactly how I want it.

 

this.timeline.scrollTrigger.kill();
this.timeline.kill();

 

 

  • Thanks 1
Link to comment
Share on other sites

Thank you @Cassie for the pen ist a lot closer to the mechanics in my project than the first one but, as with my own tests, it seems impossible recreate the situation I described in a simplified test.

maybe @GreenSock has some ideas/hints what could cause the problem I'm experiencing, meanwhile I try to dig deeper...

  • Like 1
Link to comment
Share on other sites

Yeah, without a minimal demo or any way to reproduce the issue, it's super difficult to offer any insight @iDad5. What version of ScrollTrigger are you using? I hope it's the latest. 

 

You can try a minified version of the upcoming release here: https://assets.codepen.io/16327/ScrollTrigger.min.js

 

There was an issue fixed related to calling .kill() multiple times on the same ScrollTrigger instance potentially misbehaving in a rare situation, but that doesn't really sound like what you're struggling with here. 🤷‍♂️

 

And Blake is correct - there aren't asynchronous tasks inside ScrollTrigger (other than of course the browser itself handles the painting of scroll updates on a separate thread, but that's not a ScrollTrigger thing). 

  • Thanks 1
Link to comment
Share on other sites

@OSUblake thank you very much for your input it helped me discover the likely source of my problem.

@GreenSock thank you too, I use 3.8 and I guess that this wasn't related to the issue you are mentioning. 

 

@OSUblake suggestion to make sure to kill each scrollTrigger present with for each worked, and some more digging revealed that  my self-assuredness that I 100% did never create more than the one ScrollTrigger was misguided. Through a small typo at some other function I accidentally recreated the timeline after the resize and in consequence a new scrollTrigger so my line that was supposed to  elegantly kill the one and only scrollTrigger without using a nuclear 'kill all option' left the evil firstborn twin running loose in the shadows....

 

All my fault, I sincerely do apologize for taking you time. 

Thank you so much  for you patience. 

 

 

  • Like 3
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...