Home > other >  Multiple objects animated at once in Compose
Multiple objects animated at once in Compose

Time:06-16

I'm trying to animate the movement of multiple circles on canvas at once. So far I managed to animate one, that moves to a random spot on canvas on every user click using Animatable. Now I want to add another 2 circles that do the same but move to another, also randomly chosen spot. Is there a way to achieve it easily without launching multiple coroutines?

My code so far:

@Composable
fun CanvasScreen(){

    val animationScope = rememberCoroutineScope()
    val animationX = remember{Animatable(0f)}
    val animationY = remember{Animatable(0f)}
    val randomColor = Color((Math.random() * 16777215).toInt() or (0xFF shl 24))

    Canvas(
        modifier = Modifier
            .fillMaxSize()
            .clickable {
                animationScope.launch {
                    launch {
                        animationX.animateTo(
                            targetValue = (90..1000)
                                .random()
                                .toFloat()
                        )
                    }
                    launch {
                        animationY.animateTo(
                            targetValue = (90..1500)
                                .random()
                                .toFloat()
                        )
                    }
                }
            }
    ){
        drawCircle(
            color = randomColor,
            radius = 90f,
            center = Offset(animationX.value, animationY.value),
        )
    }
}

CodePudding user response:

it took me a while but i finally got it done, there may be a simpler way of course but this can work.

@SuppressLint("UnrememberedAnimatable")
@Composable
fun CanvasScreen(){

    val circleNumber = 20

    val animationScope = rememberCoroutineScope()
    val randomColorList = remember { arrayListOf<Color>()}
    val animationXList = remember { arrayListOf<Animatable<Float, AnimationVector1D>>() }
    val animationYList = remember { arrayListOf<Animatable<Float, AnimationVector1D>>() }

    for(i in 0 until circleNumber){
        randomColorList.add(Color((Math.random() * 16777215).toInt() or (0xFF shl 24)))
        animationXList.add(Animatable(0f))
        animationYList.add(Animatable(0f))
    }

    for(i in 0 until circleNumber){
        Canvas(
            modifier = Modifier
                .fillMaxSize()
                .clickable {
                    animationXList.forEach {
                        animationScope.launch {
                            launch {
                                it.animateTo(
                                    targetValue = (90..1000)
                                        .random()
                                        .toFloat()
                                )
                            }
                        }
                    }
                    animationYList.forEach {
                        animationScope.launch {
                            launch {
                                it.animateTo(
                                    targetValue = (90..1500)
                                        .random()
                                        .toFloat()
                                )
                            }
                        }
                    }
                }
        ){
            drawCircle(
                color = randomColorList[i],
                radius = 90f,
                center = Offset(animationXList[i].value, animationYList[i].value),
            )
        }
    }
}
  • Related