Jump to content
Search Community

ScrollTrigger - Resize Logic

Steve Giorgi test
Moderator Tag

Recommended Posts

I have some fairly complex animations what I'm triggering with dummy containers so that I can have them separated by 100vh sections.  It's a little cumbersome but it works very well for the most part.  I created each ScrollTrigger as a stand alone trigger in the demo on purpose -- I'm using those as my timelines which include many different tweens with the actual build.  In this example, I just added a text blurb to each.

 

Now this demo appears to work correctly --- although it doesn't appear to be triggering the ScrollTrigger resize listener (I may be wrong but I don't see it triggered when I resize Codepen); these containers/triggers are always set at 100vh.

 

I have this same exact type of layout built in Gatsby.js and when I scroll through it, it works beautifully, but when I resize the window after I've triggered a couple of the animations, text controlled by separate dummy triggers (the '.scroll-trigger' containers in the demo markup) will overlap.

 

In my setup, trigger1 and trigger2 will both get tripped on resize so that the text and other elements overlap (if I scrolled further, trigger 2 and 3 gets tripped, etc.).  I thought it was the two separate tweens that are attached to trigger2, but in fact it's the tween in trigger1 that is being tripped along with trigger2.  The trigger (trigger1) start points are already above the viewport, yet it's tween is being tripped on resize.

 

I've tried to set an end for each trigger, invalidate the triggers on refresh, set immediateRender: false, refresh and update all of the ScrollTriggers on resize.

 

 

Edit: I added overflow hidden to each trigger --- didn't want any confusion when multiple triggers got hit in the small Codepen preview.  I'm just hoping someone has some ideas.  I know it's difficult if the demo works but maybe the markup structure or something else would point to something very obvious that I'm not seeing.

 

See the Pen gOWQqrG by steve-giorgi (@steve-giorgi) on CodePen

Link to comment
Share on other sites

  • Steve Giorgi changed the title to ScrollTrigger - Resize Logic

The ScrollTrigger stop and end markers reset to the bottom/top of the screen each time I resize or anytime something triggers a refresh.  I've tried to save and restore the ScrollTrigger progress.  I've also tried to do this after disabling all autoRefreshEvents, but some events still trigger a refresh:

 

ScrollTrigger.config({
      autoRefreshEvents: '',
    })
 
window.addEventListener('resize', () => {
      allProgress.current = allScrollTriggers.current.map((st) => st.scroll())
      allScrollTriggers.current.forEach((trigger, i) => {
        trigger.scroll(allProgress.current[i])
      })
    })

 

The markers associated with the ScrollTrigger/timeline+tween that is firing are well off the top of the screen -- the trigger is two full screens from the top of the viewport.  I'm thinking the Codepen does not trigger the ScrollTriggers on resize because it's in an iframe?

 

 

 

 

Link to comment
Share on other sites

Thanks Blake,

 

That's interesting though - I wish I could see how they were conflicting.  If I have panels dedicated to triggering the animations, and each runs it's course before the next panel comes into the viewport I thought it wouldn't be possible for them to conflict.  I understand if it's a logic issue, but would you mind pointing out where one of the logic issues is?

 

I looked at the post you referred and he definitely has conflicting tweens.  Each of my triggers is a dedicated 100vh panel, the start times should never touch.  I'll check to see how duration works, that must be where I'm confused.

 

I must have been looking at it for so long that I'm blinded to it.  I'll review; at least that gives me a huge hint.  Thank you.

Link to comment
Share on other sites

Yea, the scrollbar is replaced with a custom scrollbar in the site --- it is very jarring.

 

OK, it does work great if you're going through it forwards/backwards in the actual build which mimics the triggers here.  I added the overflow hidden just so that if a forum user scrolled through the little Codepen preview window too quickly, they wouldn't think the overlapping there was the issue I was trying to demonstrate.  My mistake, that worked against me.

 

I am only seeing overlapping when the browser is resized.  Maybe I'm just completely misunderstanding how ScrollTriggers should be used.  I wanted to show an animation + text, pause, allow the user to trigger the next animation + text, pause, and so on.

 

If I change all of my ScrollTriggers to scrub, and run through it, nothing overlaps or conflicts, so the durations are correct.   The only issue is when resizing.  Maybe I'll simply disable the default resizing and handle it some other way.

 

 

Link to comment
Share on other sites

Yep, this has to do with logic issues in the way you set things up. I'll try to explain...

  1. You set things up with .to() tweens and you must remember take the current values as the starting ones (tweens interpolate between starting and ending values - .to() tweens let you define the end values and then it uses the current ones AT THE TIME THAT TWEEN FIRST RENDERS as the starting ones). 
  2. Imagine a scenario where the user scrolls really fast or the page refreshes further down so that the first two sections get triggered right away (basically at the same time). The first one is fine...it reads the current opacity as 0 and records that as the start and then begins animating it to 1. Great. BUT the 2nd tween is ALSO running now, so it reads the current value as its start too. See the problem? You're animating .c1 to 0...and it reads the start as 0 or maybe 0.01 if the first tween has done its first render. So you expected that animation to animate from 1 to 0, but it's actually going to animate it from 0 to 0. Same in the other direction. 
  3. Another problem is that your first animation is half the duration as your second one (because the first one only fades in .c1 but the second one fades out .c1 AND THEN fades .c2 in). So imagine what happens when you scroll backwards very quickly - tween2 and tween1 reverse() at basically the same time but tween1 will finish first because it's half as long. tween2's starting state has .c1 at an opacity of 1! Thus you'll end up in the wrong state. 

Again, it's all logic stuff in your setup. 

 

I think it'd be good to review your other thread where we discuss how to handle logic stuff with non-scrubbed ScrollTriggers that are animating the same elements or must have one thing finish before the other starts: 

 

Since you've got things set up where the animations could step on eachother's toes, you might consider switching to .fromTo() tweens so that you can bake the starting and ending values into the animations and not risk contamination from concurrent timing. 

 

Pretty much anything can be accomplished with the tools - you've just gotta understand how they work and the logic flow, that's all. 👍

 

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