When there is one circle, I want to give different...
# compose
l
When there is one circle, I want to give different animations for each time section. For example, I want to increase the circle size in 0-3 seconds, move the x-coordinate to the right in 3-6 seconds, and reduce the size again in 6-9 seconds. How to do it?
a
Since animating functions are all suspend functions, you can simply do something like this.
Copy code
val circleSize = remember { Animatable(initialValue = 100f) }
val xCoordinate = remember { Animatable(initialValue = 100f) }
val scope = rememberCoroutineScope()
Button(
    onClick = {
        scope.launch {
            circleSize.animateTo(
                targetValue = 200f,
                animationSpec = tween(durationMillis = 3000)
            )
            xCoordinate.animateTo(
                targetValue = 200f,
                animationSpec = tween(durationMillis = 3000)
            )
            circleSize.animateTo(
                targetValue = 100f,
                animationSpec = tween(durationMillis = 3000)
            )
        }
    }
) {
    Text(text = "Animate")
}
👆 1
l
@Albert Chang I love you
@Albert Chang It’s not working…
a
How is it not working?
🙌 1
l
never mind. I forgot modifer…
🆗 1
z
You couple maybe also use a keyframes spec?
l
@Albert Chang How can i repeat this animation???
Copy code
val circleSize = remember { Animatable(initialValue = 0f) }
    val xCoordinate = remember { Animatable(initialValue = -25f) }

    suspend fun startAnimation() {
        circleSize.animateTo(
            targetValue = 10f,
            animationSpec = tween(durationMillis = 700),
        )
        xCoordinate.animateTo(
            targetValue = 25f,
            animationSpec = tween(durationMillis = 2100, easing = LinearEasing)
        )
        circleSize.animateTo(
            targetValue = 0f,
            animationSpec = tween(durationMillis = 700, easing = LinearEasing)
        )
        xCoordinate.snapTo(-25f)
    }

    LaunchedEffect(key1 = true) {
        delay(initialDelay)
        while (true) {
            startAnimation()
        }
    }

    Box(
        modifier = modifier
            .offset(x = xCoordinate.value.dp)
            .clip(CircleShape)
            .background(color)
            .size(circleSize.value.dp),
    )
Would it be okay to write code like this?
a
It’s OK!
l
@Albert Chang I did that, but there is a problem that the delay time changes little by little as it repeats.
full code
Copy code
@Composable
fun LoadingB(modifier: Modifier = Modifier) {
    Box(modifier = modifier) {
        Circle(color = Color.Green, initialDelay = 0L)
        Circle(color = Color.Red, initialDelay = 700L)
        Circle(color = Color.Cyan, initialDelay = 1400L)
        Circle(color = Color.Magenta, initialDelay = 2100L)
    }
}

@Composable
private fun Circle(modifier: Modifier = Modifier, color: Color, initialDelay: Long) {
    val circleSize = remember { Animatable(initialValue = 0f) }
    val xCoordinate = remember { Animatable(initialValue = -25f) }

    suspend fun startAnimation() {
        circleSize.animateTo(
            targetValue = 10f,
            animationSpec = tween(durationMillis = 700, easing = LinearEasing),
        )
        xCoordinate.animateTo(
            targetValue = 25f,
            animationSpec = tween(durationMillis = 1000, easing = LinearEasing)
        )
        circleSize.animateTo(
            targetValue = 0f,
            animationSpec = tween(durationMillis = 700, easing = LinearEasing)
        )
        xCoordinate.snapTo(-25f)
    }

    LaunchedEffect(key1 = true) {
        delay(initialDelay)
        while (true) {
            startAnimation()
        }
    }

    Box(
        modifier = modifier
            .offset(x = xCoordinate.value.dp)
            .clip(CircleShape)
            .background(color)
            .size(circleSize.value.dp),
    )
}
a
I don't exactly know what you want to achieve but I think it's a timing issue. If you want the 4 circles to be started sequentially with the same interval, you should use a interval of 600 instead of 700 since the total time of your animation is 2400.
😆 1