Jump to content
Search Community

GSAP ScrollTrigger with separate scrollRef in React

LVegetable test
Moderator Tag

Recommended Posts

I have started learning GSAP recently and have been loving it. However, I have been experimenting with ScrollTrigger now and likely due to my own design choices it is not quite working. To whomever takes the time to help me with this, thank you so much in advance 🙏 And apologies for the broken CodePen, I added it anyways in case it helped understanding the description of the problem better, but it was really hard to recreate a Next Typescript React Tailwind project within a codepen.... I am new to web dev so I don't exactly have that 'mindset' yet so also apologies for the spaghetti code and appraoches hhaha.

 

My project uses React with Next. The problem i'm having is likely due to the fact that I use a scroll ref for scroll context instead of the window scroll. I'm doing this because the website consists of 3 layers. 1. The main background, this (ideally) would change colors with ScrollTrigger. I have not yet done this as I have encountered the problem with ScrollTrigger in a different component, but my idea was to attach a ScrollTrigger to each section and based on enter and leave change the color. 2. The content background, this just sits on top and is a padded div that has a different constant background color. The key thing is that this is where all of the content (layer 3) lies, and so I need to have overflow-y-auto here, such that when you scroll you scroll the content/children within this div. Because of this for any ScrollTrigger animation I need a ref to this div, that I have within context so that I can provide it to the children below. 

 

Now the problem is related to the pinning of a section in layer 3 to create a horizontal scroll effect with some other animations I have in mind. The first problem with pinning here is that I get a wobbly effect when I try to scroll the section. I found a similar question on the forums at 

 However, it seemed to be quite related to PIXI which I do not use. Theres also the first solution provided that sets pinTyped to fixed but I do need to enable clicking and mouse interaction within this section so I cannot simply disable pointer events. The second problem is that while I am in this section, I am still scrolling the section and so even if it did work I would end up at the bottom of the page upon exit.

