How to Draw an Oval Shape in Jetpack Compose Canvas?

Jetpack Compose oval shape

Today, we will learn how to draw an oval shape in Jetpack Compose Canvas using the drawOval() method.

Prerequisites:

Canvas drawOval() method:

fun drawOval(
    color: Color,
    topLeft: Offset = Offset.Zero,
    size: Size = this.size.offsetSize(topLeft),
    alpha: Float = 1.0f,
    style: DrawStyle = Fill,
    colorFilter: ColorFilter? = null,
    blendMode: BlendMode = DefaultBlendMode
)

color – Color of the oval

topLeft – It is used to adjust the oval position

size – The size of the oval

alpha – Opacity level. It ranges from from 0.0f to 1.0f, 0.0f represents fully transparent and 1.0f represents fully opaque.

style – If the oval is filled or stroked (border applied)

colorFilter – It is used for modifying each pixel.

blendMode – It is an algorithm to use when painting on the canvas.

Oval shape example:

@Composable
fun MyUI() {
    Canvas(
        modifier = Modifier
            .size(size = 300.dp)
            .border(width = 2.dp, color = Color.Magenta)
    ) {
        drawOval(
            color = Color.Green,
            size = Size(width = 120.dp.toPx(), height = 60.dp.toPx())
        )
    }
}

Output:

oval shape

Oval Position:

Let’s change its position by using the topLeft parameter. We need to pass an Offset object. We can get this object from the Offset() method. It takes x and y coordinates.

@Composable
fun MyUI() {
    Canvas(
        modifier = Modifier
            .size(size = 300.dp)
            .border(width = 2.dp, color = Color.Magenta)
    ) {
        drawOval(
            color = Color.Green,
            size = Size(width = 120.dp.toPx(), height = 60.dp.toPx()),
            topLeft = Offset(x = 40.dp.toPx(), y = 40.dp.toPx())
        )
    }
}

Output:

offset position

The topLeft parameter sets the coordinates to the top left corner of the oval. In the above example, the top left corner of the oval is at (40.dp, 40.dp).

To understand it furthermore, let’s place the oval at the center of the canvas. The canvas size is 300.dp. So, let’s pass 150.dp to both x and y values.

@Composable
fun MyUI() {
    Canvas(
        modifier = Modifier
            .size(size = 300.dp)
            .border(width = 2.dp, color = Color.Magenta)
    ) {
        drawOval(
            color = Color.Green,
            size = Size(width = 120.dp.toPx(), height = 60.dp.toPx()),
            topLeft = Offset(x = 150.dp.toPx(), y = 150.dp.toPx())
        )
    }
}

Output:

Oval center

It is not exactly at the center. The top left corner is at (150.dp, 150.dp). Actually, we need to place the center of the oval at (150.dp, 150.dp). We can do that by moving the oval to the left by half of its width and up by half of its height.

The new offset coordinates become:

x = (Canvas width / 2) - (oval width / 2)
   = (300 / 2) - (120 / 2)
   = 150 - 60
   = 90

y = (Canvas height / 2) - (oval height / 2)
   = (300 / 2) - (60 / 2)
   = 150 - 30
   = 120
@Composable
fun MyUI() {
    Canvas(
        modifier = Modifier
            .size(size = 300.dp)
            .border(width = 2.dp, color = Color.Magenta)
    ) {
        drawOval(
            color = Color.Green,
            size = Size(width = 120.dp.toPx(), height = 60.dp.toPx()),
            topLeft = Offset(x = 90.dp.toPx(), y = 120.dp.toPx())
        )
    }
}

Output:

Center oval

Oval with Border:

Using the style parameter, we can create an oval shape with border.

@Composable
fun MyUI() {
    Canvas(
        modifier = Modifier
            .size(size = 300.dp)
            .border(width = 2.dp, color = Color.Magenta)
    ) {
        drawOval(
            color = Color.Green,
            size = Size(width = 120.dp.toPx(), height = 60.dp.toPx()),
            topLeft = Offset(x = 90.dp.toPx(), y = 120.dp.toPx()),
            style = Stroke(width = 8.dp.toPx())
        )
    }
}

Output:

oval border

There is another overload of drawOval(). It takes brush instead of color. We can draw gradient backgrounds using it.

@Composable
fun MyUI() {
    Canvas(
        modifier = Modifier
            .size(size = 300.dp)
            .border(width = 2.dp, color = Color.Magenta)
    ) {
        drawOval(
            brush = Brush.horizontalGradient(listOf(Color.Cyan, Color.Blue)),
            size = Size(width = 120.dp.toPx(), height = 60.dp.toPx()),
            topLeft = Offset(x = 90.dp.toPx(), y = 120.dp.toPx()),
            style = Stroke(width = 8.dp.toPx())
        )
    }
}

Output:

Gradient Oval

This is all about the drawOval() method. I hope you have learned how to draw an oval shape in Jetpack Compose. If you have any doubts, comment below.

Leave a Comment