How to Draw a Rectangle in Jetpack Compose Canvas?

jetpack compose draw rectangle

drawRect() method helps us to draw a rectangle in Jetpack Compose Canvas. Today, we are going to explore it with the help of examples.

Note: Instead of Canvas, you can create rectangles using the Box and Shape APIs.

Canvas drawRect() Method:

fun drawRect(
    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 rectangle

topLeft – It is used to adjust the rectangle position

size – Size of the rectangle

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 rectangle is filled or stroked (border applied)

colorFilter – It is used for modifying each pixel.

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

Here is a simple rectangle:

@Composable
fun MyUI() {
    Canvas(
        modifier = Modifier
            .size(size = 300.dp)
            .border(width = 2.dp, color = Color.Magenta)
    ) {
        drawRect(color = Color.Yellow)
    }
}

Output:

Canvas draw Rectangle

If we don’t mention the size, it fills the whole canvas. Let’s set the size.

Rectangle Size:

We can set the size using the size parameter.

@Composable
fun MyUI() {
    Canvas(
        modifier = Modifier
            .size(size = 300.dp)
            .border(width = 2.dp, color = Color.Magenta)
    ) {
        drawRect(
            color = Color.Yellow,
            size = Size(width = 160.dp.toPx(), height = 100.dp.toPx())
        )
    }
}

Output:

Size

Rectangle Position:

We can adjust the position by using the topLeft parameter. We need to pass an Offset object by using the Offset() function. It takes x and y coordinates.

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

Output:

Offset Position

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

Let’s place it exactly at the center of the canvas. The canvas size is 300.dp. So, set the x and y coordinates to 150.dp.

@Composable
fun MyUI() {
    Canvas(
        modifier = Modifier
            .size(size = 300.dp)
            .border(width = 2.dp, color = Color.Magenta)
    ) {
        drawRect(
            color = Color.Yellow,
            size = Size(width = 160.dp.toPx(), height = 100.dp.toPx()),
            topLeft = Offset(x = 150.dp.toPx(), y = 150.dp.toPx())
        )
    }
}

Output:

Center Rectangle

Note: If the size of the canvas’ children is bigger than canvas’, they will cross the canvas’ borders. That is why some portion of the rectangle is outside the canvas.

The rectangle is not exactly at the center. Like I said before the top left corner of the rectangle is placed at (150.dp, 150.dp). We actually need to place the center of the rectangle at (150.dp, 150.dp). We can calculate the top left coordinates like this:

x = (Canvas width / 2) - (rectangle width / 2)
   = (300 / 2) - (160 / 2)
   = 150 - 80
   = 70

y = (Canvas height / 2) - (rectangle height / 2)
   = (300 / 2) - (100 / 2)
   = 150 - 50
   = 100
@Composable
fun MyUI() {
    Canvas(
        modifier = Modifier
            .size(size = 300.dp)
            .border(width = 2.dp, color = Color.Magenta)
    ) {
        drawRect(
            color = Color.Yellow,
            size = Size(width = 160.dp.toPx(), height = 100.dp.toPx()),
            topLeft = Offset(x = 70.dp.toPx(), y = 100.dp.toPx())
        )
    }
}

Output:

Coordinates center rectangle

Rectangle with Border:

With the help of the style parameter, we can create a stroked rectangle. The Stroke() method takes the border width as a parameter.

@Composable
fun MyUI() {
    Canvas(
        modifier = Modifier
            .size(size = 300.dp)
            .border(width = 2.dp, color = Color.Magenta)
    ) {
        drawRect(
            color = Color.Yellow,
            size = Size(width = 160.dp.toPx(), height = 100.dp.toPx()),
            topLeft = Offset(x = 70.dp.toPx(), y = 100.dp.toPx()),
            style = Stroke(width = 6.dp.toPx())
        )
    }
}

Output:

Rectangle border

There is another overload of drawRect() that accepts brush instead of color. It is used to create gradient effects.

@Composable
fun MyUI() {
    Canvas(
        modifier = Modifier
            .size(size = 300.dp)
            .border(width = 2.dp, color = Color.Magenta)
    ) {
        drawRect(
            brush = Brush.horizontalGradient(listOf(Color.Magenta, Color.Yellow)),
            size = Size(width = 160.dp.toPx(), height = 100.dp.toPx()),
            topLeft = Offset(x = 70.dp.toPx(), y = 100.dp.toPx()),
            style = Stroke(width = 6.dp.toPx())
        )
    }
}

Output:

draw gradient rectangle

Note: Instead of Canvas, you can also draw rectangles using the Box layout and shapes.

This is about drawRect() function. I hope you have learned how to draw a rectangle in Jetpack Compose Canvas. If you have any doubts, leave a comment below.

Leave a Comment