How to Draw an Arc in Jetpack Compose Canvas?

Jetpack Compose draw arc

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:

Canvas dp

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:

draw arc

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:

start and sweep angles

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:

startAngle 90f sweepAngle 180f

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:

startAngle negative

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:

draw arc negative values

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:

angles

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:

useCenter

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:

top left canvas

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:

topLeft center

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:

draw arc size

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:

gradient arc

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:

Jetpack compose arc stroke

This is all about Canvas drawArc method in Jetpack Compose. I hope you have learned something new. If you have any doubts, comment below.

Leave a Comment