Thread
#compose
    g

    Guy Bieber

    1 year ago
    The example of rotation in the jetpack compose playground seems a bit messy. Is there a simpler method to rotate a @Composable?
    v

    Vinay Gaba

    1 year ago
    what was it using in the example?
    g

    Guy Bieber

    1 year ago
    @Composable
    fun RepeatedRotationDemo() {
        val state = remember { mutableStateOf(RotationStates.Original) }
        Column(
            Modifier.fillMaxSize()
                .wrapContentSize(Alignment.Center),
            verticalArrangement = Arrangement.SpaceEvenly
        ) {
            val textStyle = TextStyle(fontSize = 18.sp)
            Text(
                modifier = Modifier.tapGestureFilter(onTap = { state.value = RotationStates.Rotated }),
                text = "Rotate 10 times",
                style = textStyle
            )
            Text(
                modifier = Modifier.tapGestureFilter(onTap = { state.value = RotationStates.Original }),
                text = "Reset",
                style = textStyle
            )
            val transitionState = transition(
                definition = definition,
                toState = state.value
            )
            Canvas(Modifier.preferredSize(100.dp)) {
                rotate(transitionState[rotation], 0.0f, 0.0f) {
                    drawRect(Color(0xFF00FF00))
                }
            }
        }
    }
    
    private enum class RotationStates {
        Original,
        Rotated
    }
    
    private val rotation = FloatPropKey()
    
    private val definition = transitionDefinition<RotationStates> {
        state(RotationStates.Original) {
            this[rotation] = 0f
        }
        state(RotationStates.Rotated) {
            this[rotation] = 360f
        }
        transition(RotationStates.Original to RotationStates.Rotated) {
            rotation using repeatable(
                iterations = 10,
                animation = tween(
                    easing = LinearEasing,
                    durationMillis = 1000
                )
            )
        }
        transition(RotationStates.Rotated to RotationStates.Original) {
            rotation using tween(
                durationMillis = 300
            )
        }
    }
    It would be lovely to have something like this: Rotate ( duration : Long, step : Float) { Image () … }
    v

    Vinay Gaba

    1 year ago
    oh you can totally just use the logic from your first message and create a composable that makes the API look exactly like your second message 😄
    g

    Guy Bieber

    1 year ago
    When I tried it the rotate could not take a @Composable
    @Composable
    fun Rotate ( durationMillis : Int, rotations : Int, children: @Composable() () -> kotlin.Unit) {
        val state = remember { mutableStateOf(RotationStates.Original) }
        val rotation = FloatPropKey()
        val definition = transitionDefinition<RotationStates> {
            state(RotationStates.Original) {
                this[rotation] = 0f
            }
            state(RotationStates.Rotated) {
                this[rotation] = 360f
            }
            transition(RotationStates.Original to RotationStates.Rotated) {
                rotation using repeatable(
                    iterations = rotations,
                    animation = tween(
                        easing = LinearEasing,
                        durationMillis = durationMillis
                    )
                )
            }
            transition(RotationStates.Rotated to RotationStates.Original) {
                rotation using tween(
                    durationMillis = durationMillis
                )
            }
        }
        val transitionState = transition(
            definition = definition,
            toState = state.value
        )
        Canvas(Modifier.preferredSize(100.dp)) {
            rotate(transitionState[rotation], 0.0f, 0.0f) {
                children()
            }
        }
    }
    @Composable invocations can only happen from the context of a @Composable function
    Is there a version of rotate that is composable?
    it really should be a modifier like animateContentSize.
    grrrr
    v

    Vinay Gaba

    1 year ago
    replace the
    Canvas
    with a
    Box
    and you can then use this
    Modifier.drawLayer(rotationZ = transitionState[rotation])
    g

    Guy Bieber

    1 year ago
    Hmmm. Tried that it compiles and runs, but no rotation:
    private enum class RotationStates {
            Original,
            Rotated
        }
        
        @Composable
        fun Rotate ( durationMillis : Int, rotations : Int, children: @Composable() () -> kotlin.Unit) {
            val state = remember { mutableStateOf(RotationStates.Original) }
            val rotation = FloatPropKey()
            val definition = transitionDefinition<RotationStates> {
                state(RotationStates.Original) {
                    this[rotation] = 0f
                }
                state(RotationStates.Rotated) {
                    this[rotation] = 360f
                }
                transition(RotationStates.Original to RotationStates.Rotated) {
                    rotation using repeatable(
                        iterations = rotations,
                        animation = tween(
                            easing = LinearEasing,
                            durationMillis = durationMillis
                        )
                    )
                }
                transition(RotationStates.Rotated to RotationStates.Original) {
                    rotation using tween(
                        durationMillis = durationMillis
                    )
                }
            }
            if (state.value == RotationStates.Original) {
                state.value = RotationStates.Rotated
            } else {
                state.value = RotationStates.Original
            }
            val transitionState = transition(
                definition = definition,
                toState = state.value
            )
            Box (
                Modifier.drawLayer(rotationZ = transitionState[rotation],)
            ) {
                children()
            }
        }
    v

    Vinay Gaba

    1 year ago
    use this as a base for your rotation logic and replace the canvas in that example with
    Box(
            modifier = Modifier.fillMaxSize()
                .drawLayer(rotationZ = state[rotation]),
            gravity = ContentGravity.Center,
        ) {
            children()
        }

    https://github.com/vinaygaba/Learn-Jetpack-Compose-By-Example/raw/master/screenshots/animation_rotation.gif