Jump to content
Search Community

ScrollTrigger scrub animation with hiding elements

thehaes test
Moderator Tag

Go to solution Solved by Rodrigo,

Recommended Posts

Hey guys, hope everyone is doing well.

 

I have a scrubbed scrollTrigger animation, actually 2 animations changing scale of card starting from bottom to center and then scaling down again from center to top.

I also have some filter buttons that will hide the cards assigned to that filter button (which is simplified in this codepen to hide just every 2nd card).

 

I wanted to have some smooth animation instead simply using display: "none".

The problem is when the cards get hidden, the scrub animation gets all messy and jumpy, which is especially visible when you start scrolling again - only then the cards will jump to their proper positions. 

I tried calling ScrollTrigger.refresh() in the onUpdate callback, but I think that's both not working and heavy on performance.

 

Is there any way I can make sure the cards will still be animating/scaling properly when the height of card changes?

See the Pen OJYVoeQ by thehaes (@thehaes) on CodePen

Link to comment
Share on other sites

Tested both on Safari an Chrome (macOS) and what ever I do it seems perfectly smooth to me. You're hiding elements using the height property, so there is going to be some jumpy-ness, there are some CSS properties that cause a browser repaint which of with height is one. 

 

You could look in to the flip plugin https://gsap.com/docs/v3/Plugins/Flip/, but again I don't see it. Hope it helps and happy tweening! 

Link to comment
Share on other sites

4 minutes ago, mvaneijgen said:

Tested both on Safari an Chrome (macOS) and what ever I do it seems perfectly smooth to me. You're hiding elements using the height property, so there is going to be some jumpy-ness, there are some CSS properties that cause a browser repaint which of with height is one. 

 

You could look in to the flip plugin https://gsap.com/docs/v3/Plugins/Flip/, but again I don't see it. Hope it helps and happy tweening! 

Thanks for the answer! 

The animations itself is smooth, it's just the ScrollTrigger part that is jumping. 

If you scroll to the second image just so the first one has only part of the bottom visible and then press the button, you will notice that the images jumps to 100% scale and when you start scrolling again it will instantly scale to correct scale based on the trigger. Hope this clarifies what I meant before

Link to comment
Share on other sites

I don't know a quick fix for that in your current setup. My first instinct is to check out the Flip plugin (see my previous comment) .

 

Also right now you have a tween plus ScrollTrigger for each image I would wonder what it would do if you have just one tween with one ScrollTrigger, because right now when you hide the elements the third element needs to update, but then also the 5th needs to wait for the third to fully animate before it can update and because they all depend on each other I don't see the need for them to all have their on animation + ScrollTrigger.

Link to comment
Share on other sites

I've updated the codepen (same link as first post), this time using Flip as suggested. Still the same issue happening :(

See the Pen OJYVoeQ?editors=0010 by thehaes (@thehaes) on CodePen

 

I guess there's also the issue of the scroll position jumping, because of the container height changing due to hiding of the cards. I wonder if blocking the scrolling (position fixed, overflow hidden or something like that) would work...

Link to comment
Share on other sites

Yeah that jump seems a bit difficult to avoid IMHO. When you add/remove elements that affects a ScrollTrigger instance(s) and then refresh, ScrollTrigger will run the calculations and instances will update accordingly and then update the animations based on that. On top of this Flip does records the most common on the state:

https://gsap.com/docs/v3/Plugins/Flip/static.getState()#configuration

 

I'm pretty sure that there must be a way to solve this, but my first guess is that is not a simple endeavor, a bit beyond the help we can provide in these free forums. The main issue seems to be that when you filter the elements and the ScrollTrigger instances don't update completely when the DOM is updated, so the flip animations don't reflect that. The simplest way I can think to tackle this is probably the ugliest, less efficient and can't guarantee that it'll work. Create three sets of elements. One that is the visible one with all the images in it (by the way, why always with the angry dude in the pictures? can't it be a kitten or a puppy? 😆), a copy of the previous but with the images not rendered and a copy of the filtered list with the images not rendered, so you can flip the elements that will remain in the DOM after filtering to those that already have the scale value applied to them.

 

Another option is to refresh ScrollTrigger before the Flip animation, there is still a jump, but is at the start of the animation:

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

 

Happy Tweening!

Link to comment
Share on other sites

Thanks @Rodrigo!

I decided to reduce the scrub animations a bit and keep it simple so it looks nice and smooth + flip gives me that nice animation I want for filtering :)

My only issue is the jump - it's all perfect when you're at the top of the page, but when you scroll down to the bottom part, or close to the bottom and then click the button, the scroll jumps to top. Is there a way to tell Flip to animate the height of the container/body the same way it does with elements inside? I tried to add the container div to the state so flip can register it, but the scroll will still jump to top + cards get some kind of scaleY animation to them. I know it's probably bit beyond the help you can give, but I'm not expecting a complete solution, just some suggestion or ideas to try.

 

So far I've tried:
1) ScrollTrigger refresh() in onUpdate 

2) Adding overflow hidden + 100% height on container/body while the animation is running 

3) Adding the container to Flip's state 

 

I was also thinking:

On my local build I am currently smoothly scrolling to the top of the page first. What if I somehow postpone the "shrinking" of the container/body, only after the scrollToTop animation is finished?

 

Thanks for all the help so far guys.

 

Link to comment
Share on other sites

  • Solution

Hi,

 

Yeah that's just the way browsers work in this sense. What you can try is to wrap everything in an extra element and use Flip or just get the height of the element once you filtered the elements. Just create concurrent Flip instances.

 

Maybe something like this:

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

 

Hopefully this helps.

Happy Tweening!

  • Like 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.
×
×
  • Create New...