How can i draw one-sided thickening stoke on canvas in Android Jetpack Compose?

Viewed 52

Here is my code;

Box(
        modifier = Modifier.fillMaxSize(),
        contentAlignment = Alignment.Center
    ){
        Canvas(
            modifier = Modifier
                .fillMaxSize(0.5f)
                .border(1.dp, Color.Red)
        ){
            drawRect(
                color =Color.Black,
                size = size,
                style = Stroke(
                    width = 100f
                )
            )
        }
    }
}

Result;

enter image description here

I want the thickness to increase from the inside or outside of the red line, NOT both side. How can i achieve this?

3 Answers

You have to consider the offset and the width of the Rect.

To draw outside you can use:

        val width = 100f
        drawRect(
            topLeft = Offset(-width/2, -width/2),
            color =Color.Black,
            size = Size(size.width + width, size.height + width),
            style = Stroke(
                width = width
            )
        )

To draw inside:

        val width = 100f
        drawRect(
            topLeft = Offset(+ width/2, + width/2),
            color =Color.Black,
            size = Size(size.width - width, size.height - width),
            style = Stroke(
                width = width
            )
        )

enter image description here enter image description here

I couldnt able to find any direct solution modifying stroke placement with inner or outer. But here is a way to achieve it,by increasing/ decreasing size and offset.

Here size(width and height) is increased by the (stroke value+size) of rect. And topleft offset will hold (-0.5*stroke value). Here it will increase size of rect and moves slightly left*top from topleft.

  drawRect(
                color = Color.Black,
                size = Size(size.width+100f,size.height+100f),
                style = Stroke(
                    width = 100f
                ),
                topLeft = Offset(-50f,-50f),
            )

enter image description here

Here size(width and height) is increased by the (size-stroke value) of rect. And topleft offset will hold (0.5*stroke value). Here it will decrease size of rect and moves slightly right & bottom from topleft.

    drawRect(
        color = Color.Black,
        size = Size(size.width-100f,size.height-100f),
        style = Stroke(
            width = 100f
        ),
        topLeft = Offset(50f,50f),
    )

enter image description here

You need to offset draw position. Border is drawn from center position to both sides in Canvas so offset it by half of your stroke width and reduce size as stroke width. Also using, for instance 20.dp.px instead of 100f will make sure that your borderSroke will look similar on every device.

@Composable
fun BorderCanvasSample() {
    Box(
        modifier = Modifier.fillMaxSize(),
        contentAlignment = Alignment.Center
    ) {
        Canvas(
            modifier = Modifier
                .fillMaxSize(0.5f)
                .border(1.dp, Color.Red)
        ) {

            val borderStroke = 100f
            val halfStore = borderStroke / 2
            drawRect(
                color = Color.Black,
                topLeft = Offset(halfStore, halfStore),
                size = Size(
                    width = size.width - borderStroke,
                    height = size.height - borderStroke
                ),
                style = Stroke(
                    width = borderStroke
                )
            )
        }
    }
}
Related