How to Create Translate Animation in Android Jetpack Compose

By Mohammed Rashid •  Updated on: February 22nd, 2023 • 

Jetpack Compose simplifies UI development and allows developers to create beautiful, responsive, and customizable interfaces with ease. In this tutorial, let’s learn how to add translate animation in Jetpack Compose.

By the translate animation, we mean animating the position of the composable using the offset modifier. See the following code.

@Composable
fun AnimationExample() {
    val coroutineScope = rememberCoroutineScope()
    val offsetX = remember { Animatable(0f) }
    val offsetY = remember { Animatable(0f) }

    Column(Modifier.fillMaxSize(),
        horizontalAlignment = Alignment.CenterHorizontally)
    {
        Button(onClick = { coroutineScope.launch {
            launch {
                offsetX.animateTo(
                    targetValue = 300f,
                    animationSpec = tween(
                        durationMillis = 1000,
                        easing = LinearEasing))}
        } }) {
            Text(text = "Click Here!")
        }

        Box(modifier = Modifier
            .offset {
                IntOffset(
                    offsetX.value.toInt(),
                    offsetY.value.toInt()
                )
            }
            .size(100.dp)
            .background(color = Color.Blue)
            )
    }
}

The function starts by creating a CoroutineScope using the rememberCoroutineScope() function. This is necessary to launch coroutines, which can be used to run animations.

Then we have two Animatable objects called “offsetX” and “offsetY” using the remember() function. These Animatable objects are used to store the current values of the X and Y offsets for the animation.

When the button is clicked, a coroutine is launched that animates the X offset using the animateTo() function. The animation moves the X offset from its current value to 300 pixels over a duration of 1000 milliseconds (1 second), using a linear easing function.

Finally, we have a Box with a size of 100 dp and a blue background color. The Box is positioned using the offsetX and offsetY Animatable objects, which are converted to IntOffsets using the .toInt() function.

We will get the following output.

jetpack compose translate animation

The above example do a horizontal translate animation. If you want to have a vertical translate animation you can do it as given below.

@Composable
fun AnimationExample() {
    val coroutineScope = rememberCoroutineScope()
    val offsetX = remember { Animatable(0f) }
    val offsetY = remember { Animatable(0f) }

    Column(Modifier.fillMaxSize(),
        horizontalAlignment = Alignment.CenterHorizontally)
    {
        Button(onClick = { coroutineScope.launch {
            launch {
                offsetY.animateTo(
                    targetValue = 300f,
                    animationSpec = tween(
                        durationMillis = 1000,
                        easing = LinearEasing))}
        } }) {
            Text(text = "Click Here!")
        }

        Box(modifier = Modifier
            .offset {
                IntOffset(
                    offsetX.value.toInt(),
                    offsetY.value.toInt()
                )
            }
            .size(100.dp)
            .background(color = Color.Blue)
            )
    }
}

You will get the following output.

In case, you want to create a move animation across both the x and y axis then you can use the following code.

fun AnimationExample() {
    val coroutineScope = rememberCoroutineScope()
    val offsetX = remember { Animatable(0f) }
    val offsetY = remember { Animatable(0f) }

    Column(Modifier.fillMaxSize(),
        horizontalAlignment = Alignment.CenterHorizontally)
    {
        Button(onClick = { coroutineScope.launch {
            launch {
                offsetX.animateTo(
                    targetValue = 300f,
                    animationSpec = tween(
                        durationMillis = 1000,
                        easing = LinearEasing))}
            launch {
                offsetY.animateTo(
                    targetValue = 300f,
                    animationSpec = tween(
                        durationMillis = 1000,
                        easing = LinearEasing))}
        } }) {
            Text(text = "Click Here!")
        }

        Box(modifier = Modifier
            .offset {
                IntOffset(
                    offsetX.value.toInt(),
                    offsetY.value.toInt()
                )
            }
            .size(100.dp)
            .background(color = Color.Blue)
            )
    }
}

You will get the following output.

jetpack compose move animation

Following is the complete code for reference.

package com.example.myapplication

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.animation.core.Animatable
import androidx.compose.animation.core.LinearEasing
import androidx.compose.animation.core.tween
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.material3.Button
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.dp
import com.example.myapplication.ui.theme.MyApplicationTheme
import kotlinx.coroutines.launch

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            MyApplicationTheme {
                Surface(
                    modifier = Modifier.fillMaxSize(),
                    color = MaterialTheme.colorScheme.background
                ) {
                    AnimationExample()
                }
            }
        }
    }
}

@Composable
fun AnimationExample() {
    val coroutineScope = rememberCoroutineScope()
    val offsetX = remember { Animatable(0f) }
    val offsetY = remember { Animatable(0f) }

    Column(Modifier.fillMaxSize(),
        horizontalAlignment = Alignment.CenterHorizontally)
    {
        Button(onClick = { coroutineScope.launch {
            launch {
                offsetX.animateTo(
                    targetValue = 300f,
                    animationSpec = tween(
                        durationMillis = 1000,
                        easing = LinearEasing))}
            launch {
                offsetY.animateTo(
                    targetValue = 300f,
                    animationSpec = tween(
                        durationMillis = 1000,
                        easing = LinearEasing))}
        } }) {
            Text(text = "Click Here!")
        }

        Box(modifier = Modifier
            .offset {
                IntOffset(
                    offsetX.value.toInt(),
                    offsetY.value.toInt()
                )
            }
            .size(100.dp)
            .background(color = Color.Blue)
            )
    }
}

@Preview(showBackground = true)
@Composable
fun DefaultPreview() {
    MyApplicationTheme {
        AnimationExample()
    }
}

That’s how you create translate animations in Jetpack Compose.

Keep Reading