Jump to content
Search Community

R3F + Model - ScrollSmoother - ScrollTrigger

SeventySeven test
Moderator Tag

Recommended Posts

Hello everybody.


Im trying to develop something that involves R3F and some GSAP plugins. I've made a codesandbox that maybe helps people to understand and help me out.

 

https://codesandbox.io/s/r3f-scrollsmoother-scrolltrigger-lidew2

 

I would like the model to have the scrolltrigger animation synced with the SmoothScroll behaviour. While doing the sandbox I first tried with a basic geometry and it worked just fine. Right now, model rotates based on window position instead of scroll position, so both animations are not synced.

 

I tried to use the "scroller" option inside scrollTrigger but it doesn't work on my setup.

 

Maybe is something not related with gsap at all, but if someone could help me out a bit I would appreciate it very much.

 

Thanks a lot!

Link to comment
Share on other sites

Hi @SeventySeven and welcome to the GreenSock forums!

 

I don't know anything about R3F so I can't give you much advice on that.

 

What actually throws me off is the fact that you have some GSAP code in your Model.jsx file and this script.js file that you're adding directly to the HTML file 🤔, I've actually never seen that before. Any particular reason for that approach? Why not put everything in your JSX files? My best guess is that this is actually a possible cause for your issues. Also I would move all the HTML elements to the React component and keep all the logic there so you have more control over it and you can sync your app more accurately.

 

Also you should use GSAP Context when integrating GSAP in your React projects:

https://greensock.com/docs/v3/GSAP/gsap.context()

 

Also take a look at this articles as they provide a solid starting point for using GSAP in React environments:

 

Finally you should use the latest version of GSAP, your example was using 3.10.4.

 

Hopefully this helps.

Happy Tweening!

Link to comment
Share on other sites

Thanks Rodrigo.

 

I already tried to use gsap context but couldn't make it work.

 

The project im building is more complex than what i showed in the sandbox. I tried to create a minimal demo that was throwing the error im finding. I've already built a whole dom structure that is working with gsap scrolltrigger + scrollsmoother with HTML elements and a script.js file. (Same as the two objects I created in the sandbox)

 

Now, im trying to build an R3F project in the top of that, but i can't really sync the animations. I'm basically only using react (r3f) to build the 3D part. ¿Any clue about how to achive that?


Thanks again.

 

 

Link to comment
Share on other sites

Hi,

 

As I mentioned is quite odd that you have parts of your GSAP code in a JSX file (React component) and another in a separate file. I'd concentrate everything in your React components/files.

 

Here is a React example that uses ScrollSmoother with GSAP Context in it:

https://stackblitz.com/edit/react-iqmjfx?file=src%2FApp.js

 

You can fork it and adapt it to illustrate the issues you're having.

 

As I mentioned I have no experience with R3F, but a first step should be to concentrate all your JS and HTML in the React files and components and not use this weird setup you have right now.

 

Happy Tweening!

Link to comment
Share on other sites

I migrated the project to a react context, and now it works propperly. I'm not sure that this is the way to do it, since i have gsap animations outside the gsap context.

 

https://codesandbox.io/s/mmigration-to-react-obz8x6?file=/src/Domcreate.jsx

 

How should i call a gsap animation for a ref that is inside another component? Like for example, how would be the propper way to call that gsap function inside the Model.jsx?

 

Thanks a lot for your responses and your time!

Link to comment
Share on other sites

Hi,

 

In your model component just create a GSAP Context instance as well. There is limitation to create just one GSAP Context per app, you can create as many as you need. GSAP Context provides super easy scoping, cleaning/reverting when components get unmounted and many other super helpful perks, but there is no obligation to create just one. For example in your model component you can do this:

export function Model(props) {
  const { nodes, materials } = useGLTF("/src/model.glb");
  const group = useRef();

  useEffect(() => {
    const ctx = gsap.context(() => {
      gsap.to(group.current.rotation, {
        scrollTrigger: {
          trigger: "#first",
          scrub: 0.2,
          start: "top top",
          end: "bottom top",
          markers: true,
          id: "MODEL",
        },
        y: Math.PI * 2,
        immediateRender: false
      });
    });
    return () => ctx.revert();
  }, []);

  return (
    <>
      <pointLight position={[10, 10, 10]} />
      /* REST OF YOUR JSX HERE */
    </>
  );
}

That should be enough.

 

Is anything in this particular example that is not working as you expect?

 

Hopefully this helps.

Happy Tweening!

Link to comment
Share on other sites

Hello!

 

First of all, thanks for all the tips. The sandbox i created just worked pretty fine, but when I scaled to my project things went bit different. I tried to replicate that logic, and to be honest everything seems to work just fine.

Anyway, when i load the project simulating slow network connection, scrolltriggers that are located inside components are not firing at all. If I load the webpage just normally it works fine.

 

Can this be an issue related with the topic we were talking about?

 

 

Link to comment
Share on other sites

Hey @SeventySeven can you elaborate more about this problem? I use gsap a lot in 3D animation..also you can ask at the

https://discourse.threejs.org/ if you have a question about R3F. I can help you with this but I don't understand well why you put out the script.js in the useEffect method. You should have put it in the useEffect and also don't create this in the index.html that is so messy.

 

    <div id="wrapper">
      <div id="content">
        <section id="first">
          <div class="element"></div>
        </section>
        <section id="second">
          <div class="element"></div>
        </section>
      </div>
    </div>
    <script type="module" src="src/script.js"></script>

 

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