Jump to content
Search Community

React Layers Pinner

TaiwoJazz test
Moderator Tag

Recommended Posts

I made a little bit of modification to React layer pinning but i noticed that it only work with fixed height and "top0" css set on the ".panel"

If the top: 0 is comment out, the first page will scroll the entire height but the layer will no longer work.

Here is a link to the my minimal demo https://stackblitz.com/edit/react-1af7mc?file=src%2Fviews%2FLayers.js,src%2Fstyle.css

Link to comment
Share on other sites

@TaiwoJazz I'm confused - your demo doesn't have any pinning at all, right? Instead, you're trying to use position: sticky which is a whole different thing unrelated to ScrollTrigger.  From what I can tell by looking at your code, your ScrollTriggers wouldn't do anything. They're firing as they should...but you don't have them actually doing anything. Or am I missing something? 

 

// not really doing anything: 
panels.forEach((panel, i) => {
  ScrollTrigger.create({
    trigger: panel,
    start: 'top bottom',
    end: '+=' + window.innerHeight * 3,
    markers: true,
  });
});

🤷‍♂️

Link to comment
Share on other sites

Waoo, thanks for that observation, I just noticed that now. You are right. 

First of all, the minimal demo was actually created from this starter template https://stackblitz.com/edit/react-6rzfpp?file=src%2FApp.js
Let's focus on the Layers page.

The issue is that, the sections in the layers page must be 100vh. What we have content that are more than 100vh, and i still want to maintaining the layers animation.

Once we scroll down to the end of each layers, it looks like it's pin while the other section overlay it. But this time, the height is not mandatory 100vh

 

Link to comment
Share on other sites

Hi,

 

Yeah indeed that is predicated on each section's height being 100vh. Any different height requires an entire different setup because of this:

ScrollTrigger.create({
  trigger: panel,
  start: 'top bottom',
  end: () => "+=" + (panel.offsetHeight + window.innerHeight - 1), // offset by 1 pixel to avoid overlaps
  onToggle: (self) => self.isActive && !scrollTween.current && goToSection(i),
});

That is basically what triggers the goToSection method that makes the jump immediate. See the start point configuration?: "top bottom", that means when the top of the trigger hits the bottom of the viewport. If a section height is less than the height of the viewport, two sections go through that before the scrollTween is completed so that boolean in the onToggle callback returns falsy, as shown in this video:

https://i.imgur.com/gF2FsfN.mp4

 

See how sections two and three go through the start point one after the other while the scrollTween is still active?

 

Honestly I can't think of an easy/quick way to accommodate this to the needs you have, the only thing I can think of is to keep elements that are 100vh but make them transparent and keep their content aligned to the top so the previous element will be visible behind the small element and the logic in the onToggle callback will work as expected.

 

Happy Tweening!

Link to comment
Share on other sites

Just to be clear, @Rodrigo, I updated that Stackblitz demo before you looked at it, so it didn't match what @TaiwoJazz was looking at. Sorry about any confusion there. 

 

I have since updated it again to improve the logic and leverage an Observer to get the desired effect:

https://stackblitz.com/edit/react-6rzfpp?file=src%2Fviews%2FLayers.js,src%2Fstyle.css

 

I made the purple panel 50vh tall just to illustrate that it all works as expected, even when the panels aren't 100vh. 

 

Does that help, @TaiwoJazz

  • Like 1
Link to comment
Share on other sites

@RodrigoTanks for the help

@GreenSock Thanks for the help. The animation will work as expected if the panel height is lesser than 100vh but not more then 100vh. This was the problem i was facing before.

As Rodrigo has previously said, i may have to make sure that the panel height are 100vh to achieve that effect.

Link to comment
Share on other sites

Ah, okay. Well, just about anything is doable with the tools and enough elbow grease. I don't have time to go back and forth and build it all out for you, but I was curious so I took a crack at it: 

 

https://stackblitz.com/edit/react-fqulx8?file=src%2Fviews%2FLayers.js,src%2Fstyle.css

 

Hopefully that at least gets you going in the right direction. If you need more, you're welcome to contact us about paid consulting services. 

Link to comment
Share on other sites

@GreenSock Thanks for taking time to provide the above demo.

I tried as much as possible to keep it simple in the first demo i provided above. I didn't include the snapping feature as it makes it more unnecessarily complex.

I have made some changes and i have achieved 100% of the desire result, thanks to your demo.

I think this code monitoring scrollY is causing the flicking so i fixed that by removing the below key: value

pinType: 'transform',

 

My forked demo can be found here https://stackblitz.com/edit/react-a8iwqz?file=src%2Fviews%2FLayers.js,src%2Fstyle.css

Link to comment
Share on other sites

2 hours ago, TaiwoJazz said:

I think this code monitoring scrollY is causing the flicking so i fixed that by removing the below key: value

If that works in your scenario, great. The reason I had pinType: "transform" is because one of the ancestor elements had a transform applied which makes position: fixed relative to that instead of the viewport (it's a CSS thing, not a GSAP thing). If you get vibration, that's almost always because the browser is doing the scrolling on a different (not synchronized) thread. There are several ways to deal with that. One is to use ScrollTrigger.normalizeScroll(true).

 

Or there are more complicated solutions if the vibrating is happening while the scrollTo tween is occuring: you'd set up your own "wheel" and "touchmove" event handlers that use passive: false and then call preventDefault() on the event if (and only if) it's in the middle of tweening. 

 

Anyway, I'm glad to hear you got it working well. Cheers!

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