Jump to content
Search Community

Vertical Scroll Pin and scrolling through a container

jaeyholic test
Moderator Tag

Recommended Posts

I am new to GSAP and I love it so far. I am working on this project but I am facing an issue now. I want to pin a section, then when scrolling, the stacks on images change, set the currentIndex state with the new index, and update the data on the right side of the section. when the current image, leaves the stack, I want it to go to the back of the stack, and the current image comes on top. I have been struggling to finish it and need some help, please.

 

Codesandbox link:  https://codesandbox.io/p/devbox/epic-hill-qgf7r5?file=%2Fsrc%2FApp.jsx%3A111%2C73&workspaceId=832ea3ad-fd7e-4423-a361-77ecef5fb412

 

image.thumb.jpeg.bcb88ad9eda09041cc2bbd23e82c66e1.jpeg

 

See the Pen src by p (@p) on CodePen

Link to comment
Share on other sites

Hi @jaeyholic welcome to the forum!

 

Your codesandbox link is not working, maybe you didn't publish it yet? Personally I like to work in Codepen, just plain HTML, CSS and JS, so that I don't have to worry about my preferred library of choice throwing errors and really can focus on the effect I'm going for, but of course to each their own. 

 

The best thing to do when working with ScrollTrigger is to remove it! This seems counter intuitive, but ScrollTrigger is just animating something on scroll, so just focus on the animation at first and only when you're happy with the animation add ScrollTrigger back in. This way you can focus on one part at a time and it will save a lot of headache when debugging. 

 

It is probably not the effect you're going for, but maybe it points you in the right direction. This one works on click, but could also work on scroll, again everything in GSAP starts with an animation and you can then hook it to what ever you like to play that animation. Hope it helps and happy tweening! 

 

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

  • Like 1
Link to comment
Share on other sites

5 hours ago, mvaneijgen said:

Hi @jaeyholic welcome to the forum!

 

Your codesandbox link is not working, maybe you didn't publish it yet? Personally I like to work in Codepen, just plain HTML, CSS and JS, so that I don't have to worry about my preferred library of choice throwing errors and really can focus on the effect I'm going for, but of course to each their own. 

 

The best thing to do when working with ScrollTrigger is to remove it! This seems counter intuitive, but ScrollTrigger is just animating something on scroll, so just focus on the animation at first and only when you're happy with the animation add ScrollTrigger back in. This way you can focus on one part at a time and it will save a lot of headache when debugging. 

 

It is probably not the effect you're going for, but maybe it points you in the right direction. This one works on click, but could also work on scroll, again everything in GSAP starts with an animation and you can then hook it to what ever you like to play that animation. Hope it helps and happy tweening! 

 

 

 

I have tried this but doesn't seem to work for me. the stack doesn't go behind, it just gets off the stack and hides

Link to comment
Share on other sites

Hi,

 

Two things.

 

First, proper cleanup is very important with frameworks, but especially with React. React 18 runs in strict mode locally by default which causes your useEffect() and useLayoutEffect() to get called TWICE.

 

Since GSAP 3.12, we have the useGSAP() hook (the NPM package is here) that simplifies creating and cleaning up animations in React (including Next, Remix, etc). It's a drop-in replacement for useEffect()/useLayoutEffect(). All the GSAP-related objects (animations, ScrollTriggers, etc.) created while the function executes get collected and then reverted when the hook gets torn down.

 

Here is how it works:

const container = useRef(); // the root level element of your component (for scoping selector text which is optional)

useGSAP(() => {
  // gsap code here...
}, { dependencies: [endX], scope: container }); // config object offers maximum flexibility

Or if you prefer, you can use the same method signature as useEffect():

useGSAP(() => {
  // gsap code here...
}, [endX]); // simple dependency Array setup like useEffect()

This pattern follows React's best practices.

 

We strongly recommend reading the React guide we've put together at https://gsap.com/resources/React/

 

Two, you have this on your setup:

onUpdate: (self) => {
  const progress = self.progress;
  const index = Math.floor(progress * images.length);
  // HERE
  setCurrentPrayerIndex(index);

  gsap.set(`#image-${currentPrayerIndex}`, {
    rotation: 0,
    scale: 1,
    zIndex: prayers.length,
  }); // Reset rotation, scale, and z-index
},

The onUpdate callback of a ScrollTrigger instance is going to fire everytime the scroll position is updated. Do you really want to update the state of your component everytime the user scrolls? On top of that since that state property you're updating is on the useEffect hook and you're not doing proper cleanup, the GSAP Timeline is being created again and again and again, so everytime the user scrolls you have more and more GSAP Timelines and ScrollTrigger instances, which is a memory leak.

 

I would strongly recommend you to not use ScrollTrigger for now, just focus on creating the animation. Once the animation is working the way you intend, then you can add ScrollTrigger back into the mix. Also take a look at the useGSAP hook and the article link I shared in order to bbetter understand how things are wired up when using GSAP in a react app.

 

Happy Tweening!

Link to comment
Share on other sites

12 hours ago, Rodrigo said:

Hi,

 

Two things.

 

First, proper cleanup is very important with frameworks, but especially with React. React 18 runs in strict mode locally by default which causes your useEffect() and useLayoutEffect() to get called TWICE.

 

Since GSAP 3.12, we have the useGSAP() hook (the NPM package is here) that simplifies creating and cleaning up animations in React (including Next, Remix, etc). It's a drop-in replacement for useEffect()/useLayoutEffect(). All the GSAP-related objects (animations, ScrollTriggers, etc.) created while the function executes get collected and then reverted when the hook gets torn down.

 

Here is how it works:

const container = useRef(); // the root level element of your component (for scoping selector text which is optional)

useGSAP(() => {
  // gsap code here...
}, { dependencies: [endX], scope: container }); // config object offers maximum flexibility

Or if you prefer, you can use the same method signature as useEffect():

useGSAP(() => {
  // gsap code here...
}, [endX]); // simple dependency Array setup like useEffect()

This pattern follows React's best practices.

 

We strongly recommend reading the React guide we've put together at https://gsap.com/resources/React/

 

Two, you have this on your setup:

onUpdate: (self) => {
  const progress = self.progress;
  const index = Math.floor(progress * images.length);
  // HERE
  setCurrentPrayerIndex(index);

  gsap.set(`#image-${currentPrayerIndex}`, {
    rotation: 0,
    scale: 1,
    zIndex: prayers.length,
  }); // Reset rotation, scale, and z-index
},

The onUpdate callback of a ScrollTrigger instance is going to fire everytime the scroll position is updated. Do you really want to update the state of your component everytime the user scrolls? On top of that since that state property you're updating is on the useEffect hook and you're not doing proper cleanup, the GSAP Timeline is being created again and again and again, so everytime the user scrolls you have more and more GSAP Timelines and ScrollTrigger instances, which is a memory leak.

 

I would strongly recommend you to not use ScrollTrigger for now, just focus on creating the animation. Once the animation is working the way you intend, then you can add ScrollTrigger back into the mix. Also take a look at the useGSAP hook and the article link I shared in order to bbetter understand how things are wired up when using GSAP in a react app.

 

Happy Tweening!

Thank you so much. I am changing the logic to use useGsap. I will go through the whole guide and try to figure this out one more time. Thank you once again

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