Create the polygons
The first step we want to perform is a transition from a circle to a squiggly circle, so we create the two shapes that we need to morph between.
We use RoundedPolygon#star() as this allows us to set an inner radius for the shape with rounded corners, and a RoundedPolygon#circle() for the circle shape.
val starPolygon = remember {
   RoundedPolygon.star(
       numVerticesPerRadius = 12,
       innerRadius = 1f / 3f,
       rounding = CornerRounding(1f / 6f))
}
val circlePolygon = remember {
   RoundedPolygon.circle(
       numVertices = 12
   )
}
Morph between the two shapes
In order to morph between the two polygons, we need to create a Morph object:
val morph = remember {
   Morph(starPolygon, circlePolygon)
}
val infiniteTransition = rememberInfiniteTransition(label = "infinite")
val progress = infiniteTransition.animateFloat(
   initialValue = 0f,
   targetValue = 1f,
   animationSpec = infiniteRepeatable(
       tween(4000, easing = LinearEasing),
       repeatMode = RepeatMode.Reverse
   ),
   label = "progress"
)
//.. shapes that are created .. // 
var morphPath = remember {
   Path()
}
var androidPath = remember {
   Path()
}
var matrix = remember {
   Matrix()
}
Box(
   modifier = Modifier
       .padding(16.dp)
       .drawWithCache {
          androidPath = morph.toPath(progress.value, androidPath)
          morphPath = androidPath.asComposePath()
          matrix.reset()
          matrix.scale(size.minDimension / 2f, size.minDimension / 2f)
          morphPath.transform(matrix)
           onDrawBehind {
               translate(size.width / 2f, size.height / 2f) {
                   drawPath(morphPath, color = Color.Black, style = Stroke(16.dp.toPx()))
               }
           }
     }
)Now we can rotate the shape over time by creating another animating variable for rotation and calling DrawScope#rotate().
val infiniteTransition = rememberInfiniteTransition(label = "infinite")
val progress = infiniteTransition.animateFloat(
   initialValue = 0f,
   targetValue = 1f,
   animationSpec = infiniteRepeatable(
       tween(4000, easing = LinearEasing),
       repeatMode = RepeatMode.Reverse
   ),
   label = "progress"
)
val rotation = infiniteTransition.animateFloat(
   initialValue = 0f,
   targetValue = 360f,
   animationSpec = infiniteRepeatable(
       tween(4000, easing = LinearEasing),
       repeatMode = RepeatMode.Reverse
   ),
   label = "rotation"
)
Box(
   modifier = Modifier
       .padding(16.dp)
       .drawWithCache {
           androidPath = morph.toPath(progress.value, androidPath)
           morphPath = androidPath.asComposePath()
           matrix.reset()
           matrix.scale(size.minDimension / 2f, size.minDimension / 2f)
           morphPath.transform(matrix)
           onDrawBehind {
               rotate(rotation.value){
                   translate(size.width / 2f, size.height / 2f) {
                       drawPath(morphPath, color = Color.Black, style = Stroke(16.dp.toPx()))
                   }
               }Which results in a rotating and morphing shape animation like this:
