How do I create this circular shape in Jetpack Compose?

544 views Asked by At

I have a Pomodoro app and want to use this circular shape. This shape changes according to time value. Dots on the outside are not important, I want an inside and circular shape on my app. I used Jetpack Compose with drawArc and Canvas, but can't achieve it.

I want something like this:

circle design

Here are my codes:

Canvas(modifier.offset(y = 10.dp)) {
    drawArc(
        color = inactiveBarColor,
        startAngle = 90f,      
        sweepAngle = 90f,       
        useCenter = false,
        size = Size(size.width.toFloat(), size.height.toFloat()),
        style = Stroke(strokeWidth.toPx(), cap = StrokeCap.Round)
   )
   drawArc(
        color = activeBarColor,
        startAngle = 0f,      
        sweepAngle = 90f,
        useCenter = false,
        size = Size(size.width.toFloat(), size.height.toFloat()),
        style = Stroke(strokeWidth.toPx(), cap = StrokeCap.Round)
   )
}

Values of angles are random, and just used for demonstrating

1

There are 1 answers

2
Thracian On BEST ANSWER

You can draw it like this. By changing values you can build exact clock shape. And you need to convert from time to angle for sweep angle in your code.

enter image description here

 @Preview
@Composable
private fun ClockArcSample() {
    Column {

        var sweepAngle by remember {
            mutableStateOf(90f)
        }

        Canvas(
            modifier = Modifier
                .fillMaxWidth()
                .background(Color.Red)
                .aspectRatio(1f)
        ) {
            val canvasWidth = size.width
            val arcDiameter = canvasWidth * .55f

            drawCircle(
                color = Color.White,
                style = Stroke(canvasWidth * 0.04f),
                radius = canvasWidth * .35f
            )

            drawArc(
                color = Color.White,
                270f,
                sweepAngle,
                true,
                topLeft = Offset((canvasWidth - arcDiameter) / 2, (canvasWidth - arcDiameter) / 2),
                size = Size(arcDiameter, arcDiameter)
            )

            val strokeWidth = 2.dp.toPx()
            for (i in 0..360 step 6) {
                rotate(i.toFloat()) {
                    drawLine(
                        color = Color.White,
                        strokeWidth = strokeWidth,
                        start = Offset(
                            x = canvasWidth * 0.90f,
                            y = center.y
                        ),
                        end = Offset(
                            x = canvasWidth * 0.93f,
                            y = center.y
                        ),
                        cap = StrokeCap.Round
                    )
                }
            }
        }

        Slider(
            value = sweepAngle,
            onValueChange = { sweepAngle = it },
            valueRange = 0f..360f
        )
    }
}