Skip to content

Instantly share code, notes, and snippets.

@ymatinfard
Created May 5, 2025 08:57
Show Gist options
  • Save ymatinfard/0f180405a63b79c345b98942abacf88f to your computer and use it in GitHub Desktop.
Save ymatinfard/0f180405a63b79c345b98942abacf88f to your computer and use it in GitHub Desktop.
Loading animation in compose
@Composable
fun CircleLoadingIndicator(
modifier: Modifier = Modifier,
size: Dp = 50.dp,
color: Color = MaterialTheme.colorScheme.primary,
spaceBetween: Dp = 8.dp,
travelDistance: Dp = 20.dp,
) {
val transition = rememberInfiniteTransition(label = "loading_circles")
val delays = listOf(0, 100, 200) //ms
val animatedOffsets = delays.map { delay ->
transition.animateFloat(
initialValue = 0f,
targetValue = 1f,
animationSpec = infiniteRepeatable(
animation = keyframes {
durationMillis = 1200
0.0f at 0 with LinearOutSlowInEasing
1.0f at 300 with LinearOutSlowInEasing
0.0f at 600 with LinearOutSlowInEasing
0.0f at 1200 with LinearOutSlowInEasing
},
repeatMode = RepeatMode.Restart,
initialStartOffset = StartOffset(delay)
),
label = "circle_animation"
)
}
Row(
modifier = modifier,
horizontalArrangement = Arrangement.spacedBy(spaceBetween)
) {
animatedOffsets.forEach { offset ->
Box(
modifier = Modifier
.size(size)
.graphicsLayer {
translationY = -offset.value * travelDistance.toPx()
}
.background(color = color, shape = CircleShape)
)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment