Created
March 25, 2021 11:25
-
-
Save willhalling/e76edc84003b68d860f05a0bcf280734 to your computer and use it in GitHub Desktop.
Remotion text typewriter effect
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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