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)
- Rectangle – drawRect()
- Circle – drawCircle()
- Oval – drawOval()
- Line – drawLine()
- Arc (Partial Circle) – drawArc()
- Point (Dot) – drawPoints()
- Image (Bitmap) – drawImage()
- Text – drawText() (Using AndroidTextPaint)
2. Custom Shapes (Using Path)
- For more complex shapes, use drawPath() with the Path API:
- Triangle
- Pentagon
- Hexagon
- Star (5-point, 6-point, etc.)
- Heart
- Custom Curved Shapes (Bezier curves, Waves)
- Polygons (Any number of sides)
3. Complex and Interactive Shapes
- 🔵 Custom Circular & Linear Progress Indicators
- 📊 Graphs & Charts (Bar, Pie, Line)
- 🌊 Waveforms (Sine Wave, Audio Visualizer)
- 🧊 3D-like Shapes (Shadows & Perspective)
- ✍️ Handwritten Signatures (Freehand Drawing)
🔵 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
anddrawLine
- 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))
}