Apply scrollTrigger to a section of page (for 100vh pages) in mui react

105 Views Asked by At

I'm new to gsap and I want to create timeline animation like this (I've attached the images below) where if I scroll, current section should fade away and next section should fade in (changing the state of timeline on the left side too). To make the pages 100vh (which is requirement in my case) I've used overflow: none property but the scrolltrigger doesn't works if the page scroll is hidden. If I hide it, it doesn't work.

so far I've written this code.

import { useEffect, useRef, useState } from "react";
import { StepTimleline, TextCard, Wrapper } from "./Common/ReusableObj";
import { features } from "./Common/Data";
import { Grid, Tab, Typography, Tabs, Box, Stack } from "@mui/material";

import { gsap } from "gsap";
import { ScrollTrigger } from "gsap/ScrollTrigger";
import { Link } from "react-router-dom";

gsap.registerPlugin(ScrollTrigger);

export default function Features() {
  const [isActive, setIsActive] = useState(null);
  const [isTabActive, setIsTabActive] = useState("#section-1");
 
  useEffect(() => {
    setIsActive(location.pathname);
  }, [location]);

  useEffect(() => {
    gsap.to(".section-1", {
      scrollTrigger: {
        trigger: ".section-1",
        
        toggleActions: "play none none reverse",
      },
      y: -600,
    });
    
    gsap.to(".section-2", {
      scrollTrigger: {
        trigger: ".section-2",
       
        toggleActions: "play none none reverse",
      },
      y: -500,
    });
    
    gsap.to(".section-3", {
      scrollTrigger: {
        trigger: ".section-3",
        
        toggleActions: "play none none reverse",
      },
      y: -500,
    });
    
    gsap.to(".section-4", {
      scrollTrigger: {
        trigger: ".section-4",
        
        toggleActions: "play none none reverse",
      },
      y: -500,
    });
  }, []);

  return (
    <>
      <Wrapper
        sx={{
          height: "auto",
        }}
        className={
          isActive === "/"
            ? "res-height wrapper-center border-box"
            : "wrapper-center border-box"
        }
      >
        <StepTimleline
          className="steps-timeline features"
          sx={{ alignSelf: "center", marginTop: { xs: "6rem", md: 0 } }}
        >
          <Stack className="steps" spacing={3}>
            {features.map((item, index) => (
              <Link
                key={index}
                className={
                  isTabActive === `#section-${index + 1}` ? "active" : ""
                }
                href={`#section-${index + 1}`}
                to={`#section-${index + 1}`}
                onClick={() => {
                  setIsTabActive(`#section-${index + 1}`);
                }}
              ></Link>
            ))}
          </Stack>

          <Stack>
            {features.map((item, index) =>
              index % 2 == 0 ? (
                <Box
                  key={index}
                  id={`#section-${index + 1}`}
                  className={`section-${
                    index + 1
                  } sections justify-content-center`}
                  ref={imgRef}
                >
                  <Grid
                    container
                    sx={{
                      height: { md: "auto", lg: "-webkit-fill-available" },
                    }}
                  >
                    <Grid
                      item
                      xs={12}
                      md={6}
                      className="d-flex align-items-center justify-content-center"
                    >
                      <TextCard>
                        <Typography className="section-title">
                          {item.sectionTitle}
                        </Typography>
                        <Typography className="section-text">
                          {item.content}
                        </Typography>
                      </TextCard>
                    </Grid>
                    <Grid
                      item
                      xs={12}
                      md={6}
                      sx={{ marginTop: { xs: "1rem", md: 0 } }}
                      className="d-flex align-items-center justify-content-center"
                    >
                      <img src={item.img} alt="goddess" loading="lazy" />
                    </Grid>
                  </Grid>
                </Box>
              ) : (
                <Box
                  key={index}
                  id={`section-${index + 1}`}
                  className={`section-${
                    index + 1
                  } sections justify-content-center`}
                  ref={imgRef}
                >
                  <Grid
                    container
                    sx={{
                      height: { md: "auto", lg: "-webkit-fill-available" },
                    }}
                  >
                    <Grid
                      item
                      xs={12}
                      md={6}
                      className="d-flex align-items-center justify-content-center"
                      sx={{
                        marginTop: { xs: "1rem", md: 0 },
                        order: { xs: "2", md: "1" },
                      }}
                    >
                      <img src={item.img} alt="fruit" loading="lazy" />
                    </Grid>
                    <Grid
                      item
                      xs={12}
                      md={6}
                      className="d-flex align-items-center justify-content-center"
                      sx={{
                        order: { xs: "1", md: "2" },
                      }}
                    >
                      <TextCard>
                        <Typography className="section-title">
                          {item.sectionTitle}
                        </Typography>
                        <Typography className="section-text">
                          {item.content}
                        </Typography>
                      </TextCard>
                    </Grid>
                  </Grid>
                </Box>
              )
            )}
          </Stack>
        </StepTimleline>
      </Wrapper>
    </>
  );
}

Style component

export const StepTimleline = styled(Box)`
  width: -webkit-fill-available;
  overflow: hidden;

  &.features {
    height: calc(100vh - 20vh);

    img {
      width: 636.12px;
      height: 585.27px;

      @media (max-width: 1200px) {
        width: 550px;
        height: 550px;
      }

      @media (max-width: 900px) {
        width: 496px;
        height: 472px;
      }

      @media (max-width: 500px) {
        width: 296px;
        height: 272px;
      }
    }
  }

  .steps {
    position: sticky;
    top: 0;
    left: 0;
    align-items: end;
    float: inline-start;
    z-index: 1;

    a.active {
      background: linear-gradient(180deg, #c798ff 1.28%, #8824b6 101.28%);
      box-shadow: 0px 0px 8px 0px #b05bec;
      opacity: 1;
    }
    a {
      width: 4px;
      background: #b87cd4;
      opacity: 0.15;
    }
  }

  .sections:nth-of-type(odd) {
    display: flex;
    opacity: 1;
    transition: all 2s ease-in;
  }
  .sections:nth-of-type(even) {
    display: flex;
    opacity: 1;
    transition: all 2s ease-in;
  }

  @media (max-width: 900px) {
    .res-btn button {
      width: 288px;
      height: 63px;
      img {
        width: 288px;
        height: 63px;
      }
    }
    .footer {
      position: absolute;
    }
  }
`;

(https://i.stack.imgur.com/WCHai.png) (https://i.stack.imgur.com/mZFQW.png)

0

There are 0 best solutions below