Jump to content


pinned overlapping layers - timing

Recommended Posts

Hi all,


I've used the GS example for pinned layers to try and lay out part of a page, and it's kind-of working, but I think I'm having an issue with setting the correct height. Perhaps. 

If you scroll down (really slowly!) in the example, the pinned text (that comes up on black) and the second image both seem to come in a lot quicker than the first image. I think I'm missing something in setting the end point of the trigger correctly. I've tried to get the overall height of #container using the row height but I'm missing something here.

I'd like so that the scroll speed feels the same (i'm going to use ASScroll to add some smooth scrolling later), but for now I just need a little help understanding where I'm going wrong.


EDIT: I haven't yet done anything to cope with mobile yet so unless the pen is full screen the text panel is going to be huge!



See the Pen NWNevYx by darkgr33n (@darkgr33n) on CodePen

Link to comment
Share on other sites


Hey @darkgr33n


Since you are using a scrub-animation, the perception of its 'speed' depends on the duration of the ScrollTrigger - meaning the time between its start and end.


You don't necessarily have to set the end of your ScrollTrigger to the containerRows.offsetHeight - you could vary on that a bit.


Just setting the end to '+=1000%' for example, makes the scrubbed animation appear waaaay slower.


You should be good to go, simply just adjusting that end to your liking 


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


Does that help?




  • Like 5
Link to comment
Share on other sites

Hey @akapowl


Thanks for the quick reply, much appreciated ;) 

I did have something like that initially but wasn't sure if it was the right way to go as I thought the 'speed' would vary  too much depending on the monitor size, so was trying to work out what the best calculation would be. I'm on my laptop right now and not the big monitor but, to be honest, setting it to "+=1000%" does actually seem to work pretty well.


Maybe I was overthinking it :/ 


So, when we are using scrub, the end point can be something completely arbitrary and doesn't have to be related to any element to set the perceived 'speed' ?

I think I may need to revisit some of the tutorials again!



Link to comment
Share on other sites


14 minutes ago, darkgr33n said:

I thought the 'speed' would vary  too much depending on the monitor size


Well those '+=1000%' just basically sets its end to 10* the container-height (10*100%).


But you are right, making the end dependent on the container height itself solely, would give varying results on different screen-sizes.

And since those 1000% are just 10 times the container height, that would be still the case here - was totally overseeing that, sorry.




1 minute ago, darkgr33n said:

So, when we are using scrub, the end point can be something completely arbitrary and doesn't have to be related to any element to set the perceived 'speed' ?


That is less because of the scrub, but more because of the pin and ScrollTrigger applying that nifty pin-spacer . 

Your container will stay pinned for whatever amount of scrolling-distance you tell it to, so yeah, I think, you can vary on that to your liking.



  • Like 3
Link to comment
Share on other sites



Mimicing the natural scroll-speed, as you intend, can probably be done, but I think it might be a bit more complicated, than you thought.

(And I also really hope, I am not overcomplicating things, where there actually might be an easy solution)




Let me start with this:


Lets say you have a container and within that container you have a wrapper with lots of content in it.

You set a ScrollTrigger with a pin for  that container - starting when it hits the top and the end to += the height of (all the content within) that wrapper.


If you apply a scrub with only a single tween, that translates the wrapper upwards on the y-axis for that same amount as the height,

you will get that effect, that basically just mimics the natural scrolling behaviour - in a way, similar to what you tried and had in mind.


An example of this can be seen in this thread, where I incidentally created such behaviour - see my last two answers in that thread:





The problem in your actual case now is, that you have a timeline with multiple tweens, on multiple elements with different heights, so you'd have to 'sync' up the duration of each element, for which it is important to appear like naturally scrolling, with the total duration of your scrubbing ScrollTrigger. ( Hope this is at least a bit understandable to you, I don't know how else to say it. )



So first we need to get the height of all important elements, which in your case is 2 times the height of the .pinned-text ( because you tween on the scale twice and it probably should mimic the natural scroll-speed in both cases) + the height of your .image-wipe--two.


var relevantElementsHeight = pinnedTextHeight*2 + imageTwoHeight;



To that relevantElementsHeight I add 10% of that height 5 times ( 3 times for the offsets you have on some tweens and 2 times for the tweens on opacity, for which it is not that important, that they have a duration that mimics the natural scroll flow).


I chose the 10%, so I could set the duration on the opacity-tweens and the offset on the other tweens to 0.1 (so 10% of the scrubbing-distance for each one)


var totalPinDuration = relevantElementsHeight + ((relevantElementsHeight*0.1)*5);



That makes the totalPinDuration that I set to the 'end' of your ScrollTrigger then


end: () => "+=" + totalPinDuration,



To get the neccessary duration for the relevant tweens in relation to the scrubbing, I then devided the height of the single elements to be tweened on, by the relevantElementsHeight


var pinnedTextDuration = pinnedTextHeight/relevantElementsHeight;
var imageTwoDuration = imageTwoHeight/relevantElementsHeight;


so I could set up the timeline like this in the end


 .from(".pinned-text", { duration: pinnedTextDuration, scaleY:0, transformOrigin:("bottom center")},"+=0.1")
 .to(".pinned-text p", { duration: 0.1, opacity:1 })
 .from(".image-wipe--two", { duration: imageTwoDuration, yPercent: 100 },"+=0.1")
 .to(".pinned-text p", { duration: 0.1, opacity:0 })
 .to(".pinned-text", { duration: pinnedTextDuration, scaleY:0, transformOrigin:("bottom center") },"+=0.1")




This was a pretty wild ride, but it seems to be working pretty consistent for every window-width.

Just note, that it is by no means responsive to resizes yet - I just had no more time rewriting it to work with resizes.




See the Pen 57ed95f73ef3f0386468b0e711fa627a by akapowl (@akapowl) on CodePen




Just thought, it was something interesting to tackle, after I noticed, that it would probably not be that easy to achieve.

I wouldn't bet on me not having overseen anything obvious on this, though - maybe even a way easier approach.





It would be great, if you could leave that original pen of yours in its original state and fork it for yourself, when you want to try out any changes on it. This way you could give others in the future the chance to better retrace what has been discussed in this thread :) 


  • Like 4
Link to comment
Share on other sites





Incredible work. I can't thank you enough, and breaking it down the way you did has really helped in visualising what's going on. 

I was aware of the pin spacing but was having problems really understanding what its doing and being able to hold that in my head while making the decisions you made. Seriously, thank you! 


One really important thing I hadn't thought about was actually including the times of the various tweens into the equation, but it makes perfect sense.


I also loved what you did and learnt quite a bit from the other 'pinning' thread too. Combined, both of these has really helped my increase my understanding.


I'll make sure to fork everything.


Once again, many many thanks!


For mobile, I think I'm going to just wrap to a standard div and remove all the scrollTrigger action as I don't think it's necessary on a small screen.







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