How to Draw Shapes in Jetpack Compose

How to Draw Shapes in Jetpack Compose
Shapes
A rounded rectangle 📦
A circle🔴 ⭕ 
A triangle 🔺
A line ➖
An arc 🌓
In Jetpack Compose Canvas, you can draw various custom shapes using the drawScope API. Unlike Shape, which is used to define UI component outlines, Canvas gives you complete control over drawing lines, paths, arcs, and custom shapes.

Jetpack Compose provides functions to draw standard geometric shapes:

1. Basic Shapes (Built-in)

  1. Rectangle – drawRect()
  2. Circle – drawCircle()
  3. Oval – drawOval()
  4. Line – drawLine()
  5. Arc (Partial Circle) – drawArc()
  6. Point (Dot) – drawPoints()
  7. Image (Bitmap) – drawImage()
  8. Text – drawText() (Using AndroidTextPaint)

2. Custom Shapes (Using Path)

  1. For more complex shapes, use drawPath() with the Path API:
  2. Triangle
  3. Pentagon
  4. Hexagon
  5. Star (5-point, 6-point, etc.)
  6. Heart
  7. Custom Curved Shapes (Bezier curves, Waves)
  8. Polygons (Any number of sides)

3. Complex and Interactive Shapes

🔵 Custom Circular & Linear Progress Indicators

Using Canvas in Jetpack Compose, you can draw animated circular or linear progress indicators with text or percentage overlays.


// Circular Progress
Canvas(modifier = Modifier.size(100.dp)) {
    drawArc(
        color = Color.Blue,
        startAngle = -90f,
        sweepAngle = 270f, // percent * 360
        useCenter = false,
        style = Stroke(width = 12f)
    )
}
    

📊 Graphs & Charts (Bar, Pie, Line)

Create charts using Jetpack Compose Canvas or use libraries like MPAndroidChart or Charts for Compose.

  • Bar Graph: Use rectangles of varying heights
  • Line Graph: Use Path and drawLine
  • Pie Chart: Use drawArc in loop

// Pie chart arc
drawArc(
    color = Color.Red,
    startAngle = 0f,
    sweepAngle = 90f,
    useCenter = true
)
    

🌊 Waveforms (Sine Wave, Audio Visualizer)

Plot dynamic waveforms using mathematical sine functions and animations.


// Sine Wave with Path
val path = Path()
for (x in 0..width) {
    val y = amplitude * sin(frequency * x + phase)
    path.lineTo(x.toFloat(), y.toFloat())
}
drawPath(path, color = Color.Cyan)
    

🧊 3D-like Shapes (Shadows & Perspective)

Simulate 3D shapes by drawing with shadows, gradients, or perspective skew using GraphicsLayer.


// 3D Shadow Box
Box(
    Modifier
        .size(150.dp)
        .graphicsLayer(
            rotationX = 10f,
            shadowElevation = 12.dp.toPx()
        )
        .background(Color.Gray)
)

✍️ Handwritten Signatures (Freehand Drawing)

Track finger touches with pointerInput and draw a Path for freehand drawing.


val path = remember { Path() }
val points = remember { mutableStateListOf() }

Canvas(modifier = Modifier
    .fillMaxSize()
    .pointerInput(Unit) {
        detectDragGestures { change, _ ->
            points.add(change.position)
        }
    }) {
    path.reset()
    if (points.isNotEmpty()) {
        path.moveTo(points[0].x, points[0].y)
        for (point in points.drop(1)) {
            path.lineTo(point.x, point.y)
        }
    }
    drawPath(path, color = Color.Black, style = Stroke(4f))
}
Previous Post Next Post

Contact Form