Skip to content

Instantly share code, notes, and snippets.

@riggaroo
Created May 8, 2024 16:32
Show Gist options
  • Save riggaroo/668868c954c4a1e9b29fa57a762e63b5 to your computer and use it in GitHub Desktop.
Save riggaroo/668868c954c4a1e9b29fa57a762e63b5 to your computer and use it in GitHub Desktop.
Animate text character by character as you type.
@Preview
@Composable
private fun AnimatedText() {
val text = "This text animates as though it is being typed \uD83E\uDDDE\u200D♀\uFE0F \uD83D\uDD10 \uD83D\uDC69\u200D❤\uFE0F\u200D\uD83D\uDC68 \uD83D\uDC74\uD83C\uDFFD"
// Use BreakIterator as it correctly iterates over characters regardless of how they are
// stored, for example, some emojis are made up of multiple characters.
// You don't want to break up an emoji as it animates, so using BreakIterator will ensure
// this is correctly handled!
val breakIterator = remember(text) { BreakIterator.getCharacterInstance() }
// Define how many milliseconds between each character should pause for. This will create the
// illusion of an animation, as we delay the job after each character is iterated on.
val typingDelayInMs = 50L
var substringText by remember {
mutableStateOf("")
}
LaunchedEffect(text) {
// Initial start delay of the typing animation
delay(1000)
breakIterator.text = StringCharacterIterator(text)
var nextIndex = breakIterator.next()
// Iterate over the string, by index boundary
while (nextIndex != BreakIterator.DONE) {
substringText = text.subSequence(0, nextIndex).toString()
// Go to the next logical character boundary
nextIndex = breakIterator.next()
delay(typingDelayInMs)
}
}
Text(substringText)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment