Animating brush Text coloring in Compose đď¸
After adding a gradient to your text in Compose, now itâs time to animate it!
This post builds up on text styling using the Brush
API and Compose animations! Make sure youâre familiar with these concepts. We covered all the integrations using the Brush
API on this blog post here.
Candy cane shimmer effect
We want to implement a candy cane effect for the gradient in our text. The colors in the gradient should move from the top left to the bottom right corner of the text continuously, as per our design:
We can use linearGradient
to create the gradient, which places the colors along given start
and end
coordinates.
Because of how linear gradient works, the coordinates define the area and angle at which the linear brush paints. For our example, if you define a region as described by the image below, the brush stroke is diagonally cropped, which is easy to see if the brush size is smaller than the drawing area:
So an idea to implement this animation is to animate start
and end
coordinates in a small section of the drawing area and then repeat the sequence.
We can define an infinite transition, and use animateFloat
to animate a value from 0f to at least twice your font size in pixels. Because we donât know the drawing area size in this case, we are using font size as an anchor point, which directly relates to the area of the drawn text.
We can use this animated offset next, make the gradient move in a specific area of the canvas, and then repeat this sequence in the rest of the available space. This is how the first step would look like without repetition:
We can create the linear gradient brush, configure the start
and end
coordinates of the drawing area using the animated offset, and apply it to the text. We start in the (0,0) coordinate and then move up until our defined offset.
To repeat the sequence and create the effect of continuity, we can use tileMode
mirror
. So the code looks like this:
Thatâs it! Youâve achieved the candy cane effect that works for any text size and density of your device.
You can create other types of effects (for example a faster transition or a thicker gradient) by tweaking offsetâs
targetValue
and the gradientâsoffset
parameters.
Back and forth shimmer effect
Next, we have a new animation, consisting of a gradient rocking back and forth.
In the previous example we used the currentFontSizePx
to estimate how big the area of the animation would be, and using an estimate was good enough to achieve the effect we wanted. But sometimes, we may want to know the exact size occupied by the text or drawing area. To access this size (which is also the brush size), we can create a custom brush, as we did in the Custom brushes section, in the previous post.
We can start thinking how to draw the first pass of the gradientâs movement, with coordinates that are a function of an animated offset
and the width and height of the drawing area.
Letâs define an infinite transition, animating a range from 0f to 1f. We can configure RepeatMode.Reverse
, so the gradient can be painted moving in one direction and then in the opposite direction.
Because of the gradient pattern, we can create a linear gradient brush using the LinearGradientShader
method. Same as before, from and to represent the coordinates where the brush will paint.
We can define widthOffset
and heightOffset
variables, that scale the width and height based on the animated offset.
And then we can use tileMode
mirror
to fill the drawing space with the inverse gradient allowing the effect of moving back and forth.
Finally, we set the new brush to Text
. The code might look something like this:
We are using the remember
function to allow recomposition whenever offset
changes. This is necessary because, due to an internal optimization in AndroidTextPaint
, if the brush or its direct parameters are not changing no recomposition will be scheduled. In this case, brush remains the same, and what changes is the LinearGradientShader
âs parameters.
And youâre done, youâve achieved the design above â¨.
Recap
Youâve learned how to use the animation APIs with the different Brush
APIs and some techniques to make your gradient colors come to life.
Give it a try in your app and let us know if you experience any issues by filing a bug on our issue tracker.
Happy Composing! đ
This post was written with the collaboration of Halil Ăzercan on the Jetpack Compose Text team. Thanks to Rebecca Franks and Florina Muntenescu on the DevRel team for their thorough reviews.