Jump to content
GreenSock

Search In
  • More options...
Find results that contain...
Find results in...
Pauline Brothier

How to pin div in a full horizontal scroll

Go to solution Solved by akapowl,

Recommended Posts

Hello ! 


I'm new with scrollTrigger and I don't understand how I can pin elements inside my horizontal scroll section. 
For example, in this codepen :  I would like the scroll to stop when the number 3 (grey div)  "touch" the left side of the screen.

And then the number 4 scroll above the number 3 section and the classic horizontal scroll continue. 

I think it's possible, I hope, but I don't understand how to make it. 

 

I hope my issue is clear, and someone could help me on it. 

 

Thanks :)

See the Pen MWjeqdb by PaulettePaillette (@PaulettePaillette) on CodePen

Link to comment
Share on other sites

 

Hey @Pauline Brothier - welcome to the forums :)

 

4 hours ago, Pauline Brothier said:

but on my website (http://dev.bklt.fr/ggr/agence.html), is super fast.

 

The problem on your website is, that for the x-translation you use the scrollWidth of the container, whereas for the end of the ScrollTrigger, you use the offsetWidth - which basically means the width that the container takes space in the window. So your 'scroll-duration' here is just a window's width. You could try changing it to the scrollWidth of your container instead, see if that changes anything, and adjust it to your needs.

 

 

4 hours ago, Pauline Brothier said:

I would like the scroll to stop when the number 3 (grey div)  "touch" the left side of the screen.

 

I don't think that would be too trivial to get to, and you would probably have to change your setup (at least for the ScrollTrigger) quite a bit to get it working.

 

The thing is, that you are not naturally scrolling horizontally, so ScrollTrigger's pinning is not something that would work. So instead you would probably have to animate each section to the left individually, and do the calculations individually for when you want the animation of that one section to stop (and maybe start again). I myself can not think of an easier way of how to do that now - maybe someone else will, though.

 

It would probably be easier, if you were to be able/willing to use natural horizontal scrolling - but I get, that depending on the exact scenario you want this to happen in, that might not be a solution to go with at all.

 

Anyways, hope this helps.

 

Cheers,

Paul

  • Like 3
Link to comment
Share on other sites

  • Solution

 

Alright,

as always, to get something like that working, it is not one solution fits all, so you probably can not rely on the following demo to be working in every imaginable scenario. But I was curious myself on how get something like what you described working and came up with this following little concept.

 

It works properly ( even after resizes ), but if you wanted to do things differently, you would have to apply the changes yourself and figure out a way to get it running in you scenario, if my demo doesn't work for you. This is just for demonstration purposes of how to possibly achieve what you intended.

 

For example, I added margins to space out the elements - and added a wrapper around the elements, that it my demo serves as the trigger element for each of the .thumbnail-ScrollTriggers. The wrapper has a set width ( which equals to the width of all those elements plus their margins ) - That you would definitely have to adjust to your scenario. It may look wild, but it actually makes sense. Also note, that I went away from using display: flex for the aligning of the .thumbnails, because it kept messing with the widths of those elements, so instead I went to use display: inline-block and float left on the .thumbnails themselves. There are quite a few other changes in the CSS, but it would be too much to adrress every single one of them now.

 

For the ScrollTriggers themselves:

I use one trigger for the pinning of the .container - that one is what makes the whole thing scrollable. Since I had it there already, whithout doing anything else, I thought it would be a good idea to also leverage it for animating that fake-scrollbar/scrollindicator that you had commented out in your demo.

 

I added extra individual ScrollTriggers for each of the thumbnails. 

Those without fake-pinning essentially behave the same, as you had initially  for your whole container - but here instead it happens for each section individually. For those with fake-pinning, I added an extra function, that calculates their total-width to move (used for their x-translation, and the end of the ScrollTrigger) that takes into account all previous thumbnails with their widths and margins.

 

It may not be perfect, but it works decently.

 

And as you see, this is not the most trivial thing to realize - unless I am overcomplicating, which I might be.

 

This doesn't take into account though, that at one point, you might want to 'unpin' a thumbnail again, but that could be calculated too for each element.

 

Also, what you might notice on this demo:

depending on how fast you scroll, there will be a larger 'offset' to when the fake-pinning happens. I think, this is soleley just related to how the scrub works - you won't see an offset like that with the scrub set to true instead of a different value. So if you wanted to get rid of that offset, you'd have to use scrub:true and if you still wanted the whole thing to be 'smooth' you then would also have to use a smooth-scrolling library on top of that.

 

With all that being said, here is the demo I was talking about all along

 

See the Pen 59f35078bb8ca75e734aa43a4761414a by akapowl (@akapowl) on CodePen

 

 

I actually quite like the idea, it allows for some neat stacking effects, too.

 

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

 

 

Anyways, I know, the setup is much different from what you have posted above, and it might be a bit tricky to wrap your head around all this, but I hope this still helps at least convey an idea, of how to get to what exactly you need.

 

Cheers,

Paul

 

  • Like 5
  • Thanks 1
Link to comment
Share on other sites

Hi, 

Thank you both for helping me!

I tried your solution on the website I'm working on @akapowl, it's perfect! I didn't have the right logic. 

Thank you so much 😊

Cheers,
Pauline

  • Like 1
Link to comment
Share on other sites

  • 3 months later...

@akapowl Awesome solution! Thanks so much for posting a demo, it's been really helpful to learn from.

 

I've been trying to implement ScrollTo into your demo, using nav links as anchor links to each section - same functionality as in this 

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

 and struggling a little bit lol... I was hoping you might be able to give me some direction please? 🙂

 

I have anchor links set up, just having trouble with getting the scroll container to scroll to the selected section. 

 

Cheers,

Dan

  • Thanks 1
Link to comment
Share on other sites

 

Welcome to the forum @tractaNZ

 

It pretty much works exactly the same as in the example you posted.

 

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

 

If this doesn't work for you, it would be best to create a minimal demo of your issues for us to have a look at.

 

Hope this helps, though.

 

  • Like 3
  • Thanks 1
Link to comment
Share on other sites

Hi @akapowl,

 

Thanks for the welcome and taking the time to reply, I really appreciate it!

 

I've had crack at implementing scroll to as in your demo above, but it seems my issue is with ScrollTo. On click of an anchor item, I'm getting a console warning "scrollTo target doesn't exist. Using 0". I've put together a basic codepen, if possible would you mind please having a quick look to see what I'm doing wrong? 🙂

 

Thanks so much for all your help.

 

Cheers,

 

See the Pen JjEpJem by tracta_nz (@tracta_nz) on CodePen

 

 

Link to comment
Share on other sites

31 minutes ago, tractaNZ said:

I've put together a basic codepen, if possible would you mind please having a quick look to see what I'm doing wrong? 🙂

 

Sure;

Since you appear to be using locomotive-scroll, GSAP's ScrollTo-Plugin won't work here because of the way that smooth-scrolling library works.

 

You will have to use locomotive-scroll's own .scrollTo method.

 

Check loco-scroll's documentation on GitHub for more information.

 

 

 

Also it looks like you are mixing jQuery methods with vanilla JS methods.

 

When you store your panelsSection in a variable like this

 

//anchor links
var panelsSection = $(".scroll-container");

 

in combination with the rest of the code for the scrollTo now your containerOffset returns 'NaN'.

 

So you will have to adjust the rest of your code for the scrollTo to work with the jQuery way - or just stick to vanilla JS for getting the panelsSection as in the example

 

//anchor links
var panelsSection = document.querySelector(".scroll-container");

 

See the Pen 5eeff1c5e2fb29c59f8230844a72d0ab by akapowl (@akapowl) on CodePen

 

 

  • Like 1
  • Thanks 1
Link to comment
Share on other sites

@akapowl

 

What can I say! WOW thank you so much for all your help! Working perfectly, I'll be sure to read through documentation throughly next time too.

 

Thanks again!

 

Cheers

  • Like 1
Link to comment
Share on other sites

Hi @akapowl,

 

I've been playing around with your original anchor scrolling pen. I'm trying to implement anchors to content within the panels as well as the having nav anchors to each section. 

 

If you wouldn't mind having a look in the pen below, you'll see I've added a child anchor within Panel 3 called 3 Inner. Though on click of the nav item Panel 3 Inner the child anchor is offset to the right, rather than to the left like the parent panel anchors

 

See the Pen MWJBJdY by tracta_nz (@tracta_nz) on CodePen

 

If you have any advice I would really appreciate it :)

 

