Search code examples
android-jetpack-composeandroid-canvasandroid-jetpack-compose-canvas

Gap between two drawings in Jetpack compose Canvas


I am trying to make a rectangle and an arc attached to rectangle's bottom. I have used the size provided by the drawScope to lay the drawings on screen but I am unable to get why there is an unnecessary gap between the two drawings even if the specified topLeft parameter of the arc is equal to the height of the rectangle drawn.

Canvas(
        modifier = Modifier.fillMaxWidth()
            .height(200.dp)
    ){

        drawRect(
            color = Color(0xFFEF3125),
            topLeft = Offset(0f, 0f),
            size = Size(this.size.width, this.size.height.times(0.75f))
        )

        drawArc(
            color = Color(0xFFEF3125),
            startAngle = 0f,
            sweepAngle = 180f,
            useCenter = false,
            topLeft = Offset(
                0f, this.size.height.times(0.75f)
            )
        )
    }

enter image description here


Solution

  • There is a gap because when you draw an Arc you use a rectangle as refefrence but you draw arc to half of the this rectangle so you need to offset up as much as the half of the height of the rectangle that you draw arc into

    @Composable
    private fun ArcSample() {
        Canvas(
            modifier = Modifier.fillMaxWidth()
                .height(200.dp)
        ){
    
            drawRect(
                color = Color(0xFFEF3125),
                size = Size(this.size.width, this.size.height.times(0.75f)),
                style = Stroke(4.dp.toPx())
            )
    
    
            drawArc(
                color = Color(0xFFEF3125),
                startAngle = 0f,
                sweepAngle = 180f,
                useCenter = false,
                size = Size(size.width, size.height.times(.25f)),
                topLeft = Offset(
                    0f, this.size.height.times(0.625f)
                ),
                style = Stroke(4.dp.toPx())
            )
        }
    }
    

    I used Stroke style to show bounds, it's for demonstration.

    enter image description here

    @Composable
    private fun ArcSample2() {
        Canvas(
            modifier = Modifier.fillMaxWidth()
                .height(200.dp)
        ){
    
            drawRect(
                color = Color(0xFFEF3125),
                size = Size(this.size.width, this.size.height.times(0.75f))
            )
    
    
            val sizeCoefficient = 0.25f
    
            drawArc(
                color = Color(0xFFEF3125),
                startAngle = 0f,
                sweepAngle = 360f,
                useCenter = false,
                size = Size(size.width, size.height.times(sizeCoefficient)),
                topLeft = Offset(
                    0f, this.size.height.times(0.75f-sizeCoefficient/2f)
                )
            )
        }
    }
    

    enter image description here