Jump to content
Search Community

Text Reveal Effect using ScrollTrigger

Reboot Studio test
Moderator Tag

Recommended Posts

Hey folks,

 

I'm interested on learning how they guys from Opal built this kind of text reveal effect.

Some nuances are:

1. It is not scrubbed, as the animation is not interpolated but it's triggered at certain scroll position

2. They combine multiple effects in the same timeline (opacity for text, scale for videos)

 

I've built something closer with the snippet below, but the animation is scrubbed.

 

Any ideas?

CleanShot 2024-01-12 at 17.57.07@2x.png

Link to comment
Share on other sites

Welcome to the forums, @Reboot Studio

 

You could just create a timeline with a scrubbed ScrollTrigger, and embed callbacks on that timeline that fire animations to do whatever you want. You can check the ScrollTrigger's direction to know if the animations should fade in or out, for example. 

 

Or you could create individual ScrollTriggered animations that use toggleActions. Lots of options. If you want more help, please make sure you provide a minimal demo that clearly illustrates the issue and we'd be happy to take a peek.

 

Thanks for being a Club GSAP member! 💚

Link to comment
Share on other sites

Thanks @GreenSock

 

Here is a Codepen with the current approach. We are using onUpdate method to add or remove custom classes to text items based on scroll progress. It's pretty verbose though, I'm wonder if Gsap enables a clean approach to do this.

 

https://codesandbox.io/p/devbox/gsap-on-scroll-rxyfgc?file=/components/paragraph.tsx

 

@Rodrigo this could work but notice there is no animation, opacity just goes from 0 to 1 with no transition.

Link to comment
Share on other sites

7 hours ago, Reboot Studio said:

Here is a Codepen with the current approach. We are using onUpdate method to add or remove custom classes to text items based on scroll progress. It's pretty verbose though, I'm wonder if Gsap enables a clean approach to do this.

Yeah, here's what a timeline-based callback approach might look like: 

let tl = gsap.timeline({
	scrollTrigger: {
		markers: true,
		trigger: container.current,
		start: "top top",
		end: "bottom bottom",
		scrub: true,
		pin: `#${id}-pin`,
	}
});
// now space out callbacks across the timeline, one for each block
blocks.forEach((block, i) => {
	let video = block.classList.contains("video") && block.firstChild;
	tl.add(() => {
		if (tl.scrollTrigger.direction > 0) {
			block.classList.add("!opacity-100");
			video && video.play();
		} else {
			block.classList.remove("!opacity-100");
			video && video.pause();
		}
	}, i + 0.01) // we don't want it to be butted up to the very start so that it can get tripped in either direction.
});
tl.set({}, {}, "+=0.01"); // just add a tiny bit of space at the end so that the callback isn't butted exactly up to the very end position and it can get tripped in either direction.

That way, you could skip some of the extra processing you're doing on every update, and looping through every block that's already triggered. In short, it's likely a bit more efficient at runtime. 

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...