Wavy Text Animation using React Hooks with GSAP v3
We will learn to use GSAP v3 with React hooks, next to that i'll build my own textsplitter.
In this article i'll create a wavy text animation with React Hooks
and GSAP v3
. For the example I created my own small text split function. This example should be usable in React frameworks like Gatsby, Next.js, etc.
Tech stack
- React for markup, templating, routing, etc.
- GSAP for animation
- EmotionCSS to write normal CSS, nest selectors and componentize styles
Goal
We want to create text that animates on first-load. The text should be split for each letter, then animate once smoothly.
Markup
First we create a styled element
1<div className="App">2 <WavyTextStyled ref={wavyTextRef}>ride the waaaaaaaave</WavyTextStyled>3</div>
CSS
We make the text look pretty with some css. The font-size
value is based on a clamp
function used in WebGL.
The function creates a range between 1600px
and 320px
screenwidth. Within this range it calculates a font-size
between 64px
and 32px
.
1const TextStyled = styled.p`2 font-size: calc(32px + (64 - 32) * ((100vw - 320px) / (1600 - 320)));3 font-family: poppins;4 font-weight: 500;5 margin: 0;6 color: white;7`;
Using hooks
We need to keep a reference to the text to target it with GSAP
.
Next to that, we only want the animation to run on load and once.
If we give an empty dependecy array to the useEffect
, it will trigger once.
1export default function App() {2 const wavyTextRef = useRef(null);34 useEffect(() => {5 // ANIMATION GOES HERE6 }, []);78 return (9 <div className="App">10 <TextStyled ref={wavyTextRef}>ride the waaaaaaaave</TextStyled>11 </div>12 );13}
Animating with GSAP
To start animating with GSAP, we want to be sure the ref has been initialised.
Afterwards, we split the text with the function underneath this codeblock.
This function will return all letters in the text as span
elements with some necessary styling.
To start animating, we set the perspective of the TextStyled
component to 400 to create depth.
Afterwards we animate the letters from
certain values
I'm pretty sure, that gsap.from also does a gsap.set under the hood. This results in the element being set in the starting position on load.
1if (!wavyTextRef.current) return;2const chars = SplitTextToChars(wavyTextRef.current);34gsap.set(wavyTextRef.current, { perspective: 400 });56gsap.from(7 chars,8 {9 duration: 0.8,10 opacity: 0,11 scale: 1,12 delay: 2,13 y: -40,14 rotationX: -90,15 transformOrigin: '0% 50% -50',16 ease: 'back',17 stagger: 0.1,18 },19 '+=0'20);
1function SplitTextToChars(textNode) {2 const textContent = textNode.textContent;3 const textSplit = textContent.split('');45 const frag = document.createDocumentFragment();6 textSplit.forEach((letter, i) => {7 const span = document.createElement('span');8 span.textContent = letter;9 span.style = `${letter === ' ' ? 'min-width: 1rem;' : ''}z-index: ${10 textSplit.length - i11 }; position: relative; display: inline-block;`;12 frag.appendChild(span);13 });14 textNode.textContent = '';15 textNode.appendChild(frag);1617 return textNode.children;18}1920export default SplitTextToChars;
Demo
That's it!
PS.
If you are wondering how you can use GSAP v3 during interaction we can just create functions like this, with event target
or pass a reference
:
1<button onClick={e => {2 gsap.to(e.target, {3 duration: 1,4 color: green;5 })6}}>click!</button>
Final words
That's it!
You can link this animation to an Intersection Observer
to animate while scrolling, or keep it like this to animate when someone navigates.
Thanks for reading!
I hope someone somewhere learned something via this post! If you did, please consider sharing the article.
Other posts you might like
Accessible Wavy Text Animation using React Hooks and Framer Motion
February 17, 2021In this article i'll recreate a wavy text animation we built with React Hooks and GSAP v3 but…
How we drove up sales with animation and storytelling
October 05, 2020“Good animation is invisible. You shouldn’t notice that you’re looking at animation. You want to…
Transforming an image to animating Particles with Web Audio
August 19, 2020At my company Level30Wizards , we experiment with web techniques to learn how we can implement…