Jump to content
Search Community

Scroll Trigger breaks when refreshing page or resizing window

David B. test
Moderator Tag

Go to solution Solved by mvaneijgen,

Recommended Posts

Hi everyone!
I have recently started my first project using gsap and while I really enjoy working with it I came across an Issue I just couldn't fix.

 

The demo should provide a good explanation of what I am trying to achieve, basically a sticky section where some text and an image is replaced when the user scrolls down. And everything seems to be working as expected. The issue is that this only works if you start from the very top of the page, e.g. when you refresh the page and the top offset is 0. 

 

When you stop in the middle of the page and then refresh the page most browsers will snap you back to this position and not to the top. Same goes for when you resize the browser window and the window height changes. 

 

I tried a few things but none of them seem to work:

- Using an event listener to always force the page to start at top-offset 0

- Using the .refresh(true) and.matchMedia(true) methods:

    document.addEventListener("resize", (event) => {
        ScrollTrigger.refresh(true);
        ScrollTrigger.matchMedia(true);
    });
    window.addEventListener("load", (event) => {
        ScrollTrigger.refresh(true);
        ScrollTrigger.matchMedia(true);
});

I am pretty sure I did not implement these correctly, maybe that is why it won't work ;)

 

 

Does anybody have an idea how I can fix this issue?

 

Take care

David

See the Pen VwObZyX by David-Boh (@David-Boh) on CodePen

Link to comment
Share on other sites

  • Solution

Hi @David B. welcome to the forum!

 

Timelines are the most powerful tool in GSAP and you seem to have completely overlook this. Check out this awesome getting started guide https://gsap.com/resources/get-started/. Everything in GSAP starts with an animation and that animation you can hook to what ever you like.

 

Right now you create an animation and a ScrollTrigger for each image and heading, but each heading can only be active in a sequence, so a timeline is perfect for that. I've removed most of your setup, just to get back to the basics.

 

What does "+=1000s" mean in your setup? ScrollTrigger works based on pixel values. Eg the start and end are measured in pixels and and animation that is set to 1 second will then play over 1000px (if scrub is set to true). Check out this tutorial how to work with ScrollTrigger 

 

 

As a side note it is a good habit to never animate you trigger element, ScrollTrigger uses this for its calculations, so if you then move it (this doesn't happen in your case) the calculation will be of, it works in your setup, but it is really easy to then modify your animation to move the element and then everything will be off. That is why it is a good idea to have the rule to never animatie you trigger element.

 

The best thing to do when working with ScrollTrigger is to remove it! This seems counter intuitive, but ScrollTrigger is just animating something on scroll, so just focus on the animation at first and only when you're happy with the animation add ScrollTrigger back in. This way you can focus on one part at a time and it will save a lot of headache when debugging. 

 

In the demo below I've used a timeline with use of the position parameter to have tweens play at the same time. ScrollTrigger is disabled, but you can easily turn it on. As far as I know if you use this setup everything works responsibly, when you refresh the page ect. 

 

It seems like you also wan to snap to each section so that the animation is always at a full slide. The snap feature in ScrollTrigger is perfect for that, check out the docs: https://gsap.com/docs/v3/Plugins/ScrollTrigger/?page=1

 

Quote

Number | Array | Function | Object | "labels" | "labelsDirectional" - Allows you to snap to certain progress values (between 0 and 1) after the user stops scrolling. So snap: 0.1 would snap in increments of 0.1 (10%, 20%, 30%, etc.). snap: [0, 0.1, 0.5, 0.8, 1] would only let it come to rest on one of those specific progress values. It can be any of the following...

 

Hope it helps and happy tweening! 

 

See the Pen dyEWbLj?editors=1010 by mvaneijgen (@mvaneijgen) on CodePen

  • Like 1
Link to comment
Share on other sites

@mvaneijgen thank you for your quick response!

 

This makes a lot of sense, my initial approach was to replicate the result and not to focus on the technical best practices, this came back to bite me ;)

 

I have to follow up questions:

-Why should I not animate the first item? Because now the first item is always in the background of the other ones, obviously because it does not get animated. should it not get hidden when the second item becomes active?

 

-Now the animation itself is linked to the scroll progress, the transition is very visible (the fade  in between). Is it possible to transition between the active elements without having these "steps" in between. I know this sound confusion but I don't know how to describe it. In my demo the transition is very snappy and there is no fade in between. 

 

 

Edit: I added snap to my config but this doesn't do anything. To clarify, i want the sections to animated the following way:

 

