Hello,
I would like to convert the `Animated Continuous Sections with GSAP Observer` JavaScript code by Brian into a React.js component. However, I encountered the following error: `GSAP target undefined not found. https://greensock.com.` Could anyone assist me in converting the JavaScript code to React.js code?
Thank you in advance. my code:
import React, { useLayoutEffect, useState, useRef } from "react";
import { gsap } from "gsap"
import { Observer } from "gsap/Observer";
import '../GCCarousel.css';
gsap.registerPlugin(Observer);
const GCCarousel = () => {
const [currentIndex, setCurrentIndex] = useState(0);
const main = useRef()
let animating = false;
useLayoutEffect(() => {
let ctx = gsap.context(() => {
const sections = document.querySelectorAll("section");
const images = document.querySelectorAll(".bg");
const headings = gsap.utils.toArray(".section-heading");
const outerWrappers = gsap.utils.toArray(".outer");
const innerWrappers = gsap.utils.toArray(".inner");
const wrap = gsap.utils.wrap(0, sections.length);
gsap.set(outerWrappers, { yPercent: 100 });
gsap.set(innerWrappers, { yPercent: -100 });
function gotoSection(index, direction) {
index = wrap(index); // make sure it's valid
animating = true;
let fromTop = direction === -1,
dFactor = fromTop ? -1 : 1,
tl = gsap.timeline({
defaults: { duration: 1.25, ease: "power1.inOut" },
onComplete: () => (animating = false),
});
if (currentIndex >= 0) {
// The first time this function runs, current is -1
gsap.set(sections[currentIndex], { zIndex: 0 });
tl.to(images[currentIndex], { yPercent: -15 * dFactor }).set(sections[currentIndex], { autoAlpha: 0 });
}
gsap.set(sections[index], { autoAlpha: 1, zIndex: 1 });
tl.fromTo(
[outerWrappers[index], innerWrappers[index]],
{ yPercent: (i) => (i ? -100 * dFactor : 100 * dFactor) },
{ yPercent: 0 },
0
)
.fromTo(images[index], { yPercent: 15 * dFactor }, { yPercent: 0 }, 0)
.fromTo(
headings[index].chars,
{ autoAlpha: 0, yPercent: 150 * dFactor },
{
autoAlpha: 1,
yPercent: 0,
duration: 1,
ease: "power2",
stagger: {
each: 0.02,
from: "random",
},
},
0.2
);
setCurrentIndex(index);
}
const handleScroll = (event) => {
if (!animating) {
const direction = event.deltaY < 0 ? -1 : 1;
gotoSection(currentIndex + direction, direction);
}
};
document.addEventListener("wheel", handleScroll);
document.addEventListener("touchstart", handleScroll);
document.addEventListener("pointerdown", handleScroll);
gotoSection(0, 1);
return () => {
document.removeEventListener("wheel", handleScroll);
document.removeEventListener("touchstart", handleScroll);
document.removeEventListener("pointerdown", handleScroll);
};
}, main); // <- IMPORTANT! Scopes selector text
return () => ctx.revert();
}, [currentIndex]);
return (
<main ref={main}>
<header>
<div>Animated Sections</div>
<div>
<a href="https://codepen.io/BrianCross/pen/PoWapLP">Original By Brian</a>
</div>
</header>
<section className="first">
<div className="outer">
<div className="inner">
<div className="bg one">
<h2 className="section-heading">Scroll down</h2>
</div>
</div>
</div>
</section>
<section className="second">
<div className="outer">
<div className="inner">
<div className="bg">
<h2 className="section-heading">Animated with GSAP</h2>
</div>
</div>
</div>
</section>
<section className="third">
<div className="outer">
<div className="inner">
<div className="bg">
<h2 className="section-heading">GreenSock</h2>
</div>
</div>
</div>
</section>
<section className="fourth">
<div className="outer">
<div className="inner">
<div className="bg">
<h2 className="section-heading">Animation platform</h2>
</div>
</div>
</div>
</section>
<section className="fifth">
<div className="outer">
<div className="inner">
<div className="bg">
<h2 className="section-heading">Keep scrolling</h2>
</div>
</div>
</div>
</section>
</main>
);
};
export default GCCarousel;