Is there any way to trigger an “animation” with co...
# compose
d
Is there any way to trigger an “animation” with compose (kmp) that is completely generic and just updates a float value (MutableState<Float>?) going from 0 and 1 (0 at start of “animation, 1 at the end) on an interval that syncs with the device framerate. Using that single tween value, I would like to apply it to several views and view properties of the layout. So far from what I am reading about compose animations they are all for very specific use cases and not really able to handle more flexible behaviors like this. With android I could use the Animation class, and with Flutter I was able to accomplish this with a Timer. Ideally it would be something that is aware of the device graphics and what interval is efficient to update the layout on.
r
Use animateFloatAsState() or check out the section "Low-level animation APIs" in Christian's link
d
I guess something like this is what I need: val value by animateFloatAsState( targetValue = 1f, animationSpec = tween( durationMillis = 300, delayMillis = 50, easing = LinearOutSlowInEasing ), label = “tween delay” ) But I have no idea how to trigger it to start or stop, there’s no function to do so. The github file where that’s in has it wrapped in a Composable function, but I’m not sure how that is supposed to be used either since there’s no example.
Managed to figure it out after piecing things together from different parts of the docs, In case someone is searching for transition animations in the future and comes across this, here is an example for exploding a Card to fill its parent on click:
Copy code
val scope = rememberCoroutineScope()
val animation = remember { Animatable(0f) }

Card(
  backgroundColor = AppColors.button(),
  modifier = Modifier
    .fillMaxWidth()
    .padding(animation.value.interval(16.dp, 0.dp))
    .height(animation.value.interval(height, with(LocalDensity.current) { containerSize.value.height.toDp() }))
    .clickable() {
      scope.launch {
        animation.animateTo(1f, animationSpec = tween(durationMillis = 200))
      }
    }
)

fun Float.interval(start: Dp, end: Dp) = ((end - start) * this) + start
r
A “more Compose” is shown in the docs:
var enabled by remember { mutableStateOf(true) } val alpha: Float by animateFloatAsState(if (enabled) 1f else 0.5f, label = "alpha")
And then for instance you’d do padding(16.dp * alpha)
Also instead of using your own interval function you can use the built in lerp()
d
ah I actually started with the enabled by remember {} example but for some reason it didn’t click to use that to generate the 0->1 tween from animateFloatAsState. My next step is to try and do something similar with the pressed state where the card elevates and expands a little bit. So maybe there is an elegant way to accomplish that with States.