Jump to content
Search Community

GSAP ScrollTrigger + Locomotive Scroll, data-scroll-speed issue

StevenCM test
Moderator Tag

Go to solution Solved by GreenSock,

Recommended Posts

Hi all,

 

I'm experiencing an issue with Locomotive Scroll + GSAP ScrollTrigger.
As soon as I add a "data-scroll-speed" to an element which is different from 0 it seems like the trigger is completely off and I don't know what I'm doing wrong. I would like to start the animation on all the elements as soon as they enter the viewport, this works as long as I don't change the "data-scroll-speed".

 

I've added a minimal demo and the very last element has a "data-scroll-speed" set to 3.
As you can see the opacity changes from 0 to 1  but not when the element enters the viewport.

I'm quite new to GSAP, Locomotive Scroll and JS in general and I'm hoping someone in the forums can get me back on track.
I've tried for countless hours to wrap my head around this, so this is my first post in the forums and my very first Codepen ever :-).

 

Thank you in advance!

 

See the Pen KKoQGOq by StevenVDB (@StevenVDB) on CodePen

Link to comment
Share on other sites

35 minutes ago, StevenCM said:

As soon as I add a "data-scroll-speed" to an element which is different from 0 it seems like the trigger is completely off and I don't know what I'm doing wrong. I would like to start the animation on all the elements as soon as they enter the viewport, this works as long as I don't change the "data-scroll-speed".

Yeah, LocomotiveScroll is not a GreenSock product so we can't really support it here. I assume that when you set data-scroll-speed to a non-zero value, LocomotiveScroll MOVES that element from underneath where ScrollTrigger calculated the start/end intersection points were on the scrollbar position. Remember, for performance reasons, ScrollTrigger does all that calculation up front so that it doesn't need to constantly run something like getBoundingClientRect() on every trigger element on every scroll event. That'd be terrible. So ScrollTrigger does its measurements (let's say it's 500px until the element enters the viewport) but then LocomotiveScroll moves the element so that it's much faster and hits the viewport after 200px instead of 500px. See the issue? 

 

I'd strongly recommend switching to ScrollSmoother which is our integrated smooth scrolling tool which also supports data-speed and data-lag features. They work great with ScrollTrigger. ScrollSmoother is a membership benefit of Club GreenSock, but you can try it out as much as you want on CodePen and CodeSandbox.

Enjoy!

Link to comment
Share on other sites

6 hours ago, GreenSock said:

ScrollTrigger does all that calculation up front so that it doesn't need to constantly run something like getBoundingClientRect() on every trigger element on every scroll event. That'd be terrible.

 

@GreenSock thank you very much for the swift reply. I see, and I was assuming this was causing the issue.
However, there's so many people that have managed to combine ScrollTrigger with LocomotiveScroll. I've studied implementations with both horizontal and vertical scrolling and I'm having difficulties to believe that anyone hasn't stumbled upon this problem or hasn't "fixed" this before.


Moving things at a different speed while smooth scrolling with LocomotiveScroll + having full control on animating objects with ScrollTrigger seem like the basic requirements to me to combine these plugins. I know it's not a GSAP issue, I'm just trying to get in touch with someone who has more experience in this matter. I'll kindly say hello to @akapowl via this way to get his attention. 🙂 He seems to have supported a few people here with LocomotiveScroll related posts - thank you in advance.

 

I have seen the ScrollSmoother plugin and really... I would looove to move to a native GSAP plugin for compatibility reasons, but I'm not a developer and I'll probably use it once for a small personal project. I would have to become a Club GreenSock (ShockinglyGreen) member and yearly renew the subscription in order to get updates for ScrollSmoother only in my case. That's why I've tried to implement a free plugin instead. I do understand the costs and the hard work it takes to develop these plugins though, so please don't get me wrong. 

 

Thank you again! 😉

  • Like 1
Link to comment
Share on other sites

25 minutes ago, StevenCM said:

Moving things at a different speed while smooth scrolling with LocomotiveScroll + having full control on animating objects with ScrollTrigger seem like the basic requirements to me to combine these plugins.

 

Yeah - This isn't a small task. As Jack said - ScrollTrigger calculates these positions upfront for performance reasons. Locomotive and ScrollSmoother don't 'talk' to each other as they're not built to work together.

 

The options are going to be really deep diving in and writing a substantial amount of custom JS logic, 'guesstimating' the entry according to how much the element is shifting with transforms and adjusting the triggers, or using ScrollSmoother.

Link to comment
Share on other sites

Also worth saying that you don't need to renew. We don't stop plugins or your website from working if you don't. You just won't get new features in future! And you shouldn't use the bonus plugins in new projects/sites after your membership expired. 

 

Good luck! 

Link to comment
Share on other sites

Hello @Cassie, thank you too for your reply. I appreciate it.
As I said before, I'm not a developer. I'm a photographer trying to build my own (small static) portfolio website.

Doing it myself, and learning on the go gives me full control and understanding of the libraries and plugins.

I don't have a problem paying for a plugin such as ScrollSmoother if this resolves the challenges that I'm facing, but I do have a problem with the idea of building my website based on a premium plugin and being stuck with it without having access to future updates, or yearly renew the subscription just for a single plugin on a single website.


And again, I'm not here to argue on pricing, nor sound cheap! 😅 I'm just trying to explain why I tried this implementation before anything else. Reached out to the forums as I assumed someone has tried to do the same thing before and might have resolved it.

