I am using GSAP and Lenis to make the web.
There are two components, Part1 and Part2, and Part2 is seen before the tl1 timeline of GSAP applied in Part1 is finished.
Maybe it's a problem caused by a collision between the rendering of the components and the GSAP used in useEffect.
It seems like a common problem when using React and GSAP together, how do you all solve it??
App.jsx:
const App = () => {
useEffect(() => {
gsap.registerPlugin(ScrollTrigger);
smooth();
});
return (
<>
<Wrap>
<Nav />
<Part1 />
<Part2 />
</Wrap>
</>
);
};
export default App;
Part1.jsx:
function Part1() {
const rows = [
[Image1, Image2, Image3, Image4],
[Image5, Image6, Image7, Image8],
[Image9, Image10, Image11, Image12],
[Image1, Image2, Image3, Image4],
[Image5, Image6, Image7, Image8],
];
useEffect(() => {
let ctx = gsap.context(() => {
var tl1 = gsap.timeline({
scrollTrigger: {
trigger: ".part-1",
start: "50% 50%",
end: "250% 50%",
scrub: true,
markers: true,
pin: true,
},
});
tl1
.to(".rotate-div", { rotate: -15, scale: 0.8 }, "a")
.to(".row-div-1", { marginTop: "5%" }, "a")
.to(".row-div-2", { marginTop: "-2%" }, "a")
.to(".row-div-3", { marginTop: "-8%" }, "a")
.to(".row-div-4", { marginTop: "-10%" }, "a")
.to(".overlay-div h1", { opacity: 1, delay: 0.2 }, "a")
.to(".overlay-div", { backgroundColor: "#000000b4" }, "a")
.to(".scrolling", { width: "100%" }, "a");
});
return () => ctx.revert();
}, []);
return (
<Wrap className="part1">
<div className="content-part-1">
<div className="rotate-div">
{rows.map((row, rowIndex) => (
<div key={rowIndex} className={`row-div row-div-${rowIndex}`}>
{row.map((img, imgIndex) => (
<div key={imgIndex} className="img-div">
<img src={img} alt={`Image ${rowIndex * 4 + imgIndex + 1}`} />
</div>
))}
</div>
))}
</div>
<div className="overlay-div">
<h1>Monta</h1>
<div className="scroll-down">
<h3>SCROLL DOWN</h3>
<div className="scroll-p">
<div className="scrolling" />
</div>
</div>
</div>
</div>
</Wrap>
);
}
export default Part1;
Part2.jsx:
import React, { useEffect } from "react";
import { Wrap } from "./Part2Style";
import { gsap, ScrollTrigger } from "gsap/all";
const Part2 = () => {
const text = ["Lorem ipsum dolor sit", "mollitia iure dolor digmos."];
return (
<Wrap className="part-2">
<div className="rounded-div-wrapper">
<div className="rounded-div"></div>
</div>
<div className="content-2">
<div className="text-area">
<h1>{text[0]}</h1>
<br />
<h2>{text[1]}</h2>
</div>
<div className="text-area-hover">
<h1>{text[0]}</h1>
<br />
<h2>{text[1]}</h2>
</div>
</div>
</Wrap>
);
};
export default Part2;
CodeSandBox : React