我想根据条件禁用我的 gsap 代码中的滚动

问题描述 投票:0回答:1

我的代码中有 4 个部分,我在 React js 中使用 gsap rollTrigger 进行动画,当我滚动到第三部分(即灯泡部分)时,我想禁用滚动,因为我在该部分中有按钮来显示最初的一些文本false 当我切换该按钮时,它会将其状态更改为 true 并显示我的文本,当显示文本时,我想继续滚动,直到我想禁用滚动 以下是 gsap 和部分的代码。

const Animate = () => {
  const [isChecked, setIsChecked] = useState(false);
  const [enableScrollForTimelineThree, setEnableScrollForTimelineThree] =
    useState(false);

  const [showText, setShowText] = useState(false);
  useEffect(() => {
    if (isChecked) {
      setTimeout(() => {
        setShowText(true);
      }, 1000);
    } else {
      setShowText(false);
    }
  }, [isChecked]);

  const sectionRef = useRef();

  useGSAP(
    () => {
      let translateAmount = sectionRef.current.clientHeight / 4;
      let masterTimeline = gsap.timeline();

      const createTimelineForRedBall = () => {
        const timeline = gsap.timeline();
        timeline
          .to(".red-ball", { duration: 0, opacity: 1, y: translateAmount })
          .to(".red-ball", { duration: 0.5, opacity: 1, y: 0 })
          .to(".red-ball", {
            duration: 1,
            delay: 1,
            opacity: 0,
            y: -translateAmount,
          });
        return timeline;
      };

      const createTimelineForVideo = () => {
        const timeline = gsap.timeline();
        timeline
          .to(".red-ball-video", { duration: 1, scale: 1, opacity: 1 })
          .to(".red-ball-video", { duration: 0.5, scale: 0.5, opacity: 0.5 })
          .to(".red-ball-video", { duration: 1, scale: 0, opacity: 0 });
        return timeline;
      };

      const createTimelineForFadedRedBall = () => {
        const timeline = gsap.timeline();
        timeline
          .to(".faded-red-ball", {
            duration: 0,
            opacity: 0,
            y: translateAmount,
          })
          .to(".faded-red-ball", { duration: 0.5, opacity: 1, y: 0 })
          .to(".faded-red-ball", {
            duration: 1,
            delay: 1,
            opacity: 0,
            y: -translateAmount,
          });
        return timeline;
      };

      const createTimelineForBulbSection = () => {
        const timeline = gsap.timeline();
        timeline
          .to(".bulb-section", {
            duration: 0,
            opacity: 0,
            y: translateAmount,
          })
          .to(".bulb-section", {
            duration: 0.5,
            opacity: 1,
            y: 0,
          })
          .to(".bulb-section", {
            duration: 1,
            delay: 1,
            opacity: 0,
            y: -translateAmount,
          });
        return timeline;
      };

      const createTimelineForChangeSection = () => {
        const timeline = gsap.timeline();
        timeline
          .to(".change-section", {
            duration: 0,
            opacity: 0,
            y: translateAmount,
          })
          .to(".change-section", { duration: 0.5, opacity: 1, y: 0 })
          .to(".change-section", {
            duration: 1,
            delay: 1,
            opacity: 1,
            y: -translateAmount,
            paused: false,
          });
        return timeline;
      };

      const updateGlobe = (element) => {
        return gsap.timeline().to(element, {
          duration: 0,
          delay: 0,
          css: {
            left: "0%",
          },
        });
      };

      let timelineGlobe = updateGlobe(".globe");

      if (window.innerWidth >= 768) {
        masterTimeline
          .add(createTimelineForRedBall(), 0)
          .add(createTimelineForFadedRedBall(), 2.5)
          .add(createTimelineForBulbSection(), 5)
          .add(createTimelineForChangeSection(), 8)
          .add(timelineGlobe, 8.02)
          .add(createTimelineForVideo(), 0);
      } else {
        masterTimeline
          .add(createTimelineForRedBall(), 0)
          .add(createTimelineForFadedRedBall(), 2.5)
          .add(createTimelineForBulbSection(), 5)
          .add(createTimelineForChangeSection(), 8)
          .add(timelineGlobe, 8.02)
          .add(createTimelineForVideo(), 0);
      }

      ScrollTrigger.create({
        trigger: sectionRef.current,
        animation: masterTimeline,
        start: "top top",
        end: "+=200%",
        scrub: 1,
        pin: true,
        ease: "power1.inOut",
      });
    },
    { dependencies: [showText], scope: sectionRef }
  );
  return (
    <BlackSection ref={sectionRef}>
      <WhySection className="red-ball">
        <H2 className=".not-text-fadeUp">Feeling a bit Hotter eh??</H2>
        <WhyContentContainer>
          <StyledVideo
            autoPlay={true}
            muted
            playsInline
            loop
            className="red-ball-video"
          >
            <source src="/videos/red-ball.mp4" type="video/mp4"></source>
            Your browser does not support the video.
          </StyledVideo>
          <WhyContent>
            <h3 className="title">WHY?</h3>
            <p className="text pt-4">
              A tree can absorb only 1.8kg in a month<br></br>Your current
              lifestyle emits 30 kg CO2eq of Green House Gases (GHG)on average
              per month!
            </p>
          </WhyContent>
        </WhyContentContainer>
      </WhySection>

      <ReduceSection className="faded-red-ball">
        <ReduceContainer>
          <p className="text pb-4">
            But How can you reduce these GHG emissions to help the Globe be
          </p>
          <h3 className="title colorful-title">
            <span>Healthier.</span>
            <span> Cooler. </span>
            <span>Greener?</span>
          </h3>
        </ReduceContainer>
      </ReduceSection>
      <BulbAndText className="bulb-section">
        {!showText && (
          <BulbSection className="bulbSection" isVisible={!isChecked}>
            <div className="bulbcontain">
              <img
                src="/images/tubelight.png"
                alt="Bulb"
                className="img-fluid"
              />

              <BulbContent>
                <h4 className="switch-text">Switch off the Button</h4>

                <label className="switch">
                  <input
                    type="checkbox"
                    id="togBtn"
                    onChange={() => setIsChecked(!isChecked)}
                  />
                  <div className="slider round">
                    <span className="on">ON</span>
                    <span className="off">OFF</span>
                  </div>
                </label>
              </BulbContent>
            </div>
          </BulbSection>
        )}

        {showText && (
          <TextSection className="text-section fadeIn">
            <TextContainer>
              <TextContent>
                You can save up to 1kg CO2eq if you choose to turn off lights
                for extra hours when not in use by this small action
              </TextContent>
              <TextContent>
                Imagine the Impact of similar small actions globally
              </TextContent>
            </TextContainer>
          </TextSection>
        )}
      </BulbAndText>
      <ChangeMakerSection className="change-section">
        <div className="change-maker">
          <picture>
            <source
              media="(min-width: 768px)"
              srcSet="/images/globe.png"
              alt="Globe"
              sizes="768px"
            />
            <img src="/images/globeMobile.png" alt="Globe" className="globe" />
          </picture>
          <Container>
            <ChangeContainer>
              <ChangeContent>
                This is your moment to be among the <span>47,770+</span> Change
                makers in climate action
              </ChangeContent>
              <ChangeNumber>
                <Number>1,17,000</Number>
                <Unit>kgCO2eq</Unit>
              </ChangeNumber>
              <ChangeDetail>
                <DetailContainer>
                  {globeIcon}
                  <div>
                    <h6>110</h6>
                    <p>Best Way to Bring the Change</p>
                  </div>
                </DetailContainer>
                <DetailContainer>
                  {co2Icon}
                  <div>
                    <h6>2000000</h6>
                    <p>KG Avoided GHG Emissions</p>
                  </div>
                </DetailContainer>
              </ChangeDetail>
            </ChangeContainer>
          </Container>
          <img
            src="images/barLines.png"
            alt="Bar lines"
            className="bar-lines"
          />
        </div>
      </ChangeMakerSection>
    </BlackSection>
  );
};

