Jump to content
Search Community

Recommended Posts

Posted
 

Hi!
I hope you're doing great. I'm facing some issues with the code. First of all, I couldn't figure out how to use the pin feature because I've mostly used GSAP with plain HTML, CSS, and JavaScript. Secondly, I couldn't understand the strange behavior of the animation. When I enter the start marker, the content disappears. However, the animation triggered by ScrollTrigger runs smoothly when I exit and re-enter through the end marker.

 
import React, { useEffect, useRef } from "react";
import { gsap } from "gsap";
import pakistanMap from "./assets/pakistanMap.svg";
import worldMap from "./assets/worldMap.svg";
import { ScrollTrigger } from "gsap/ScrollTrigger";
gsap.registerPlugin(ScrollTrigger);
 
const Extra = () => {
  const worldRef = useRef(null);
  const pkRef = useRef(null);
  const containerRef = useRef(null);
 
  useEffect(() => {
    gsap.to(worldRef.current, {
      scale: 0.1,
      opacity: 0,
      duration: 4,
      scrollTrigger: {
        trigger: containerRef.current,
        start: "top 30%",
        end: "bottom 30%",
        markers: {
          start: "start",
          end: "end",
        },
        scrub: 1,
        // pin: true,
        // pin: worldRef.current,
        // pin: containerRef.current,
      },
    });
  }, []);
 
  return (
    <main className="w-full overflow-x-hidden">
      <header className="w-screen h-[70vh] bg-gray-800"></header>
 
      <section
        ref={containerRef}
        className="container flex flex-col gap-4 items-center justify-center bg-white"
      >
        {/* World Map */}
        <div ref={worldRef} className=" w-[500px] h-auto bg-black/20 z-20">
          <img
            className="w-full h-full object-contain"
            src={worldMap}
            alt="World Map"
          />
        </div>
 
        {/* Pakistan Map */}
        <div ref={pkRef} className=" w-[500px] h-auto bg-green-100">
          <img
            className="w-full h-full object-contain"
            src={pakistanMap}
            alt="Pakistan Map"
          />
        </div>
      </section>
 
      <footer className="w-screen h-[80vh] bg-gray-800"></footer>
    </main>
  );
};
 
export default Extra;
 
 
 
GSAP Helper
Posted

Hi there! I see you're using React -

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/

 

If you still need help, here's a React starter template that you can fork to create a minimal demo illustrating whatever issue you're running into. Post a link to your fork back here and we'd be happy to take a peek and answer any GSAP-related questions you have. Just use simple colored <div> elements in your demo; no need to recreate your whole project with client artwork, etc. The simpler the better. 

GreenSock
Posted

One other thing to be very careful about with Tailwind projects - don't ever apply CSS transitions to the things that GSAP is controlling. I think by default Tailwind might apply CSS transitions which prevents GSAP from making immediate changes which is necessary for pinning and ScrollTriggers. When GSAP tries to set a value, CSS transitions are like "NOPE! I won't let you do that...instead, I'll drag those changes out and make them gradually..." The same goes for anything with scroll-behavior: smooth (avoid that). I'd also recommend making sure you're using the latest version of GSAP (3.12.7 right now). 

 

If you're still having trouble, please provide a minimal demo that clearly illustrates the issue. 

Posted
18 hours ago, GreenSock said:

One other thing to be very careful about with Tailwind projects - don't ever apply CSS transitions to the things that GSAP is controlling. I think by default Tailwind might apply CSS transitions which prevents GSAP from making immediate changes which is necessary for pinning and ScrollTriggers. When GSAP tries to set a value, CSS transitions are like "NOPE! I won't let you do that...instead, I'll drag those changes out and make them gradually..." The same goes for anything with scroll-behavior: smooth (avoid that). I'd also recommend making sure you're using the latest version of GSAP (3.12.7 right now). 

 

If you're still having trouble, please provide a minimal demo that clearly illustrates the issue. 

How

On 1/19/2025 at 4:57 AM, GSAP Helper said:

Hi there! I see you're using React -

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/

 

If you still need help, here's a React starter template that you can fork to create a minimal demo illustrating whatever issue you're running into. Post a link to your fork back here and we'd be happy to take a peek and answer any GSAP-related questions you have. Just use simple colored <div> elements in your demo; no need to recreate your whole project with client artwork, etc. The simpler the better. 

Thanks, but you didn't answer my question about the use of the pin. Please tell me how to use the pin in GSAP react

 

On 1/19/2025 at 4:57 AM, GSAP Helper said:

Hi there! I see you're using React -

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/

 

If you still need help, here's a React starter template that you can fork to create a minimal demo illustrating whatever issue you're running into. Post a link to your fork back here and we'd be happy to take a peek and answer any GSAP-related questions you have. Just use simple colored <div> elements in your demo; no need to recreate your whole project with client artwork, etc. The simpler the better. ok but 

 

Posted

Hi,

 

We have a stackblitz collection of demos and starter templates for React projects, you can fork one of those in order to present a minimal demo of what you're trying to achieve:

https://stackblitz.com/@gsap-dev/collections/gsap-react-starters

 

Here is a simple demo:

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

 

Finally using pinning in React is no different than using it in Svelte, Vue or a  Vanilla JS project, is just javascript. For future references always start by the docs and the learning resources we have available:

https://gsap.com/docs/v3/

https://gsap.com/resources/

 

Happy Tweening!

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