Jump to content
GreenSock

Das123

Divs replace each other as you scroll through content

Go to solution Solved by mvaneijgen,

Recommended Posts

Hello. I've been struggling with this for days. As you will be able to see, I'm not very good at javascript code - sorry. I actually thought the use-requirement would be fairly common but can't find any examples. Currently my CodePen doesn't work at all. If I remove the

  t1.from(flipper.querySelectorAll('.card'), {
    opacity: .6;
  });

code it will display the markers and sort of moves the boxes down the page but still doesn't do anything else.

 

What I'm trying to do is:

  • have multiple sections that trigger their own content animations.
  • have the left hand side (.big) work as the scroller to define the start and end. Probably don't really need this if I can sticky the elements in the right hand panel.
  • have any number of divs in the right hand column that optically replace each other as you scroll down the page. For example, if there are 2 elements they will replace at 50%. If 3 it will be at 33% and 66%. Etc.
  • need the .holder element to be sticky inside its parent div.
  • may need a way to define the height of .holder based on the tallest .card element.

 

In the CodePen I've dummied up my basic issue. Really hope someone can help shed some light on what I've been doing wrong. Thanks in advance. :)

 

I've used different opacities here so I can hopefully see what is going on rather than opacity 0 and 1. In the final version I would need to start with the first .card element at full opacity and then hid as the others come online.

See the Pen PoerMMd by Das246 (@Das246) on CodePen

Link to comment
Share on other sites

Hi @Das123 welcome to the forum! 

 

I'm not completely sure of what you're trying to do. But I do know that ScrollTrigger just animates a timeline on scroll, so I would first focus on the animation and worry about the ScrollTrigger later. The best thing to do 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.

 

What I did is have all the cards animate in and out using two tweens. By using the timing variable to start the second tween when the first element is done fading in. 

 

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

 

Now I have some animation to work with to hook that up to ScrollTrigger. I've used your container to function as the main element for all my logic, this contains all the elements I need, so that is a smart starting point.

 

I want the animation to happen on the users scroll, so I set scrub: true, I want the animation to start when the top of the element hits the top if the  browser, and it should end at when the bottom of the element hits the top of the browser again. (minus a bit, so that the two containers don't overlap each other). At last I set the element that should pin while in the trigger element and I'm done. 

 

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

 

I've disabled some of your CSS, because it's better to let GSAP handle the pinning of elements when using ScrollTrigger. 

 

Hope it helps! It's best to look at your problem in stages and tackle one stage at a time. For me it helps to write out all the things I want to happen in comments in my code and then try figure them out one by one, this works for GSAP, but also for general Javascript.

  • Like 2
Link to comment
Share on other sites

Wow! Thank you @mvaneijgen! That certainly moves me a long way along the track. :) Also, thank you for spending the time to explain the principles and approaches behind the techniques - very very valuable.

 

I'll have another attempt but one issue I think I will have is that I don't know in advance the depth of the card elements and I can't have them extend into the subsequent sections. position: sticky for an individual element works great but not when you have these position: absolute elements.

Link to comment
Share on other sites

12 hours ago, Das123 said:

one issue I think I will have is that I don't know in advance the depth of the card elements and I can't have them extend into the subsequent sections

Do you know the largest card? I would set the end value to something like this end: `bottom-=${MAX_HEIGHT_CARD} top` that should work I think or now I think about it, you just need the height of the last card. 

 

I would just try some things and post back when you're stuck. Good luck!

  • Like 1
Link to comment
Share on other sites

Thanks again @mvaneijgen. :) You're right, I only need the last child. I've coded that and it works well.

See the Pen KKeKPWY by Das246 (@Das246) on CodePen

I also needed the elements to step through clearly rather than meld across and so I changed the timing variable.

 

I am still struggling a a couple of issues - but it is really close.

1. When you look at the example the elements behind stay on the screen even when the front element is strong. I don't really understand how 'stagger' works so am hoping that can be solved easily.

2. I need the first .card to be visible before the animation starts and the last .card to be left visible after the animation ends. In my head I was thinking I would need to ditch the stagger aspect and have a trigger that toggles a .active class with opacity 1 but this seems like it would be a start again exercise.

Link to comment
Share on other sites

  • Solution

Stagger is just animating something in series, one after the other. This has nothing to do with positioning. I had used the position parameter (and you removed it from you codepen) to start the second tween 1 second after the first has started playing. Normally tweens run only after the previous as done playing, so in your example, first they animate all in and when they are done they all animate back out. This is a really smart way to have things move in, but also move out at a timely fashion, I've stolen this from the legendary @Carl check out his video here, this is a really cool concept to have in your tool belt. 

 

 

Again, here the same concept applies. The best thing to do 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.

 

Stagger is smart if you want everything to animate exactly the same, here you don't want that, so then you need to animate them separately. Take a look at my example. I've add some more classes to your HTML to make it work.

 

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

  • Like 4
Link to comment
Share on other sites

Thanks again for your help with this. :)

For completion I've fiddled a bit more with the code-pen to get what works for me...

See the Pen KKeKGBL by Das246 (@Das246) on CodePen

 

The changes are:

  • Turn back on the scrollTrigger so the scrubber still does its job.
  • Get rid of the text at the top of the right column to ensure the elements line up at the bottom.
  • Add an expo ease to minimise the animation between elements so there is minimal fade in and out. (There probably would have been a better way of doing this.)
  • Used the new .card-last class to set the height rather than the :last-child selector.
  • 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.
×