Skip to content

Instantly share code, notes, and snippets.

@TylerBarnes
Last active July 5, 2022 16:25
Show Gist options
  • Select an option

  • Save TylerBarnes/a3cce6f93c12ab39f18499275dfcb40e to your computer and use it in GitHub Desktop.

Select an option

Save TylerBarnes/a3cce6f93c12ab39f18499275dfcb40e to your computer and use it in GitHub Desktop.
Staggered Character reveal with GSAP and React Hooks
import React, { useRef, useEffect } from "react";
import { SplitText } from "../../libs/gsap/SplitText";
import { TimelineLite } from "gsap";
import styled from "styled-components";
const animateChars = nodes => {
new TimelineLite().staggerFromTo(
nodes,
1,
{ xPercent: "+=100%", opacity: 0 },
{ xPercent: "0%", opacity: 1 },
0.1,
0
);
};
const wrapChars = (el, wrapper) => {
el.parentNode.insertBefore(wrapper, el);
wrapper.appendChild(el);
wrapper.setAttribute("class", "char-container");
};
const CharacterReveal = ({ children }) => {
const text = useRef(null);
const wrapper = useRef(null);
useEffect(() => {
if (typeof document === "undefined") return;
const textSplit = new SplitText(text.current, {
type: "chars"
});
for (const char of textSplit.chars) {
wrapChars(char, document.createElement("span"));
}
setTimeout(() => animateChars(textSplit.chars, wrapper.current), 100);
});
return (
<div ref={wrapper}>
<Container ref={text}>{children}</Container>
</div>
);
};
export default CharacterReveal;
const Container = styled.div`
.char-container {
position: relative;
overflow: hidden;
padding: 0.5px;
display: inline-block;
> div {
opacity: 0;
}
}
`;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment