Jump to content
Search Community

Tabs or dots sections click redirect not working next js

Cristian Rojas test
Moderator Tag

Go to solution Solved by Rodrigo,

Recommended Posts

The tabs or dots do not redirect correctly to the section when clicking, also sometimes when scrolling it does not work well, how could I solve these errors without losing the fluids?

"use client";

import React, { useEffect, useRef, useState } from "react";

import { gsap } from "gsap";
import { ScrollTrigger } from "gsap/ScrollTrigger";
import { ScrollToPlugin } from "gsap/ScrollToPlugin";

gsap.registerPlugin(ScrollTrigger, ScrollToPlugin);

function TextRevealGsap() {

  useEffect(() => {
    let panels = gsap.utils.toArray(".panel");
    let scrollTween;

    function goToSection(i) {
      scrollTween = gsap.to(window, {
        scrollTo: {
          y: i * innerHeight,
          autoKill: false,
          ease: "Power3.easeInOut",
        },
        duration: 1.5,
        onComplete: () => (scrollTween = null),
        overwrite: true,
      });
    }

    panels.forEach((panel, i) => {
      const tl = gsap.timeline({ paused: true, reversed: true });
      const tlreverse = gsap.timeline({ paused: true, reversed: true });

      tl.to(panel.querySelector(".parr1"), { xPercent: 0, opacity: 1 }).to(
        panel.querySelector(".parr2"),
        { xPercent: 0, opacity: 1 },
        "<"
      );

      tlreverse
        .to(panel.querySelector(".parr1"), { xPercent: -50, opacity: 0 })
        .to(panel.querySelector(".parr2"), { xPercent: 50, opacity: 0 }, "<");

      ScrollTrigger.create({
        trigger: panel,
        onToggle: (self) => self.isActive && !scrollTween && goToSection(i),
      });

      ScrollTrigger.create({
        trigger: panel,
        start: "bottom bottom",
        onEnterBack: () => goToSection(i),
      });

      ScrollTrigger.create({
        animation: tl,
        trigger: panel,
        start: "top bottom",
        end: "top top",
        scrub: 1,
        /* markers: true, */
      });

      ScrollTrigger.create({
        animation: tlreverse,
        trigger: panel,
        start: "bottom bottom",
        end: "bottom top",
        scrub: 1,
      });
    });




    let links = gsap.utils.toArray("nav a");
    links.forEach((a, i) => {
      let element = document.querySelector(a.getAttribute("href")),

      linkST = ScrollTrigger.create({
        trigger: element,
        start: "top top",
      });

      ScrollTrigger.create({
        trigger: element,
        start: "top center",
        end: "bottom center",
        onToggle: (self) => self.isActive && setActive(a),
      });

      a.addEventListener("click", (e) => {
        e.preventDefault();
        gsap.to(window, {
          duration: 1.5,
          scrollTo: linkST.start,
          overwrite: "auto",
        });
      });
    });

    function setActive(link) {
      links.forEach((el) => el.classList.remove("active"));
      link.classList.add("active");
    }
  }, []);

  return (
    <div className=" h-screen w-full mainy">
      <section id="one" className="panel red">
        <p className="parr1">This is page 1</p>
        <p className="parr2">h1 1</p>
      </section>
      <section id="two" className="panel green">
        <p className="parr1">This is page 2</p>
        <p className="parr2">h2 2</p>
      </section>
      <section id="three" className="panel blue">
        <p className="parr1">This is page 3</p>
        <p className="parr2">h3 3</p>
      </section>
      <section id="four" className="panel orange">
        <p className="parr1">This is page 4</p>
        <p className="parr2">h4 4</p>
      </section>

      <nav>
        <div>
          <a href="#one">Section one</a>
        </div>
        <div>
          <a href="#two">Section two</a>
        </div>
        <div>
          <a href="#three">Section three</a>
        </div>
        <div>
          <a href="#four">Section four</a>
        </div>
      </nav>
    </div>
  );
}

export default TextRevealGsap;

 

See the Pen dyEZZaZ by Front-end-Dev-the-looper (@Front-end-Dev-the-looper) on CodePen

Link to comment
Share on other sites

Hi  @Cristian Rojas and welcome to the GSAP Forums!

 

The main issue you're running  into here is that everytime you pass one of the start/end points of your ScrollTrigger instances (at least the ones that call the gotoSection method). So when you click on one of the links the ScrollTo instance is created and runs, but then you pass that section's trigger and this other ScrollTo instance is created and takes over, that's why if you want to go to the last section from the first, you actually have to click that link three times. See the problem?

 

This is the simplest way I can think of to get around this:

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

 

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

 

Hopefully this helps

Happy Tweening!

Link to comment
Share on other sites

Hello Rodrigo, in advance, I apologize for having asked another question almost similar to this one in another forum, I am new to gsap and also to next js, but nevertheless I appreciate the advice and the solution given, therefore other problems arose with the solution

 

1. In this case, there are other sections above and below apart from the ones we already have, the scroll is bugged, this was the question I asked in the other forum, and I don't know how to find the solution

 

2. In this case there are more than 4 tabs and sections and it also fails when clicking

Example code attached

 

See the Pen yLWPEoK by Front-end-Dev-the-looper (@Front-end-Dev-the-looper) on CodePen

Link to comment
Share on other sites

Yeah, one of the SrollTrigger instances that is calling the gotoSection method is clearly interfering with this, as well as this logic in the gotoSection:

scrollTo: {
  y: i * innerHeight,
  autoKill: false,
  ease: "Power3.easeInOut"
},

Basically for the first instance that tells the ScrollTo Plugin to go to y: 0, so that's the top of the page.

 

Right now I don't have time to review all the logic and come up  with a solution for this particular scenario. I'll see if I can make some time in the coming days to solve this, but I want to manage expectations regarding timing.

 

Finally I would strongly recommend you to extend from this demo which is simpler and less convoluted than yours and should give you an easier way to solve this (this is the one I'll be tweaking actually):

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

 

Happy Tweening!

Link to comment
Share on other sites

Good morning Rodrigo, thank you for the advice, they have definitely been very useful to me, with the demo you attached I consider that it is not the result I want to obtain, what I am looking for is that the children of the sections have an entrance and exit animation with the scroll, that the sections can have a scroll snap effect and also that you can navigate between sections with tabs or dots.

 

However, I found a way where the tabs work perfectly, and it is also not blocked with sections at the top and bottom, the only thing is:

 

1. I can't find a way for the sections to have a scroll snap

 

2. When I scroll down the children of the sections do not have an entry animation

 

I attach a demonstration, always grateful for the help provided

 

See the Pen yLWPEoK?editors=0110 by Front-end-Dev-the-looper (@Front-end-Dev-the-looper) on CodePen

Link to comment
Share on other sites

  • Solution

Hi,

 

You are using an extremely convoluted setup. For example this in your loop:

ScrollTrigger.create({
  trigger: panel,
});

ScrollTrigger.create({
  trigger: panel,
  start: "bottom bottom",

});

ScrollTrigger.create({
  animation: tl,
  trigger: panel,
  start: "top bottom",
  end: "top top",
  scrub: 1
}); 

ScrollTrigger.create({
  animation: tlreverse,
  trigger: panel,
  start: "bottom bottom",
  end: "bottom top",
  scrub: 1
});

You're creating four Scrolltrigger instances there, two of them don't have any reason to exists as far as I can see.

 

This seems like a better and simpler approach IMHO:

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

 

Hopefully this helps.

Happy Tweening!

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