https://kotlinlang.org logo
Title
o

orangy

06/10/2022, 8:33 PM
Folks, is there any easy way to animate the
Brush
object? At least for
SolidColor
?
c

Chris Sinco [G]

06/10/2022, 8:45 PM
There is animateColorAsState which you can pass to Brush color parameter
o

orangy

06/10/2022, 11:21 PM
Maybe I’m missing something obvious, but could you give an example? Eg Box with a background with solid color brush, animated to another color?
I mean, given some external state of type Brush, which is animated if solid color, and not animated in all other cases
c

Colton Idle

06/10/2022, 11:49 PM
Have you seen this by chance? They change the solid color of a square too 😁

https://youtu.be/7yY2OocGiQU

o

orangy

06/10/2022, 11:52 PM
@Colton Idle Will check tomorrow, thanks :) though I somehow can guess they drive it from color. I need to drive it from brush and I can't my head over it
c

Chris Sinco [G]

06/11/2022, 3:12 AM
This is a simple example, animating a color passed into
SolidColor
, which returns a
Brush
@Preview
@Composable
fun AnimateColor() {
    var toggle by remember { mutableStateOf(false) }
    val animatedColor by animateColorAsState(
        targetValue = if (toggle) Color.Yellow else Color.Magenta,
        animationSpec = tween(2000)
    )

    MaterialTheme {
        Surface {
            Box(
                Modifier
                    .clickable { toggle = !toggle }
                    .aspectRatio(1f)
                    .background(SolidColor(animatedColor))
                    .padding(20.dp),
                contentAlignment = Alignment.Center
            ) {
                Text(
                    "Box with changing colors",
                    textAlign = TextAlign.Center,
                    style = MaterialTheme.typography.h3
                )
            }
        }
    }
}
animated if solid color, and not animated in all other cases
Do you have a visual example of what you are trying to do? Wondering if animating the values passed into Brush would suffice.
b

Berkeli Alashov

06/11/2022, 4:26 AM
Animating Brush directly could be cool since animating between SolidColor & Brush.linear/radial/sweep gradients would be also possible
o

orangy

06/11/2022, 9:58 AM
@Chris Sinco [G] yes, I know how to animate a color, but I somehow cannot find the right combination of a little bit more complex case. I have a simplistic theming system, where components like Button have associated set of ButtonAppearance instances depending on state (hover, pushed), and variation (primary, secondary, etc). Now when Button goes from one state to another I need to transition from one appearance to another. Now I have something like this (simplified for less properties):
@Composable
fun updateButtonAppearanceTransition(appearance: ButtonAppearance): AppearanceTransitionState {
    val transition = updateTransition(appearance)
    val background = mutableStateOf(appearance.background) // TODO: animate background color
    val shapeStroke = transition.animateShapeStroke(label = "AnimateShapeStroke") { it.shapeStroke }
    val haloStroke = transition.animateShapeStroke(label = "AnimateHaloStroke") { it.haloStroke }
    return AppearanceTransitionState(background, shapeStroke, haloStroke)
}
When it comes to built-in stuff, like colors it’s simple. But I can’t find how to deal with the Brush here
Well, solved it with defining specific SolidColor animation
@Composable
inline fun <S> Transition<S>.animateSolidColor(
    label: String = "SolidBrushAnimation",
    targetValueByState: @Composable() (state: S) -> SolidColor?
): State<SolidColor> {
    val color by animateColor(label = "$label.color", transitionSpec = { defaultAnimationSpec() }) {
        targetValueByState(it)?.value ?: Color.Unspecified
    }
    return remember { derivedStateOf { SolidColor(color) } }
}
And then using it in the composite transition