android-jetpack-composejetpack-compose-animationandroid-jetpack-compose-animation

Infinite color animation sequentially in Jetpack Compose


I've just learned how to animate a color from an initial value to a target value indefinitely. Now I want that animation to go through more colors.

This is what I've got so far:

@Preview(heightDp = 30, widthDp = 90)
@Composable
fun BlinkingPreview() {
    val infiniteTransition = rememberInfiniteTransition()
    val ghosting = infiniteTransition.animateColor(Color.Green, Color.Black, animationSpec = infiniteRepeatable(tween(8000))).value
    val overshooting = infiniteTransition.animateColor(Color.Black, Color.White, animationSpec = infiniteRepeatable(tween(1000))).value
    val waning = infiniteTransition.animateColor(Color.White, Color.Green, animationSpec = infiniteRepeatable(tween(1000))).value

    Row {
        Spacer(Modifier.fillMaxHeight().weight(1f).background(ghosting))
        Spacer(Modifier.fillMaxHeight().weight(1f).background(overshooting))
        Spacer(Modifier.fillMaxHeight().weight(1f).background(waning))
    }
}

This gives this output:

3 squares in a row, each animating its color independently

What I really want is a single Spacer cycling between all those color ramps, like this (I've glued the previous output manually in GIMP):

1 square animating its color


Solution

  • I did it with animateColor from Green to Green and keyframes to set intermediate goals:

    @Preview(heightDp = 30, widthDp = 90)
    @Composable
    fun BlinkingPreview() {
        val infiniteTransition = rememberInfiniteTransition()
        val blinking = infiniteTransition.animateColor(
            Color.Green, Color.Green,
            animationSpec = infiniteRepeatable(
                animation = keyframes {
                    durationMillis = 10000
                    Color.Black at 8000
                    Color.White at 9000
                }
            )
        ).value
    
        Row {
            Spacer(Modifier.fillMaxHeight().weight(1f).background(blinking))
        }
    }