Cheers,

Link to comment
Share on other sites

5 hours ago, tractaNZ said:

Though on click of the nav item Panel 3 Inner the child anchor is offset to the right, rather than to the left like the parent panel anchors

 

The logic for the scrollTo is not built for respecting child-elements of the panels but only the panels themselves so far, so you'd have to incorporate some logic that would respect that.

 

You could e.g. set up an if statement in which you check wether the e.target.getAttribute("href") has "inner" at its end.

 

If it does, set the containerOffset to the panel's offsetTop plus the targetElement's offsetLeft plus the targetElement's parent's offsetLeft (because for that case, your targetElement is not the panel itself anymor but the pannel's inner).

 

Else, use the calculations as before.

 

  • Thanks 1
Link to comment
Share on other sites

@akapowl

 

Thank you so much for you advice! I've updated my pen and all working nicely. I'll leave here for anyone else looking to do the same thing.

 

See the Pen MWJBJdY by tracta_nz (@tracta_nz) on CodePen

 

Thanks again, you're amazing!

Link to comment
Share on other sites

 

Good job :) 

 

With the afore-mentioned if statement you could spare some code, though. Maybe something like this

 

if(e.target.getAttribute("href").slice(9) === 'inner') {
  containerOffset = panelsSection.parentElement.offsetTop + targetElem.parentElement.offsetLeft + targetElem.offsetLeft;
}
else {
  containerOffset = panelsSection.parentElement.offsetTop + targetElem.offsetLeft - 10;
}

 

or use a ternary operator for that

 

const containerOffset = e.target.getAttribute("href").slice(9) === 'inner' ? 
      panelsSection.parentElement.offsetTop + targetElem.parentElement.offsetLeft + targetElem.offsetLeft : 
      panelsSection.parentElement.offsetTop + targetElem.offsetLeft - 10;

 

See the Pen 43cb579a3068d446ccd0acab72fbaba9 by akapowl (@akapowl) on CodePen

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