I'm playing around with `Canvas` and "finger drawi...
# compose
u
I'm playing around with
Canvas
and "finger drawing". I collect
Offset
points via
pointerInput.detectDragGestures
, seems easy enough My issue is in order to draw that, I need a
Path
, i.e.
List<Offset> -> Path
mapping, i.e. a new
Path
instance every draw call, which doesn't seem optimal Obviously just calling `moveTo`/`lineTo` on drag events won't do as that won't cause recomposition What would be the best way to make this work? Is there some neat way to wrap
Path
in something recomposition-triggering?
Copy code
val points = remember {
    mutableStateListOf<Offset>()
}

Canvas(
    modifier = Modifier
        .fillMaxWidth()
        .height(256.dp)
        .pointerInput(Unit) {
            detectDragGestures(
                onDragStart = { offset ->
                    points.add(offset)
                },
                onDrag = { change, _ ->
                    points.add(change.position)
                }
            )
        }
) {
    val path = points.toPath() <-----------------
    drawPath(path, color = Color.Red)
}
r
You can call reset() on a path so you don't have to create a new one
And of course you can also call lineTo on gesture events and trigger a redraw manually (you don't need a recomposition! Just a repaint)
u
Doh, thanks!
Btw since you're here, how would you determine if say x% of the canvas was filled in? Have a ImageBitmap backed Canvas, and then count the number of colored pixels? But that variant of Canvas doesnt have Modifier to attach pointerInput
r
You can attach the pointerInput to something that wraps your canvas
And to determine the fill % yeah you’d have to count pixels. You may be able to do something smarter by computing the area of what you add to the
Path
but it can be very tricky
You could also do something approximate
I.e. keep your
Canvas
, create an offscreen canvas to render into a bitmap at a lower resolution, and render your path a second time in that bitmap
As a bonus you can do that step on a worker thread at a different framerate
Won’t be exact but good enough
u
Yea I was about to dust off the math notebooks 😀 but then I realized pixels are already discrete
okay so essentially draw into both, and use the latter just for the computation, I get it, thanks you!