
Today, we will learn how to draw an arc in Jetpack Compose using the drawArc method of Canvas.
Prerequisites:
First, let’s create a Canvas of size 300.dp.
@Composable
fun MyUI() {
Canvas(
modifier = Modifier
.size(size = 300.dp)
.border(color = Color.Magenta, width = 2.dp)
) {
}
}
Output:

Here is a simple arc:
@Composable
fun MyUI() {
Canvas(
modifier = Modifier
.size(size = 300.dp)
.border(color = Color.Magenta, width = 2.dp)
) {
drawArc(
color = Color.Cyan,
startAngle = 0f,
sweepAngle = 90f,
useCenter = true
)
}
}
Output:

The drawArc function takes multiple parameters:
color – color of the arc.
startAngle – It is the starting angle of the arc. 0f represents the 3 o’clock.
sweepAngle – It is the size of the arc. It is drawn relative to startAngle.
Note: Angles with positive values travel in the clockwise direction. Angles with negative values go in the anti-clockwise direction.
In the above output:

Let’s play with the angles.
Example 1:
startAngle = 90f
sweepAngle = 180f
@Composable
fun MyUI() {
Canvas(
modifier = Modifier
.size(size = 300.dp)
.border(color = Color.Magenta, width = 2.dp)
) {
drawArc(
color = Color.Cyan,
startAngle = 90f,
sweepAngle = 180f,
useCenter = true
)
}
}
Output:

Example 2:
startAngle = -90f
sweepAngle = 180f
@Composable
fun MyUI() {
Canvas(
modifier = Modifier
.size(size = 300.dp)
.border(color = Color.Magenta, width = 2.dp)
) {
drawArc(
color = Color.Cyan,
startAngle = -90f,
sweepAngle = 180f,
useCenter = true
)
}
}
Output:

Example 3:
startAngle = -45f
sweepAngle = -90f
@Composable
fun MyUI() {
Canvas(
modifier = Modifier
.size(size = 300.dp)
.border(color = Color.Magenta, width = 2.dp)
) {
drawArc(
color = Color.Cyan,
startAngle = -45f,
sweepAngle = -90f,
useCenter = true
)
}
}
Output:

Example 4:
startAngle = 45f
sweepAngle = -90f
@Composable
fun MyUI() {
Canvas(
modifier = Modifier
.size(size = 300.dp)
.border(color = Color.Magenta, width = 2.dp)
) {
drawArc(
color = Color.Cyan,
startAngle = 45f,
sweepAngle = -90f,
useCenter = true
)
}
}
Output:

The useCenter parameter indicates if the arc should be close to the center. If we set it to false in the above code, it becomes:
@Composable
fun MyUI() {
Canvas(
modifier = Modifier
.size(size = 300.dp)
.border(color = Color.Magenta, width = 2.dp)
) {
drawArc(
color = Color.Cyan,
startAngle = 45f,
sweepAngle = -90f,
useCenter = false
)
}
}
Output:

In Canvas, everything is drawn relative to (0,0) which is the top left corner. drawArc function provides topLeft parameter to change this relative point.
Example:
With default topLeft:
@Composable
fun MyUI() {
Canvas(
modifier = Modifier
.size(size = 300.dp)
.border(color = Color.Magenta, width = 2.dp)
) {
drawArc(
color = Color.Cyan,
startAngle = 180f,
sweepAngle = 90f,
useCenter = true
)
}
}
Output:

Let’s change it to the center of the canvas:
@Composable
fun MyUI() {
Canvas(
modifier = Modifier
.size(size = 300.dp)
.border(color = Color.Magenta, width = 2.dp)
) {
drawArc(
color = Color.Cyan,
startAngle = 180f,
sweepAngle = 90f,
useCenter = true,
topLeft = Offset(x = 150.dp.toPx(), y = 150.dp.toPx())
)
}
}
Output:

We can change the size of the arc using the size parameter:
@Composable
fun MyUI() {
Canvas(
modifier = Modifier
.size(size = 300.dp)
.border(color = Color.Magenta, width = 2.dp)
) {
drawArc(
color = Color.Cyan,
startAngle = 180f,
sweepAngle = 90f,
useCenter = true,
size = Size(width = 100.dp.toPx(), height = 100.dp.toPx())
)
}
}
Output:

There is another variation of the drawArc method that accepts brush instead of color. We can draw gradient backgrounds using it.
@Composable
fun MyUI() {
Canvas(
modifier = Modifier
.size(size = 300.dp)
.border(color = Color.Magenta, width = 2.dp)
) {
drawArc(
brush = Brush.horizontalGradient(colors = listOf(Color.Yellow, Color.Green)),
startAngle = 180f,
sweepAngle = 90f,
useCenter = true
)
}
}
Output:

drawArc accepts a parameter called style. We can create a stroked arc using it.
@Composable
fun MyUI() {
Canvas(
modifier = Modifier
.size(size = 300.dp)
.border(color = Color.Magenta, width = 2.dp)
) {
drawArc(
brush = Brush.horizontalGradient(colors = listOf(Color.Yellow, Color.Green)),
startAngle = 180f,
sweepAngle = 90f,
useCenter = true,
topLeft = Offset(x = 20.dp.toPx(), y = 20.dp.toPx()),
style = Stroke(width = 8.dp.toPx())
)
}
}
Output:

This is all about Canvas drawArc method in Jetpack Compose. I hope you have learned something new. If you have any doubts, comment below.
How to detect click on each Arch
You can use Modifier.pointerInput(). https://stackoverflow.com/a/68401669/14309684
Hi, thanks for the great article! Now I finally understood how to use arcs, and listen to clicks. Is there any kind of animation for arcs? I would like to draw a chart but to “paint” the sweepAngle with an animation, or make a chronometer using the style stroke to draw a circle and decrease it in a parameterized time.
Yes. You can use any animation API. Look at this example: https://semicolonspace.com/circular-progressbar-android-compose/