What are the techniques for not having to redraw the entire content of a Canvas on every redraw? For instance, if a Canvas is displaying a top-down view of a chess game and I want to remove a piece, I'd like to redraw just the part of the Canvas where the piece is removed. In my current implementation, if I update only a section of the Canvas and don't redraw the entire board I'm left with only the updated section displayed.
I've tried methods suggested by Chat GPT such as redrawing the updated area with a clipRect, using drawWithContent(), and drawing to the underlying native canvas. Maybe I didn't use the techniques correctly, but nothing seemed to work and I still redraw the entire board with every recompose even though only a little bit of the board actually has changed.
Below is how I'm currently updating Canvas. appVM is a ViewModel that processes user clicks on the board. Based on the clicks, appVM sets the state variable gameCngState to request the board to be updated in various ways (select/deselect a piece to move, select/deselect a destination, etc). Right now, instead of drawing just the parts of the board that changed, I redraw the entire board. Otherwise, I only see the parts that changed.
Box(
modifier = Modifier
.fillMaxSize()
.pointerInput(Unit) {
detectTapGestures(
onTap = { offset -> appVM.onClick(offset) }
)
}
}
) {
Canvas(
modifier = Modifier
.fillMaxSize()
.clipToBounds()
.onSizeChanged { size -> appVM.onSizeChange(size) }
) {
appVM.onCanvasDraw(
drawScope = this,
gameCngState = gameCngState
)
}
The below code shows how the drawing of each board square is performed. The transform places the square/piece at the correct location on the Canvas.
drawScope.translate(left = transLeft, top = transTop)
{
drawPath(...) // draw square with optional piece
}