Welcome π
In this article, weβll build an amazing Rainbow Loader Animation in Jetpack Compose in less than 5 minutes β³
Excited? π€© Letβs dive in π
Defining the Main Function
First, letβs define the RainbowLoader
composable function:
@Composable
fun RainbowLoader(
modifier: Modifier = Modifier,
arcSpacing: Dp = 3.dp,
initialRadius: Dp = 5.dp,
strokeWidth: Dp = 4.dp,
strokeCap: StrokeCap = StrokeCap.Butt,
arcColors: List<Color> = listOf(Color.Red, Color.Yellow, Color.Green, Color.Cyan, Color.Blue)
)
Parameters
β€οΈ modifier
π Modifier to apply to the loader.
𧑠arcSpacing
π The spacing between each arc.
π initialRadius
π The radius of the innermost arc.
π strokeWidth
π The thickness of each arc.
π strokeCap
π The style of the arc ends.
π arcColors
π The colors of the arcs. Each color in the list results in an arc in the loader, starting from the center.
Drawing Arcs
Now, to draw a single arc, we define the RainbowArc
composable function:
@Composable
fun RainbowArc(
color: Color,
duration: Int,
delay: Int,
radius: Dp,
strokeWidth: Dp,
strokeCap: StrokeCap
) {
// Further implementation...
}
Defining the Animation
Inside the function, we define an infinite rotation animation:
// Create an infinite transition for rotating the arc
val infiniteTransition = rememberInfiniteTransition("InfiniteRainbowArcTransition")
// Animate the rotation from 0 to 360 degrees
val rotation by infiniteTransition.animateFloat(
initialValue = 0f,
targetValue = 360f,
animationSpec = infiniteRepeatable(
animation = keyframes {
// Set the total duration minus delay
durationMillis = duration - delay
delayMillis = delay
// Define the keyframes for the rotation animation
0f atFraction 0f
400f atFraction 0.5f using FastOutLinearInEasing
360f atFraction 1f using LinearOutSlowInEasing
}
),
label = "RainbowArcRotation"
)
Drawing the Arc
We use the Canvas
composable to draw the arc and apply the rotation
animation:
// Draw the rotating arc
Canvas(
modifier = Modifier
.size(radius * 2) // Set the size of the canvas based on the arc's radius
.rotate(rotation) // Apply the rotation animation
) {
drawArc(
color = color,
startAngle = -180f, // Start drawing the arc from the left
sweepAngle = 180f, // Draw a half-circle arc
useCenter = false,
style = Stroke(width = strokeWidth.toPx(), cap = strokeCap)
)
}
Composing the Loader
Finally, in this section, we will compose the RainbowLoader
using the RainbowArc
function:
@Composable
fun RainbowLoader(
// Parameters...
) {
// Calculate the total duration of the animation based on the number of arcs
val duration = remember(arcColors) { 1000 + (arcColors.size * 100) }
// Create a Box to contain and center the arcs
Box(
modifier = modifier,
contentAlignment = Alignment.Center
) {
// Create a RainbowArc for each color in the list
arcColors.forEachIndexed { index, color ->
RainbowArc(
color = color,
duration = duration,
// Delay the start of each arc's animation based on its position
delay = (index + 1) * 100,
// Determine the radius for each arc based on its position
radius = initialRadius + (arcSpacing + strokeWidth) * index,
strokeWidth = strokeWidth,
strokeCap = strokeCap
)
}
}
}
Congratulations π₯³! Weβve successfully built it π. You can find the full code on GitHub Gist π§βπ». Letβs explore the usage π
Practical Usage πββοΈ
Letβs take a look at what weβve built π
// Default usage
RainbowLoader()
// Custom colors and stroke cap
RainbowLoader(
arcColors = listOf(
Color(0xFFFF0000), // Red
Color(0xFFFFA500), // Orange
Color(0xFFFFFF00), // Yellow
Color(0xFF008000), // Green
Color(0xFF0000FF), // Blue
Color(0xFF4B0082), // Indigo
Color(0xFFEE82EE) // Violet
),
strokeCap = StrokeCap.Round
)
Output π
Thank you for reading this article! β€οΈ If you found it enjoyable and valuable, show your appreciation by clapping π and following Kappdev for more exciting articles π