Create art using Jetpack Compose
Tags: android, kotlin
Published: 2020-10-20 06:11:22

Inspired by recent amazing tweets of [@alexlockwood](https://twitter.com/alexjlockwood?s=20) about jetpack compose I started playing with jetpack compose canvas and want to share what I learned so far.

**Note:** To understand the below code you must have basic knowledge of jetpack compose.

In this article, we will look at how to make the below animation in jetpack compose.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/ruu5mdemt4m2tlcpoj72.gif)

This article is based on jetpack compose version **1.0.0-alpha05**

To add jetpack compose in your project go to your app-level build.gradle file and add below code

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/ndwovsl9iqs2ks3d2l5t.png)

Now, we will start writing our composables.

![Alt Text](https://media.giphy.com/media/PiQejEf31116URju4V/giphy.gif)

To create a container to hold your canvas
In your **`setContent`** composable add the below code.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/eo324c76t6kpm1y92fsp.png)

Write code to draw a single rectangle first.

To draw a rectangle on the canvas, canvas provides **`drawRect`** function.

{% gist https://gist.github.com/Akashkamble/345019b1201d89daac6c704104bc20d2 %}

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/t9rsfa3ur1w7lnczoglx.png)

Let's understand the above code
1. The coordinates start from the top left corner of the canvas and the **`translate`** function moves the canvas at a given point. With the above code, our (0,0) coordinates are now at the center of the canvas.
2. **`drawRect`** function requires `brush`, `topLeft` offset point on the canvas, `size`, `style`, `alpha`, `colorFilter` and `blendMode` as arguments. For now we will focus only on `brush`, `topLeft` Offset, `size` and `style`.

As you have learned to draw a single rectangle on canvas now, we will repeat the same process to draw multiple rectangles of different sizes.
For simplicity and Maintainability, we will create a data class **RectData** which takes `size`, `OffsetX`, `offsetY` for now (later in this article we will add color as a property). Make a list of **RectData** and iterate over it as shown in the code below.

{%gist https://gist.github.com/Akashkamble/b28393fb2d23790fe3a5c8f2c2f4b65f %}

Run the app and you will see an output as shown in the below image.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/bzmcuox6uzj04dv5e22v.png)

Now we are moving towards an interesting part of this article.
For the animation, we need to rotate the rectangles at a particular angle in every frame.
In order to this, we must get the time taken by our composable till now and multiply it with **360f**.
The below code gives us a state with animation time taken by our composable till now in milliseconds and every time the state value changes the rectangles will be drawn at a new angle.

{% gist https://gist.github.com/Akashkamble/479da772e22f999b7b1ce693542bd306 %}

To rotate anything on the canvas we have to use **`rotate`** function which takes `angle` and `Offset(x, y)` point.
We will wrap **`drawRect`** function in **`rotate`** function as shown in the below code.

{% gist https://gist.github.com/Akashkamble/a716e162c51b55e01cb39bceeecff29d %}

And if we run the app we will get an output as below.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/cbbvbdg96tqpzbnzm1uk.gif)

But, that's not what we wanted. We want our inner rectangle to be rotated at a faster speed and gradually decrease the speed as we go towards outer rectangles.
For this, we will change the value of the angle depending on the index of the rectangle in the list.

{% gist https://gist.github.com/Akashkamble/f576668e01908ddc7b27ff8a668ddc57 %}

And the output will be as below.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/7axif3ut0vo9buqz2h8t.gif)

It's time to add colors now.
Make colorList, add a new property in **RectData** as color, and remove the style of **`drawRect`** as default style is of Type **Fill**.

{% gist https://gist.github.com/Akashkamble/c00bb280f9e6d74de07f464bd2962a1a %}

And the output is as below

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/4zxvdnkzjnqdf6eyf6ow.png)


In the above image, the outer rectangles are getting drawn on top of the inner rectangles, so we draw them in reverse order.

And the output will be as below.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/a1gauwxjzses97fryw24.gif)


For final code and many more canvas animations checkout [CanvasPlayGround](https://github.com/Akashkamble/CanvasPlayground).