Jump to content
Search Community

ScrollTrigger Pinning Sections & Retaining Scroll for Long Text

drewatdrawn test
Moderator Tag

Go to solution Solved by akapowl,

Recommended Posts

New to GSAP and ScrollTrigger I'm working on a site where content sections will animate in, either fading in on top of a previous section or flying in from the left/right, but I need to be able to scroll through any lengthy content in these panels before triggering the next pin/animation (this is particularly important at smaller screen sizes). I've been racking my brain all day for a good way to do this.

 

In the codepen I've got the first section working correctly (purple) and I can see the xPercent working beneath the purple area when I hit its trigger (the horizontal scroll bar changes) but I need the red section to come in on top of the purple section, either with a fade or a left/right translate.

 

It seems like it should be straightforward and I must be missing something. I did try a solution that calculated the overflow height of the text content and tweened the content over the Y axis to spoof a scroll, which let me build a more complicated timeline, but this didn't feel as maintainable since I'll need to link up these sections to content built in a CMS (that I won't be able to control) and I'd prefer to stick with the native scroll behavior if possible to avoid weird timings when content is longer.

See the Pen qBajBLK by airiviom (@airiviom) on CodePen

Link to comment
Share on other sites

  • Solution

Hey @drewatdrawn - welcome to the forums.

 

If you don't want to position things absolutely and fake-scroll, what you want to achieve is actually a bit trickier than it might seem at first.

 

You would need the following section to be shifted upwards a certain amount, so its top meets the window as soon as you start some sort of pinning for the previous section when it hits the bottom, so the next section will translate over and above that previous section.

 

I decreased the width of the sections a bit in the following demo to clarify what I mean with that (in hindsight it actually also makes quite a nice effect in my opinion :D ). Using a pin with pinSpacing false for the ending of the  'previous' section was not an option because it broke things completely. The pinSpacer doesnt't seem to change over the whole ScrollProgress, so ScrollTrigger seems to use the same pinSpacer and just set it beforehand with regard to all pins made. Thus, with pinSpacing set to false, I guess there just would not be any pinSpacing whatsoever (?) (not even with regard to that first pin) - but that is just a wild guess.

 

So for moving the 'next section' upwards, I first decided to use the y-value, but that would have given ugly blank-space at the very bottom of the page, so I went with marginTop. The amount of that (negative) marginTop would have to be the window-height (makes sense, since it should hit the top, when the previous section hits the bottom) plus the 'duration' of the pinning of the previous section - neccessary because of the pinSpacing created by that pin. That you would have to do for each section after the first one - in my example it is simply just a .set in between the pinning of the previous section and the ScrollTriggers for the next section - you shouldn't forget about that, when you're going to make things responsive.

 

On to the ScrollTriggers for the 'next' section: Their trigger is set to that section itself with the start set to 'top top' - just like your first one - and to each of them I added an end set to the width of that respective section.

 

On a sidenote: I added ease: 'none' to all tweens, so there are no timing-misperceptions.

 

All in all that seems to work as intended. I also added two more sections to your markup, to see if it would stand the test.

 

See the Pen bf83088b922c6e4d68874da1e2352108 by akapowl (@akapowl) on CodePen

 

 

What you could do now, is add .defaults() and/or loop through each section and create what is neccessary in a more DRY-way as described in this article on how to write animation code efficiently.

 

Hope this all makes sense and helps you get where you want.

 

Cheers,

Paul

 

 

  • Like 2
Link to comment
Share on other sites

Thanks, Paul! It looks like we went through the same thought process right up until you cracked it with negative margin. The combination of the negative margin with the window height PLUS the previous section height did the trick!

 

I had that efficient animation code article open in another tab alread - will be digging into that to make these sections DRY and easily repeatable in partnership with the CMS content.

 

Thanks again!

  • Like 1
Link to comment
Share on other sites

5 minutes ago, drewatdrawn said:

PLUS the previous section height did the trick!

 

Probably just a mix up - but you better don't make it dependent on the previos section's height - that would become one loooong pin.

 

And actually probably also a mixup on my end:

It probably should be the section's width, which you are animating, because it should dependent on that 'animation-duration'. 🤔

It doesn't matter much here, because all sections have the same width, but just in case you were to change anything about that, keep that in mind.

 

Good luck with your project :) Let us know, how things turned out in the end.

 

Cheers.

  • Like 2
Link to comment
Share on other sites

Ah, yes, a mix-up. The width, not height. If it's offset by the width of the section currently animating, that actually makes it easier to do dynamically since I can reference the section itself and not its previousElementSibling. They should all be the same width in this instance, but good to keep in mind for the future.

 

I'm looking into a looping over each of these sections and I'm having trouble wrapping my head around if/how timelines would be treated differently than tweens. Is it any different or should I declare the timeline inside the scoped forEach and I'm good to go? Any chance you could point me in the right direction?

Link to comment
Share on other sites

Excellent, thanks! I think I'm on the right track. Realizing there are some conditional things I'll need to do with these loops, like not adding the negative margin to the first section, some similar things with the last section.

 

Thanks again for all your help!

  • Like 1
Link to comment
Share on other sites

@akapowl I may have spoken too soon. I realized after trying to implement with real content that the solution only works if the content height exceeds the viewport. If there's less content, the sections overlap. Too little content and a section will be completely hidden under its subsequent section and they animate at the same time.

 

Any ideas?

Link to comment
Share on other sites

 

At the moment, I can't think of a simple fix that would respect shorter sections. 

 

But in my opinion the whole effect your giving this, sort of relies on things filling the whole window height. Imagine if you had a section, that is only 200px in total height, and that would translate to the left over a previous section, which has so much text, that it fills the whole window-height - that would look weird, wouldn't it? ...you would have the little text of the one section, and below (or above) it you would still see all the text of the other section - not that nice.

 

So my suggestion would be to set min-height: calc(100vh + 1px); to your .scene and thus make sure, that it is taller than the window. There will be that teeny-tiny 1px 'jump' between the two different pins of that section (when the content scrolls up for that 1px) but IMHO it is barely noticable, and this seems to work reliably, whether such as section would be at the beginning, in the middle or at the end.

 

See the Pen d29ac2f94baba4d7a73325dd50c155a4 by akapowl (@akapowl) on CodePen

 

 

You will notice, though, that in this demo scenario, the section after such a such a short section (due to its short height) will 'too early' come into view horizontally - but that should not be a problem in your wanted scenario, where the sections are 100vw wide and those sections after, will come in from off-canvas anyway.

 

See the Pen 25c95e0dea9bf2596eb38c52ff99da76 by akapowl (@akapowl) on CodePen

  

 

 

 

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