Thread
#compose
    Boris Kachscovsky

    Boris Kachscovsky

    1 year ago
    We’re trying to implement an indeterminate progress spinners whose animations are synchronized between screens. Is this possible in compose? Would it be possible to base it off some shared value (e.g. time)?
    Doris Liu

    Doris Liu

    1 year ago
    Do you have a mock for what that might look like?
    Boris Kachscovsky

    Boris Kachscovsky

    1 year ago
    Currently it works like this
    val rotation = remember { Animatable(initialValue = 0f) }
    
        LaunchedEffect(Unit) {
            rotation.animateTo(
                targetValue = 359f,
                animationSpec = infiniteRepeatable(IndeterminateProgressAnimationSpec)
            )
        }
    But it would be great if it could accept some offset
    val rotation = remember { Animatable(initialValue = 0f, offset = System.currentTimeMillis() % 359) }
    
        LaunchedEffect(Unit) {
            rotation.animateTo(
                targetValue = 359f,
                animationSpec = infiniteRepeatable(IndeterminateProgressAnimationSpec)
            )
        }
    If the offsets were synced like this, the animations would sync too! I can’t give it as the initial value because we still want it to animate from 0 - 359, so an offset would be ideal
    Doris Liu

    Doris Liu

    1 year ago
    offset
    is for the delay I assume? Consider sequencing the delay and animation in the LaunchedEffect:
    val rotation = remember { Animatable(initialValue = 0f) }
        LaunchedEffect(Unit) {
            delay(offset)
            rotation.animateTo(
                targetValue = 359f,
                animationSpec = infiniteRepeatable(IndeterminateProgressAnimationSpec)
            )
        }
    Boris Kachscovsky

    Boris Kachscovsky

    1 year ago
    Ah that makes sense 👍 But the idea is that the infinite repeatable animation wouldn’t delay, just have the animation offset by a certain amount of time. So if animation 1 shows on the screen it’ll start at let’s say 50. After 500 milliseconds the animation would be at (50 + 500) % 359 = 191. The second animation should then start at 191 given that they’re using the same underlying composable and the offset would be based on the current time. I wonder if there’s a way to do something similar with this API
    Doris Liu

    Doris Liu

    1 year ago
    ah, so the offset is offsetting the animation in the opposite direction than delay. 🙂
    The second animation should then start at 191 given that they’re using the same underlying composable and the offset would be based on the current time.
    What triggers the 2nd animation to start? It sounds like the stateless animation API (e.g. TargetBasedAnimation) would be best suited for this case. With TargetBasedAnimation, you can drive it with any arbitrary rule that might apply on playtime.
    Boris Kachscovsky

    Boris Kachscovsky

    1 year ago
    What triggers the 2nd animation to start?
    It’s the loading spinner on the following screen, but i’ll take a look at
    TargetBasedAnimation
    ! Thanks for the help 🙏
    Doris Liu

    Doris Liu

    1 year ago
    Maybe the spinner animation could be hoisted to the common parent, if you are going for a continuous animation when switching the screen. Each screen would be receiving the necessary animated values for drawing the spinner. That's another way to go about this. 🙂