Greensock (GSAP) ScrollTrigger - 2 consecutive ScrollTrigger animations?

GH: https://github.com/nnall/GSAP/tree/main/experiments/react-playground/src I have a para that I've applied a 'SplitType' to in order to get the paragraph lines, apply .to() methods to them, and translate them X in my GSAP scrollTrigger animation:
let tl = gsap.timeline();

const my_para = document.querySelector(".reveal-type"); // SELECT PARA
const text = new SplitType(my_para, { types: "chars, words, lines" });

const lines = [...text.lines];
const linesRev = [...lines].reverse();

// console.log(lines);

lines.forEach((line, index) => {
tl.to(
line,
{
x: "-100vw",
duration: 3,
// opacity: 1,
},
"-=2.5"
);
});
scrollTrigger.create({
trigger: ".spacer_2",
start: "45% 100%",
end: "30% 30%",
scrub: true,
markers: true, // for debugging
animation: tl, // Assign the timeline to ScrollTrigger
});
let tl = gsap.timeline();

const my_para = document.querySelector(".reveal-type"); // SELECT PARA
const text = new SplitType(my_para, { types: "chars, words, lines" });

const lines = [...text.lines];
const linesRev = [...lines].reverse();

// console.log(lines);

lines.forEach((line, index) => {
tl.to(
line,
{
x: "-100vw",
duration: 3,
// opacity: 1,
},
"-=2.5"
);
});
scrollTrigger.create({
trigger: ".spacer_2",
start: "45% 100%",
end: "30% 30%",
scrub: true,
markers: true, // for debugging
animation: tl, // Assign the timeline to ScrollTrigger
});
Each of the paragraph lines come into screen from the right side (translate x) when the user scrolls downward, starting at the top line moving to the bottom, and with a slight stagger thanks to the"-=2.5". I want to have a second scrollTrigger animation to move the lines back out - see my comment..
GitHub
GSAP/experiments/react-playground/src at main · nnall/GSAP
for GSAP experimenting. Contribute to nnall/GSAP development by creating an account on GitHub.
2 Replies
MarkBoots
MarkBoots6mo ago
not experienced with gsap. but looking at the code. Can't you just create a new timeline with the trigger on .spacer_3?
thethingisback
thethingisback6mo ago
The end result I want is for the para lines to swoop in from the right, coming into view in the middle of the page, and then swoop off the left side of the page, starting on the bottom line. Here I've created a second timeline, and a second 'lines' array ('linesRev'), which is all of the same lines but in the reverse order. And in the second .forEach(), I'm applying a a .fromTo() to each line, in order to manually set the lines start (x:-100), the post-1st-animation position on the x axis . Here's my approach to having two animations:
// Step 1: Create a GSAP timeline
let tl = gsap.timeline();
let tl2 = gsap.timeline();

// SPLIT-TYPES - PARA
const my_para = document.querySelector(".reveal-type"); // SELECT PARA
const text = new SplitType(my_para, { types: "chars, words, lines" });

const lines = [...text.lines];
const linesRev = [...lines].reverse();

// console.log(lines);

lines.forEach((line, index) => {
tl.to(
line,
{
x: "-100vw",
duration: 3,
// opacity: 1,
},
"-=2.5"
);
});
scrollTrigger.create({
trigger: ".spacer_2",
start: "45% 100%",
end: "30% 30%",
scrub: true,
markers: true, // for debugging
animation: tl, // Assign the timeline to ScrollTrigger
});

linesRev.forEach((line, index) => {
tl2.fromTo(
line,
{
x: "-100vw", // Start value
},
{
x: "-220vw", // End value
duration: 3,
// Any other properties you want to set
},
"-=2.5"
);
});

scrollTrigger.create({
trigger: ".spacer_2",
start: "110% 100%",
end: "150% 30%",
scrub: true,
markers: true, // for debugging
animation: tl2, // Assign the timeline to ScrollTrigger
});
// Step 1: Create a GSAP timeline
let tl = gsap.timeline();
let tl2 = gsap.timeline();

// SPLIT-TYPES - PARA
const my_para = document.querySelector(".reveal-type"); // SELECT PARA
const text = new SplitType(my_para, { types: "chars, words, lines" });

const lines = [...text.lines];
const linesRev = [...lines].reverse();

// console.log(lines);

lines.forEach((line, index) => {
tl.to(
line,
{
x: "-100vw",
duration: 3,
// opacity: 1,
},
"-=2.5"
);
});
scrollTrigger.create({
trigger: ".spacer_2",
start: "45% 100%",
end: "30% 30%",
scrub: true,
markers: true, // for debugging
animation: tl, // Assign the timeline to ScrollTrigger
});

linesRev.forEach((line, index) => {
tl2.fromTo(
line,
{
x: "-100vw", // Start value
},
{
x: "-220vw", // End value
duration: 3,
// Any other properties you want to set
},
"-=2.5"
);
});

scrollTrigger.create({
trigger: ".spacer_2",
start: "110% 100%",
end: "150% 30%",
scrub: true,
markers: true, // for debugging
animation: tl2, // Assign the timeline to ScrollTrigger
});
The first animation works but there's a problem halfway through scrolling, before I get to the second 'start' % Tried that just now, still having problems with it. What's happening is that the paragraph is loading split somehow, where the bottom half of the paragraph is already-translated x to the "-100vw", so already in the middle, visible area, unaffected by the animation, while the top half of the para does the animation as I want. Then, when the second scrollTrigger start line is reached, the second animation occurs as expected, moving off the right siude of the page starting on the bottom line. Whether setting the trigger to .spacer_3 (with adjusted 'start' line to 0% <-- top of .spacer_3), or else still using .spacer_2, but setting the second scrollTrigger start line to '110%' (so past the bottom of .spacer_2), in either case, the first paragraph is getting split in half vertically. and the first animation is not being fully applied to it.