User scrolls, first section get visible, the user scrolls a bit, now the second section becomes visible, the user scrolls a bit and so on. At the moment the sections are getting faded in and out linked to the scroll position and not like actual sections.

 

 

 

Thanks again

David

Link to comment
Share on other sites

42 minutes ago, David B. said:

-Why should I not animate the first item? Because now the first item is always in the background of the other ones, obviously because it does not get animated. should it not get hidden when the second item becomes active?

Not so much that you should not, but usually people want to start with the first 'slide' visible, seems like a nice UX. 

 

1 hour ago, David B. said:

should it not get hidden when the second item becomes active?

I'd given the text a background color, so hat you don't see the previous text when the new one comes in. You could add an animation that also hide each image and slide. 

 

1 hour ago, David B. said:

I added snap to my config but this doesn't do anything. To clarify, i want the sections to animated the following way:

Can you show us in a demo what you've tried? 

 

43 minutes ago, David B. said:

User scrolls, first section get visible, the user scrolls a bit, now the second section becomes visible, the user scrolls a bit and so on. At the moment the sections are getting faded in and out linked to the scroll position and not like actual sections.

Yeah I see a lot of people requesting that feature from ScrollTrigger, but that is not what is is made for. ScrollTrigger is to hook an animation to the scroll bar, so if you were watching a YouTube video the scrollbar of the browser becomes the progress bar like in the video. If you don't want that ScrollTrigger isn't the best tool.

 

Have you seen the Observer pluginhttps://gsap.com/docs/v3/Plugins/Observer/ with it you can watch for scroll events and then do logic based on that. Below a demo that has a timeline and on each scroll animates to each label in the timeline 

 

See the Pen GRzrPPy by mvaneijgen (@mvaneijgen) on CodePen

 

The observer plugin is a bit more conciliated, so the ScrollTrigger with snap route is much easier, but if you want the above effect the Observer plugin could be a great route to go down, here an example that mixes normal scroll with the Observer plugin

 

See the Pen oNQPLqJ by GreenSock (@GreenSock) on CodePen

Link to comment
Share on other sites

UX wise making the first item visible is a good idea, thank's for clarifying. 

 

Sure here is the codepen with the snap added:

See the Pen abrWzpe by David-Boh (@David-Boh) on CodePen

 

I do not see any difference to the version without it, do I need to update any other parts of my code to make it work?

 

I never thought of using the Observer Plugin for that because the word ScrollTrigger sounded so good ;)

Link to comment
Share on other sites

Ok, you've set snap to 1 / 3 which results in 0.333333333, so in theory you've written this snap: [0, 0.333, 0.666, 1], so as you can see there will be 4 snap points the start and end and two where the progress of the timeline is 0.333 and 0.666. Personally I always like to write out my snaps in an array, just for testing purposes to make sure when I add the calculations it is doing what I think it should b doing. 

 

If you scroll below here and wait a few milliseconds you'll see it will 'snap' to the points you've defined. Let's see if with above explanation you can figure out to what points you want to snap to (hint, how many 'slides' in total do you have?)

 

See the Pen PovmwJK?editors=0010 by mvaneijgen (@mvaneijgen) on CodePen

Link to comment
Share on other sites

I've tried 1/5:

 snap: [0, 0.2, 0.4, 0.6, 0.8, 1]

This seems to work because now it snaps to a 'full' slide.

 

That is already amazing, the last thing I need to figure out is how to make the transition "snappier" so it looks like the content gets replaced and the opacity is not immediately reduces once you scroll. 

Is that even possible or am I here pushing the limits of ScrollTrigger?

 

 

Link to comment
Share on other sites

By default each tween in GSAP has an ease of power1.out you could set this to steps(1), it will forgo all the easing and just animate the animation form 0 to 1 in an instance. Check out the ease visualisers if you want to see how it works. https://gsap.com/docs/v3/Eases/CustomEase/#description

 

You can make it snappier by what you did setting the ease and the duration of the snap, but if you then set scrub: 1, this will mean that the animation will lag behind 1 second, so all the snapping will also lag behind with one second. Even with this setup ScrollTrigger will still have to wait until the user has done scrolling, so it will never be instantly.

 

See the Pen yLWbyQw?editors=0010 by mvaneijgen (@mvaneijgen) on CodePen

 

This is how close you can come with ScrollTrigger, but what you're asking is an effect you get with working with the Observer plugin so if you want to take it further, that is the tool I would use.  Hope it helps and happy tweening! 

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