Best regards,

Steven

 

Link to comment
Share on other sites

If I were you I'd look at flipping it on it's head. Locomotive does detect where elements are in the viewport. So maybe hook into that and trigger GSAP animations at that point?

You won't get the control you get with ScrollTrigger and it'll likely be less performant because it's not precalculating positions though.

Link to comment
Share on other sites

Thanks @Cassie 🙂
 

7 minutes ago, Cassie said:

We just don't like questions to go unanswered/ignored here, so just explaining why you might not get that help, it's not going to be a simple few lines of code to resolve unfortunately.

 

I fully understand.


In the meantime I'm trying out ScrollSmoother on CodePen and it's looking really promising and easy to get started. 
Let's see where we get and probably save me from getting totally loco😉

 

 

 

  • Like 1
Link to comment
Share on other sites

Aha! 😀


I'm so confused right now. I started investigating in plugins such as LocomotiveScroll to accomplish just that, having a "parallax" effect by scrolling elements at a different speed while animating them when they enter the viewport. And I thought 70% of other users were doing this for the same reason?

 

It doesn't seem like a big deal when you are only trying to animate the opacity as I did in the minimal CodePen demo, but when you add a mask layer on top of the image and animate this mask on scroll with a different speed as the image to get a cool "dragging" effect, things get really messy because of the start of the trigger is off. And the higher the data-speed value the worse it gets.

 

I'm really curious to see what other users think about this and how they would solve it.


Did I just earned a Club GreenSock member subsciption as a test-user? 😀

 

Thanks for your efforts @Cassie.

 

 

  • Haha 1
Link to comment
Share on other sites

The problem is that you're applying a speed effect to the container of the trigger element. So let's say the image (child) is 1000px from the bottom of the viewport, so when ScrollTrigger does its calculations, it sets the start to 1000. Great. But it's inside a container that you've applied a data-speed="2" effect to which totally changes everything - now depending on when that container starts moving (dependent on intersection with the viewport), it'll make that child move twice as fast, so in a simplistic way of looking at it, that image's ScrollTrigger would fire 500px too late. But actually, it depends on when that container and its offset from the speed effect hit the viewport, so it may be more like 268.75px late. 

 

We try to optimize things for performance and in order to accommodate this type of thing, it'd have to walk up the entire DOM tree for every single ScrollTrigger and say "does this have a speed effect? How about its parent? And its grandparent?", and then somehow do all the math required to figure out where all those variables converge, etc. 

 

Yeah, it's just not a simple thing. This is also why we can't accommodate nested effects. Sorry. 

 

But a bit of a band-aid approach for your issue would be to use the same trigger as has the data-speed effect applied to it rather than a child. 

Link to comment
Share on other sites

58 minutes ago, GreenSock said:

But a bit of a band-aid approach for your issue would be to use the same trigger as has the data-speed effect applied to it rather than a child. 

 

@GreenSock thank you for your support.
I've forked the previous pen and moved the "data-speed" effect to the images (child) instead of the wrapping containers and it seems to work now.
Let me do some more testing and I'll confirm if this problem has been resolved for me.

Can I ask 2 more questions please?

1. Why would you call this a band-aid approach / solution? 
2.  I'm not sure if I really understand why it works now. Both the images (child) and wrapping containers (parents) are at exactly the same location. There is no padding / margin / offset or whatsoever added to them so I was assuming ScrollTrigger's calculations would be the same for both of them?

 

New pen:

See the Pen XWEEEyo by StevenVDB (@StevenVDB) on CodePen

 

Link to comment
Share on other sites

  • Solution
6 hours ago, StevenCM said:

1. Why would you call this a band-aid approach / solution? 

I didn't mean it in a "bad" way - I simply meant that it doesn't give you the ability to use descendent elements. In most cases, that probably isn't really necessary anyway.

 

6 hours ago, StevenCM said:

I'm not sure if I really understand why it works now. Both the images (child) and wrapping containers (parents) are at exactly the same location. There is no padding / margin / offset or whatsoever added to them so I was assuming ScrollTrigger's calculations would be the same for both of them?

Because there's logic inside ScrollSmoother that looks for ScrollTriggers that have a trigger that IS the element with the effect applied, so it can adjust the start/end values accordingly. 

 

I've actually just updated the beta version of the next release with some code that I believe will help solve this and allow a descendent's trigger to get adjusted. It's the same file that loads into the CodePens above, but here's the URL (only works on CodePen and CodeSandbox): 

https://assets.codepen.io/16327/ScrollSmoother.min.js

 

Does that work better for you? 

Link to comment
Share on other sites

@GreenSock Thank you for the clarification!

 

31 minutes ago, GreenSock said:

I've actually just updated the beta version of the next release with some code that I believe will help solve this and allow a descendent's trigger to get adjusted.

 

Does that work better for you? 

 

That's pretty amazing... 🤩 it actually does!


I can see my initial Pen with ScollSmoother is working now while still using descendent elements.

I guess this topic can be marked as resolved. 👍

 

I'm going to continue building on this one and try to implement all the animations I was initially aiming for, because it used to be a more complex structure with parent / child elements. Fingers crossed. So far so good!  


Thanks a million for the outstanding support @Cassie and @GreenSock.
 

See the Pen poLaMGz by StevenVDB (@StevenVDB) 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.
×
×
  • Create New...