Home > Enterprise >  Creating reusable draw functions in Jetpack Compose Canvas
Creating reusable draw functions in Jetpack Compose Canvas

Time:09-25

I'm drawing multiple rings in a Compose Canvas by using the drawArc() function

enter image description here

Most of values being passed into drawArc() are the same apart from colour, sweepAngle and a radius value for controlling the ring size. I would like to abstract most of the drawArc code into a external, reusable function and just pass in those customizable values so I can keep my Canvas code small and easier to read, but I'm struggling trying to provide the Drawscope exposed by the Canvas composable.

Is it possible to do something along the lines of -

Canvas() {
    drawRing(Color.Red, 360f, 200f)
    drawRing(Color.Blue, 180f, 400f) 
}

//ComposeUtils.kt
fun drawRing(color: Color, sweepAngle: Float, arcRadius: Float) {
    
    //Drawscope here?
   
    val canvasWidth = size.width
    val canvasHeight = size.height

    drawArc(
        color = color,
        startAngle = 0f,
        sweepAngle = sweepAngle,
        useCenter = false,
        topLeft = Offset(
           (canvasWidth / 2) - (arcRadius / 2),
            canvasHeight / 2 - (arcRadius / 2)
        ),
        size = Size(arcRadius,
        arcRadius),
        style = Stroke(10.0f))
}

CodePudding user response:

You can define your function as extensions of DrawScope:

fun DrawScope.drawRing(style: Style, color: Color, sweepAngle: Float, arcRadius: Float)

This way you'll have DrawScope bound to this inside your function.

Notice that this isn't too different from how the lambda provided by Canvas is defined. It's a lambda with receiver:

fun Canvas(modifier: Modifier, contentDescription: String, onDraw: DrawScope.() -> Unit)
  • Related