DEV Community

myougaTheAxo
myougaTheAxo

Posted on • Originally published at zenn.dev

Canvas Custom Drawing in Compose - drawCircle, Path, and Charts (v2)

Canvas provides low-level drawing primitives for custom graphics. Master drawCircle, Path, and implement line charts and touch-responsive drawings.

Drawing Circles and Shapes

Use Canvas with drawCircle and drawRect:

Canvas(modifier = Modifier.fillMaxSize()) {
    val radius = 50.dp.toPx()

    // Draw circle
    drawCircle(
        color = Color.Blue,
        radius = radius,
        center = Offset(size.width / 2, size.height / 2)
    )

    // Draw rectangle
    drawRect(
        color = Color.Red,
        topLeft = Offset(100f, 100f),
        size = Size(200f, 200f)
    )
}
Enter fullscreen mode Exit fullscreen mode

Creating Complex Paths

Build custom shapes with Path:

Canvas(modifier = Modifier.fillMaxSize()) {
    val path = Path().apply {
        moveTo(size.width / 2, 50f)
        lineTo(size.width - 50f, size.height - 50f)
        lineTo(50f, size.height - 50f)
        close()
    }

    drawPath(path, color = Color.Green, style = Stroke(width = 3f))
}
Enter fullscreen mode Exit fullscreen mode

Drawing Line Charts

Visualize data with canvas-based charts:

@Composable
fun LineChart(data: List<Float>, modifier: Modifier = Modifier) {
    Canvas(modifier = modifier.fillMaxWidth()) {
        val maxValue = data.maxOrNull() ?: 1f
        val stepX = size.width / data.size

        data.forEachIndexed { index, value ->
            val x = index * stepX
            val y = size.height * (1 - value / maxValue)

            if (index > 0) {
                drawLine(
                    color = Color.Blue,
                    start = Offset(x - stepX,
                        size.height * (1 - data[index - 1] / maxValue)),
                    end = Offset(x, y),
                    strokeWidth = 3f
                )
            }
            drawCircle(color = Color.Blue, radius = 5f, center = Offset(x, y))
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Touch-Responsive Drawing

Handle pointer events for interactive drawings:

Canvas(
    modifier = Modifier
        .fillMaxSize()
        .pointerInput(Unit) {
            detectDragGestures { change, _ ->
                change.consume()
                paths.add(Pair(change.position, Color.Black))
            }
        }
) {
    paths.forEach { (offset, color) ->
        drawCircle(color, 5f, offset)
    }
}
Enter fullscreen mode Exit fullscreen mode

Canvas unlocks creative possibilities in Compose. Leverage it for data visualization, custom controls, and artistic interfaces.

8 Android app templates on Gumroad

Top comments (0)