I have an animation it's a green rectangle that grows in length inside a white outlined rectangle. It was working fine before I adjusted the layout. Now the green rectangle simply doesn't grow. If I change animatedWidth
to 10f the rectangle appears. But it is supposed to start from zero and grow in length.
The animation is called from a button which turns isVisible
to true which shows the composable. This part works, because I can see the white rectangle.
Button(
onClick = { isVisible = !isVisible }
) {
Text(text = "Play animation")
}
if (isVisible) {
Box(modifier = Modifier.fillMaxSize()) {
OutlinedLinearProgressBar()
}
}
This is the composable that contains my animation. The green rectangle is the one at the end and it is the size width variable that is supposed to change.
@Composable
fun OutlinedLinearProgressBar() {
var animationPlayed by remember { mutableStateOf(false) }
val animatedWidth = remember { Animatable(0f) }
var canvasSize by remember { mutableStateOf(Size.Zero) }
LaunchedEffect(Unit) {
val targetWidth = canvasSize.width / 2.18f
val duration = 1000
with(animatedWidth) {
launch {
animateTo(
targetValue = targetWidth,
animationSpec = tween(durationMillis = duration),
)
}
}
}
LaunchedEffect(key1 = true) { animationPlayed = true }
Box(modifier = Modifier.fillMaxSize()) {
Canvas(modifier = Modifier.fillMaxSize()) {
canvasSize = size
drawRect(color = Color.Black, size = size)
val centerY = center.y
drawRect(
style = Stroke(width = 10f),
color = Color.White,
topLeft = Offset(x = size.width / 4f, y = centerY - (size.height / 10f) / 2f),
size = Size(
width = size.width / 2f,
height = size.height / 10f,
),
)
drawRect(
color = Color.Green,
style = Fill,
topLeft = Offset(x = size.width / 3.7f, y = centerY - (size.height / 10f) / 2.5f),
size = Size(
width = animatedWidth.value,
height = size.height / 12.5f,
),
)
}
}
}
The code you provided works for me, but there may be some problems with the key of your LaunchedEffect when unexpected recompositions occur, like changes in size. That depends on how this is used in your actual code.
You do not even need the LaunchedEffect when you replace animatedWidth
with
val animatedWidth by animateFloatAsState(
targetValue = canvasSize.width / 2.18f,
animationSpec = tween(1000),
label = "animatedWidth",
)
Since this accesses canvasSize
directly it needs to be moved one line down, after the declaration of canvasSize
.