Jump to content
Search Community

Gsap scrolltrigger not working in React component

Ehsan.shv test
Moderator Tag

Go to solution Solved by OSUblake,

Recommended Posts

Hello, I'm working on a React component for parallax image effect. The component:

import React, { FC, useLayoutEffect, useRef } from 'react';

import { gsap } from 'gsap';
import { ScrollTrigger } from 'gsap/ScrollTrigger';
gsap.registerPlugin(ScrollTrigger);

interface ParallaxImageProps {
  src: string;
  alt?: string;
}

export const ParallaxImage: FC<ParallaxImageProps> = ({ src, alt }) => {
  const parallaxImage = useRef(null);
  const parallaxImageInner = useRef(null);

  useLayoutEffect(() => {
    const tl = gsap.timeline({
      scrollTrigger: {
        trigger: parallaxImage.current,
        scroller: '.nice-scroll-container',
        scrub: true,
        pin: false,
      },
    });
    tl.from(parallaxImageInner.current, {
      yPercent: -10,
      ease: 'none',
    }).to(parallaxImageInner.current, {
      yPercent: 10,
      ease: 'none',
    });
  }, []);

  return (
    <figure className="parallax-image" ref={parallaxImage}>
      <img
        src={src}
        alt={alt}
        className="parallax-image__inner"
        ref={parallaxImageInner}
        onLoad={() => ScrollTrigger.refresh()}
      />
    </figure>
  );
};

 I had tested onEnterand onLeavemethods and those executed in right time but animating image from yPercent: -10 to yPercent: 10 have not been working properly and have been triggering when the image comes in middle of the viewport. Any solution?

Live Demo

Link to comment
Share on other sites

It's pretty tough to troubleshoot without a minimal demo - the issue could be caused by CSS, markup, a third party library, your browser, an external script that's totally unrelated to GSAP, etc. Would you please provide a very simple CodePen or CodeSandbox that demonstrates the issue? 

 

Please don't include your whole project. Just some colored <div> elements and the GSAP code is best (avoid frameworks if possible). See if you can recreate the issue with as few dependancies as possible. If not, incrementally add code bit by bit until it breaks. Usually people solve their own issues during this process! If not, then at least we have a reduced test case which greatly increases your chances of getting a relevant answer.

 

Here's a starter CodePen that loads all the plugins. Just click "fork" at the bottom right and make your minimal demo

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

 

If you're using something like React/Next/Nuxt/Gatsby or some other framework, you may find CodeSandbox easier to use. 

 

Once we see an isolated demo, we'll do our best to jump in and help with your GSAP-specific questions. 

  • Like 1
Link to comment
Share on other sites

28 minutes ago, GSAP Helper said:

It's pretty tough to troubleshoot without a minimal demo - the issue could be caused by CSS, markup, a third party library, your browser, an external script that's totally unrelated to GSAP, etc. Would you please provide a very simple CodePen or CodeSandbox that demonstrates the issue? 

 

Please don't include your whole project. Just some colored <div> elements and the GSAP code is best (avoid frameworks if possible). See if you can recreate the issue with as few dependancies as possible. If not, incrementally add code bit by bit until it breaks. Usually people solve their own issues during this process! If not, then at least we have a reduced test case which greatly increases your chances of getting a relevant answer.

 

Here's a starter CodePen that loads all the plugins. Just click "fork" at the bottom right and make your minimal demo

 

 

If you're using something like React/Next/Nuxt/Gatsby or some other framework, you may find CodeSandbox easier to use. 

 

Once we see an isolated demo, we'll do our best to jump in and help with your GSAP-specific questions. 

Live Demo

Link to comment
Share on other sites

Hello @Ehsan.shv

 

2 hours ago, Ehsan.shv said:

I had tested onEnterand onLeavemethods and those executed in right time but animating image from yPercent: -10 to yPercent: 10 have not been working properly and have been triggering when the image comes in middle of the viewport. Any solution?

 

To me it looks to be working just how the ScrollTrigger is set up - starting when the container's top (which is your trigger) hits the top of the window. You can see that a bit clearer, when setting a background-color on the .parallax-image container and increasing the yPercent values of the tweens a bit. But maybe I'm just misunderstanding your question? 

 

https://codesandbox.io/s/strange-fermat-tyogs9?file=/src/ParallaxImage.tsx

 

 

 

Edit:

Oh wait, the default on non-pinning STs actually is 'top bottom' - so something definitely seems to be off here.

Even when explicitely setting the start to 'top bottom', it still starts in 'top top' 🤔 Sorry for the confusion.

 

Unfortunately I myself am not a React guy, so we'll have to wait for someone who is a bit more React savvy to jump in.

 

Thanks for your patience!

  • Like 1
Link to comment
Share on other sites

  • Solution

The first thing you need to do for React is to make sure React 18 isn't going create any issues. You need to make sure it doesn't create something twice.

 

 

You also need to create that smooth scrollbar thing before creating your ScrollTriggers. Code in a child component will run before their parent, so that means your smooth scrollbar is being created last.

 

 

  • Like 1
  • Thanks 1
Link to comment
Share on other sites

6 hours ago, OSUblake said:

The first thing you need to do for React is to make sure React 18 isn't going create any issues. You need to make sure it doesn't create something twice.

 

 

You also need to create that smooth scrollbar thing before creating your ScrollTriggers. Code in a child component will run before their parent, so that means your smooth scrollbar is being created last.

 

 

Thanks. Yes, you're right. what a nice topic that you linked. I learned a lot. I handled rendering child component after parent component by <React.Suspense></React.Suspense>

  • Like 1
Link to comment
Share on other sites

11 minutes ago, OSUblake said:

Would you mind adding what you did with Supense to your CodeSandbox so other people can see in case they have the same issue?

Yes, it's done. However, this is a part of an open-source library that I'm working on it and when it's complete I'll add the repo link to this topic.

  • Thanks 1
Link to comment
Share on other sites

10 minutes ago, OSUblake said:

 

I'm also asking for curiosity because I've never used Suspense before. 😋

Suspense and Lazy loading are amazing stuff for async and improving performance in React. I don't know have you seen Kent C. Dodds course about React before or no, if don't I suggest you to see React Performance section from that course.

  • Like 1
Link to comment
Share on other sites

  • 2 weeks later...

An update for this topic:

1- Previous approach to executing triggers after smooth scrollbar initialization didn't work in production. I've solved executing triggers after parent rendering by the global state. At first parent renders then set a global state and then the child component renders.

2- I've published a React package by smooth-scrollbar and GSAP that has some components for scroll-based animations. Check repo.

If there is an issue or you have suggestions or ideas please tell me.

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