我尝试了 onEnter , onLeaveBack 但没有任何效果

reactjs gsap scrolltrigger
1个回答
0
投票

要实现当用户到达第三部分 (

bulb-section
) 直到切换按钮时禁用滚动的行为,您可以使用
ScrollTrigger
中的
gsap
插件。您可以通过以下方式修改代码来实现此目的:

  1. 添加
    ScrollTrigger
    以在用户输入
    bulb-section
    时禁用滚动。
  2. 根据按钮切换来切换滚动禁用状态。

这是修改后的代码:

import { useState, useEffect, useRef } from "react";
import { gsap } from "gsap";
import { ScrollTrigger } from "gsap/ScrollTrigger";

gsap.registerPlugin(ScrollTrigger);

const Animate = () => {
  const [isChecked, setIsChecked] = useState(false);
  const [showText, setShowText] = useState(false);

  const sectionRef = useRef();

  useEffect(() => {
    // Function to handle the button toggle
    const handleToggle = () => {
      setIsChecked(!isChecked);
    };

    // ScrollTrigger to disable scrolling when entering bulb-section
    ScrollTrigger.create({
      trigger: sectionRef.current,
      onEnter: () => {
        gsap.globalTimeline.pause();
      },
      onLeaveBack: () => {
        gsap.globalTimeline.resume();
      },
    });

    // Clean up event listener on component unmount
    return () => {
      window.removeEventListener("toggle", handleToggle);
    };
  }, [isChecked]);

  // Your existing GSAP animations and JSX code here...

  return (
    <BlackSection ref={sectionRef}>
      {/* Your sections here */}
    </BlackSection>
  );
};

export default Animate;

在此修改后的代码中:

  • 我们在
    ScrollTrigger
    (
    bulb-section
    ) 中添加了
    sectionRef.current
    ,当用户进入该部分时暂停全局时间线(禁用滚动),并在用户向后滚动时恢复全局时间线。
  • 按钮切换(
    isChecked
    )用于控制滚动状态。切换按钮时,状态会发生变化,并且全局时间线会恢复,从而允许继续滚动。

确保根据您的具体要求和动画调整触发器和条件。

© www.soinside.com 2019 - 2024. All rights reserved.