I have tried quite a few things so far but to no avail :(... What I currently have is: Upon entering, use a scrolltrigger to pin and set a state of isPinned. This isPinned. When scrolling in this area, the actual event will .preventDefault() and instead add to the h(orizontal)ScrollContainer.scrollLeft, to some extent adding this middleman that will fake scrolling. This also checks if we have reached the maxScrollLeft which is some value that once we have scrolled past we will use to setIsPinned to false, and kill/disable the trigger. The reason I had to do this is because otherwise I will never reach the end since all I will be doing is adding to scrollLeft, the actual mouse scroll event is still disabled. Now we exit this pin but this still has problems. Firstly since we kill or disable it, it will reset which looks bad going back up. Furthermore, you cant reactivate it backwards. Additionally, it is still wobbly if I scroll into this section very fast before the actual pin takes effect. I'm not sure if killing it is the best thing but the entire code I have right now is starting to like my shoelaces back in kindergarten.  This solution is the best I can think of right now, perhaps to introduce reverse scrolling I would use isScrollingDown and then use a seperate reverse ScrollTrigger but...... Yeah Im struggling hahah and I dont really like spaghettiness of the code right now....

 

It is making me rethink the design of the website but it would suck to not have ScrollTrigger cause - its cool - and cool is good hahah. Perhaps the best solution is to figure out a way to build the project with global scroll. The main problem with this is that when I tried, for some reason none of the components I wrote would render as body would go above and Z indexes didn't do anything, probably something related to how Next works that I dont understand....


Anyhow, again, thank you so much to whomever takes the time to help figure this out, I tried to describe the situation as best as I could but it is quite messy and at some point I begin to yap.... 💀 hh, anyways, if anything requires further clarification then I would be happy to help and provide that!~

See the Pen YzMMGEK?editors=1010 by Markingcomic40 (@Markingcomic40) on CodePen

Link to comment
Share on other sites

Hi @LVegetable welcome to the forum!

 

Have you seen our Stackblitz starter templates? It has a boilerplate for all the major frameworks, including next.js

 

In all my time developing websites I've never needed to overwrite the default scroll behaviour there is always a better way, I think. From your description I would also not read anything that needs to overwrite the default scroll behaviour. Your background can just be a fixed element and the other elements can just scroll or animate them with the y property in GSAP. Keep in mind that everything in GSAP is an animation, even things on scroll start out as an animation. Check out this tutorial how to work with ScrollTrigger 

 

 

 

Personally I always start in codepen and really focus on the logic I need before I bring it over to my framework. It usually takes me around 10 versions to get to a state I am happy with and then it will be trivial to port it over to what ever framework you like, but the web is basic HTML, CSS, JS so if that is solid it will work any where! 

 

You can work with React in codepen and you can then set it up like the pen below. But again, personally I would remove all abstractions and just focus on the basics and when that is working your can port it to what ever you like. Hope it helps and happy tweening! 

 

See the Pen OJmQvLZ?editors=0010 by GreenSock (@GreenSock) on CodePen

 

 

 

 

  • Like 2
Link to comment
Share on other sites

Hi,

 

Just to add to @mvaneijgen's great advice, you can create a new NextJS project in Stackblitz. Click on the large New Project button at the top left and select NextJS in the FullStack tab:

Hb8atUM.png

The one thing we ask to our users is to keep the demo as small and simple as possible, just the easiest way to re-create the probem you're facing.

 

Also in ScrollTrigger you can set a scroller property if you don't want to use the window object as the default scroller. From the ScrollTrigger docs:

scroller
String | Element - By default, the scroller is the viewport itself, but if you'd like to add a ScrollTrigger to a scrollable <div>, for example, just define that as the scroller. You can use selector text like "#elementID" or the element itself.

 

https://gsap.com/docs/v3/Plugins/ScrollTrigger/#config-object

 

Hopefully this helps.

Happy Tweening!

  • Like 1
Link to comment
Share on other sites

Hello, thank you so much for the quick responses @Rodrigo and @mvaneijgen, and apologies for the delayed reply, I worked on it today morning after reading the first one but got caught up with stuff after.

 

I took a step back and looked over the code again today and noticed that I had quite some nesting with HTML tags all loaded with Tailwind stylings I forgot about that were messing me up so I ended up 'cleaning the project up' as best as I could and moved back to using the window scroll instead of a reference. I did check the docs for using a reference to scroll, it just didn't work at the time but likely due to all the nesting I had. Probably would have been able to figure it out the way it was, but I think the new approach is a little cleaner and for now, I think, I got the ScrollTrigger to work, the pinning at least.... kind of (?)

 

Kind of.... I have run into a new problem now.... Sry cause its somewhat unrelated the question/title of this thread, but... I am now encountering a new problem with ScrollTrigger. My design includes an animated canvas layer that updates continuously, and it appears to cause a clipping effect with ScrollTrigger and Pin (When you scroll into the section fast). I initially thought this was due to the visual effects, but it seems more related to the computational load, possibly interfering with GSAP... I noticed this when I was trying to optimize the effect using a GLSL shader instead of just pure JS which sort of helped but not really, and adding things like throttling etc where if I delayed the animations to only update every 50ms it would happen and otherwise it would all be fine... (Also I tried anticipate scroll and It didnt seem to help).

 

I attached a 'proper' demo using the StackBlitz templates this time with a similar environment!~ Not exactly the same because I wasn't going to throw in the whole shader and all that but the result is the same. Im not sure if theres a solution to this but I thought it would be worth mentioning anyhow, perhaps I just need to further optimize the component or think of a new design..... Also the current pin and scroll trigger is quite terrible, kind of embarrassing to share with the GSAP team hahaha, I'll see if I can add the horizontal scrolling and all tomorrow...

 

Anyways, thanks again for the quick help~ I wasn't expecting a reply so soon haha.


(SomeComponent has the ScrollTrigger, SomeEffect is the computationally heavy effect (sry for naming I put it together real quick without thinking much 💀))
https://stackblitz.com/edit/stackblitz-starters-xmk1gs?file=app%2Fcomponents%2FSomeComponent.tsx

Link to comment
Share on other sites

Hi,

 

I'm not completely sure of what the issue is in your stackblitz demo, but it seems to me that your HTML/CSS needs some tinkering in order to accommodate the horizontal panels correctly.

 

Here is a simple demo showing how a horizontal movement is achieved through vertical scroll on a Next app using GSAP and the useGSAP hook:

https://stackblitz.com/edit/stackblitz-starters-zsu4zc

 

Hopefully this helps.

Happy Tweening!

Link to comment
Share on other sites

Hello,

 

Thanks again for the quick response @Rodrigo~ The problem is I have a component that renders a canvas on top of everything and that this causes the pinning to look glitchy when scrolling into the sections fast enough. The component itself could be invisible and it still causes the problem. I attached a video and added the component to the StackBlitz you sent me. It is somewhat hard to see but the pinning is glitchy at the bottom when entering the pin, after entering its fine, and in reverse it would make a glitchy look on top).

 

Kind Regards,

L

 

https://stackblitz.com/edit/stackblitz-starters-3lbk7s?file=app%2Fcomponents%2FExpensiveEffect.tsx

Link to comment
Share on other sites

Yeah that is most definitely not a GSAP related problem, the fact that the issue disappears after you remove a component that has no GSAP code in it tells us that, whatever is causing this problem is inside that component. I'm not sure about what you're trying to do in there, but you should really try to optimize it because I made a performance recording with devtools with just that component, no GSAP code whatsoever, and the performance is as bad as with GSAP.

 

Unfortunately this boils down to something that is beyond the scope of these free forums and the help we can provide here, since we have to focus our time to GSAP related issues.

 

Happy Tweening!

Link to comment
Share on other sites

Hello~ okok, ill look into it then, thanks~  Yeah, the one in the demo is random, I just added a ton of math functions to simulate a computationally heavy component so that the glitch effect is more noticeable.

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