'Jetpack compose how to animate multiple values

I have couple of Path elements in my Canvas and would like to do some complex animations with every one of the Path lines. I am not sure how to approach this. Let's take a look at a simple path.

val line1Path = Path()
line1Path.moveTo(maxTopLeftX, 0f) // top left
line1Path.lineTo(maxBottomLeftX, size.height) // bottom left
line1Path.lineTo(maxBottomLeftX+lineWidth, size.height) // bottom right
line1Path.lineTo(maxTopLeftX+lineWidth, 0f) // top right

Currently I am using updateTransition with animateFloat but this way if I have to make animations for every one of the points only for this Path I would have to have 8 variables just for this 1 object.

Also I would like to do more than just a single value to value animation so something like animateFloatAsState where there are keyframes and I can order my animations seems better for the job, but the issue again is I have to create 8 variables that hold every one of the line positions to just animate this object.

What will be the best way to approach this?



Solution 1:[1]

I have been having same issue for days. In my case I use a data class for input data, so I just added an Animatable variable with default initialization to my data class. Then launch it from coroutine scope forEaching every item.

Not sure if this is the correct way to approach such issue, but hope it helps!

Solution 2:[2]

Here you have an example of multiple values animated at the same time. A transition is used to orchestrate the value animations.

val interactionSource = remember { MutableInteractionSource() }
    val isPressed by interactionSource.collectIsPressedAsState()

    val transition = updateTransition(targetState = isPressed, label = "")

    val angle by transition.animateFloat(transitionSpec = {
        tween(durationMillis = 180, easing = FastOutSlowInEasing)
    }, label = ""){
        when(it){
            true -> 90f
            false -> 0f
        }
    }

    val x by transition.animateDp(transitionSpec = {
        tween(durationMillis = 180, easing = FastOutSlowInEasing)
    }, label = ""){
        when(it){
            true -> 85.dp
            false -> 0.dp
        }
    }


    Column(modifier = Modifier.fillMaxSize().background(Color(0xFFF0F8FF))
            .padding(80.dp).wrapContentSize(align = Alignment.BottomCenter),
        verticalArrangement = Arrangement.spacedBy(16.dp),
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        // THIS IS THE ANIMATED BOX
        Box(Modifier.rotate(angle).offset(x = x)
            .background(Color.Red)
            .width(20.dp)
            .height(150.dp)
        )

        Box(modifier = Modifier.clickable(interactionSource = interactionSource, indication = null) {}
            .hoverable(interactionSource)
            .focusable(interactionSource = interactionSource)
            .size(100.dp).background(Color.Blue),
        )
    }

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 immortalape
Solution 2 Raymond Arteaga