Skip to content

Instantly share code, notes, and snippets.

@willhalling
Created March 25, 2021 11:25
Show Gist options
  • Save willhalling/e76edc84003b68d860f05a0bcf280734 to your computer and use it in GitHub Desktop.
Save willhalling/e76edc84003b68d860f05a0bcf280734 to your computer and use it in GitHub Desktop.
Remotion text typewriter effect
import {spring, useCurrentFrame, interpolate, Easing, useVideoConfig} from 'remotion';
/*
Pass params into component like this:
<TitleThree titleText={`But I watch
and learn from them.
I like the little they know,
which is so much.`} titleColor="white" backgroundColor="black" fontSize={60} fontFamily="Lora" />
*/
export const TitleThree: React.FC<{
titleText: string;
titleColor: string;
fontSize: number;
fontFamily: string;
backgroundColor: string;
textShadow: string;
}> = ({titleText, titleColor, fontSize, delay, fontFamily, backgroundColor, textShadow}) => {
const {fps} = useVideoConfig();
const frame = useCurrentFrame();
const lines = titleText.split("\n").map((lineWords) => {
const words = lineWords.split(' ').map((text) => ` ${text} `);
return {
lineWords: words.map((text) => {
return {
characters: text.split('').map((text) => ` ${text} `)
}
}),
}
})
const backgroundOpacity = interpolate(frame, [0, 30], [0, 1]);
// @TODO: add multiline text:
// https://stackoverflow.com/questions/35351706/how-to-render-a-multi-line-text-string-in-react
let counter = 0;
return (
<div>
{lines.map((words, l_i) => {
return (
<h1
style={{
display: 'block',
fontWeight: 'normal',
width: 'auto',
margin: '0 0 20px',
fontSize,
fontFamily,
textShadow,
opacity: backgroundOpacity
}}
>
<span style={{ padding: '5px', backgroundColor}}>
{ words.lineWords.map((word, i) => {
return (
<span style={{ padding: '5px 10px'}}>
{word.characters.map((letter, c_i) => {
counter++;
const halfSecond = 15;
const progress = spring({
frame: frame - halfSecond - counter * 1,
fps,
config: {
mass: 2.5,
damping: 1000,
},
});
const opacity = interpolate(progress, [0, 1], [0, 1], {
easing: Easing.bezier(0.45, 0, 0.55, 1),
extrapolateLeft: 'clamp',
extrapolateRight: 'clamp',
});
return (
<span
key={i}
style={{
color: titleColor,
marginLeft: 0,
marginRight: 0,
opacity,
display: 'inline-block',
}}
>
{letter}
</span>
);
})}
</span>
);
})}
</span>
</h1>
)
})};
</div>
);
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment