What You Will Build

A polygon that continuously morphs between a triangle and a dodecagon while cycling through the color spectrum. The shape smoothly adds and removes sides, creating a mesmerizing generative animation.

Why This Pattern Matters

Morphing shapes appear in loading indicators, brand animations, and creative coding art. This teaches polygon math with trigonometry, HSL color animation, and how Canvas drawing recomposes efficiently in Compose.

Step 1: Animate Morph Progress and Hue

@Composable
fun MorphingShapesScreen() {
    val infiniteTransition = rememberInfiniteTransition(label = "morph")
    val morph by infiniteTransition.animateFloat(
        0f, 1f,
        infiniteRepeatable(tween(3000), RepeatMode.Reverse),
        label = "m"
    )
    val hue by infiniteTransition.animateFloat(
        0f, 360f,
        infiniteRepeatable(tween(6000, easing = LinearEasing)),
        label = "h"
    )
    // ...
}

Step 2: Draw the Dynamic Polygon

The number of sides is derived from the morph value, ranging from 3 (triangle) to 12 (dodecagon). Standard trigonometry plots each vertex:

Canvas(Modifier.size(250.dp)) {
    val center = Offset(size.width / 2, size.height / 2)
    val path = Path()
    val sides = 3 + (morph * 9).toInt()
    val radius = size.width / 2.5f

    for (i in 0..sides) {
        val angle = Math.toRadians(
            (i.toDouble() / sides) * 360.0 - 90.0
        )
        val x = center.x + radius * cos(angle).toFloat()
        val y = center.y + radius * sin(angle).toFloat()
        if (i == 0) path.moveTo(x, y)
        else path.lineTo(x, y)
    }
    path.close()
    drawPath(path, Color.hsl(hue, 0.7f, 0.6f))
}

Step 3: Add a Label Overlay

Box(
    Modifier.fillMaxSize().background(Color(0xFF0F0F23)),
    contentAlignment = Alignment.Center
) {
    // Canvas here
    Text("Morphing", color = Color.White,
         style = MaterialTheme.typography.headlineSmall)
}

Tips and Pitfalls

  • Color.hsl() is the easiest way to cycle through the rainbow. Animating hue from 0 to 360 with LinearEasing creates a smooth spectrum sweep.
  • Subtracting 90 degrees in the angle calculation rotates the polygon so the first vertex points up rather than to the right.
  • Integer side count means jumps. For smoother morphing, interpolate vertex positions between adjacent polygon side counts instead of snapping.
  • Performance: Path construction on every frame is fast for simple polygons. For complex paths (100+ vertices), consider caching.

Get New Tutorials by Email

No spam. Just clear, practical breakdowns you can apply right away.

Enjoy this tutorial?

Get new practical tech tutorials in your inbox.