Compose Animation:AnimationSpecでアニメの形状を指定(snap編)

投稿日:  更新日:

アニメーションの動きに特殊な効果を加えることができます。

特殊な効果とは、動きが加速したり、減速したり、弾んだり、または向きを変えたり、などです。

上記のような特殊な効果は、動きの軌道がそれぞれ異なる形になるため、ここでは「アニメーションの形状」と表現しています。

AnimationSpecはアニメーションの形状を定義するインターフェースです。そして、Jetpack Composeは実装済みの形状を4つ提供しています。

この中から、「snap」と取りあげて、まとめます。

※環境:Android Studio Iguana | 2023.2.1 Patch 1
    Kotlin 1.9.0
    Compose Compiler 1.5.1
    androidx.compose.animation:* 1.5.0

スポンサーリンク

アニメーションの形状

AnimationSpecはアニメーションの形状を定義するインターフェースです。

interface AnimationSpec<T> {
    fun <V : AnimationVector> vectorize(
        converter: TwoWayConverter<T, V>
    ): VectorizedAnimationSpec<V>
}

Jetpack Composeは実装済みの形状を4つ提供しています。

形状概要補足
tween滑らかな曲線を描いて変化3次のベジェ曲線
springバネが振動するように変化バネの減衰比(振動の振幅)を選択可能
バネの硬さ(振動の速さ)を選択可能
keyframes折れ線を描いて変化
snap指定時間に即座に切り替え

この中のsnapは、指定時間に即座に切り替えるアニメーションを提供します。snapの実態はAnimationSpecを実装したSnapSpecクラスです。

@Stable
fun <T> snap(delayMillis: Int = 0) = SnapSpec<T>(delayMillis)

snapの変化

private val StartX = 20.dp
private val EndX = 260.dp

@Preview
@Composable
private fun AnimationSpecSample() {
    Column {
        val _toggle = remember { mutableStateOf(false) }
        Spacer(modifier = Modifier.height(20.dp))
        // ----------------------------------------------------------
		...
        Text(text = "[ snap ]")
        Box(
            modifier = Modifier
                .size(width = 320.dp, height = 50.dp)
                .background(color = Color(0xFFF0F0FF)),
            contentAlignment = Alignment.CenterStart
        ) {
            val _posX = animateDpAsState(
                targetValue = if(_toggle.value) EndX else StartX,
                animationSpec = snap(delayMillis = 300),
            )
            Image(
                painter = painterResource(R.drawable.baseline_toys_black_36),
                contentDescription = null,
                modifier = Modifier
                    .size(36.dp)
                    .offset(x = _posX.value)
            )
        }
		...
        // ----------------------------------------------------------
        Spacer(modifier = Modifier.height(20.dp))
        Button(onClick = { _toggle.value = !_toggle.value }) {
            Text(text = "Toggle")
        }
    }
}
スポンサーリンク

関数の引数

snap関数は次のような引数を持ち、形状を調整できます。

引数概要
delayMillisIntアニメーションの開始までの待機時間
スポンサーリンク

待機時間(delayMillis)

delayMillisはアニメーション開始までの待機時間を指定します。

待機時間の経過後、即座にtargetValueへ値を切り替えます。

待機時間

例:delayMillisの違い

delayMillisの違い

delayMillisのサンプルコード
private val StartX = 20.dp
private val EndX = 260.dp

@Preview_mdpi320x480
@Composable
private fun DelaySample() {
    Column {
        val _toggle = remember { mutableStateOf(false) }
        Spacer(modifier = Modifier.height(20.dp))
        // ----------------------------------------------------------
        Text(text = "[ Delay  200ms ]")
        Box(
            modifier = Modifier
                .size(width = 320.dp, height = 50.dp)
                .background(color = Color(0xFFF0F0FF)),
            contentAlignment = Alignment.CenterStart
        ) {
            val _posX = animateDpAsState(
                targetValue = if(_toggle.value) EndX else StartX,
                animationSpec = snap(delayMillis = 200)
            )
            Image(
                painter = painterResource(R.drawable.baseline_toys_black_36),
                contentDescription = null,
                modifier = Modifier
                    .size(36.dp)
                    .offset(x = _posX.value)
            )
        }
        // ----------------------------------------------------------
        Text(text = "[ Delay  500ms ]")
        Box(
            modifier = Modifier
                .size(width = 320.dp, height = 50.dp)
                .background(color = Color(0xFFF0F0FF)),
            contentAlignment = Alignment.CenterStart
        ) {
            val _posX = animateDpAsState(
                targetValue = if(_toggle.value) EndX else StartX,
                animationSpec = snap(delayMillis = 500)
            )
            Image(
                painter = painterResource(R.drawable.baseline_toys_black_36),
                contentDescription = null,
                modifier = Modifier
                    .size(36.dp)
                    .offset(x = _posX.value)
            )
        }
        // ----------------------------------------------------------
        Text(text = "[ Delay 1000ms ]")
        Box(
            modifier = Modifier
                .size(width = 320.dp, height = 50.dp)
                .background(color = Color(0xFFF0F0FF)),
            contentAlignment = Alignment.CenterStart
        ) {
            val _posX = animateDpAsState(
                targetValue = if(_toggle.value) EndX else StartX,
                animationSpec = snap(delayMillis = 1000)
            )
            Image(
                painter = painterResource(R.drawable.baseline_toys_black_36),
                contentDescription = null,
                modifier = Modifier
                    .size(36.dp)
                    .offset(x = _posX.value)
            )
        }
        // ----------------------------------------------------------
        Spacer(modifier = Modifier.height(20.dp))
        Button(onClick = { _toggle.value = !_toggle.value }) {
            Text(text = "Toggle")
        }
    }
}
スポンサーリンク

関連記事:

animate*AsState関数は制御する値のタイプにより、数種類が準備されています。 どの関数も、animateValueAsStateが原型のラッパー関数であり、動作は同じです。 ここでは、各々の関数について、サンプルを示します。 また、animateValueAsStateのサンプルは、独自の関数を作る方法を紹介しています。 ※環境:Android Studio Iguana | 2023.2.1     Kotlin 1.9.0     Compose Compiler 1.5.1     androidx.compose.animation:* 1.5.0 ...
Jetpack Composeが提供するアニメーションAPIは非常に充実しています。 「どのAPIを使えば最適なのか?」と、その選択を迷うくらいに数が多いです。ドキュメントは、「〇〇占い」に登場するようなYes/Noの設問ツリーを掲載(アニメーションAPIを選択する)して、選択の手助け行っています。 ここでは、アニメーションAPIの中から「animate*AsState(*は型名が入る)」を取りあげて、まとめます。 animate*AsStateは、APIの中で最も汎用性があります。まず始めに抑えておくべきアニメーションAPIです。 ※環境:Android Studio Iguana | 2023.2.1     Kotlin 1.9.0     Compose Compiler 1.5.1     androidx.compose.animation:* 1.5.0 ...
アニメーションの動きに特殊な効果を加えることができます。 特殊な効果とは、動きが加速したり、減速したり、弾んだり、または向きを変えたり、などです。 上記のような特殊な効果は、動きの軌道がそれぞれ異なる形になるため、ここでは「アニメーションの形状」と表現しています。 AnimationSpecはアニメーションの形状を定義するインターフェースです。そして、Jetpack Composeは実装済みの形状を4つ提供しています。 この中から、「spring」と取りあげて、まとめます。 ※環境:Android Studio Iguana | 2023.2.1 Patch 1     Kotlin 1.9.0     Compose Compiler 1.5.1     androidx.compose.animation:* 1.5.0 ...
アニメーションの動きに特殊な効果を加えることができます。 特殊な効果とは、動きが加速したり、減速したり、弾んだり、または向きを変えたり、などです。 上記のような特殊な効果は、動きの軌道がそれぞれ異なる形になるため、ここでは「アニメーションの形状」と表現しています。 AnimationSpecはアニメーションの形状を定義するインターフェースです。そして、Jetpack Composeは実装済みの形状を4つ提供しています。 この中から、「tween」と取りあげて、まとめます。 ※環境:Android Studio Iguana | 2023.2.1 Patch 1     Kotlin 1.9.0     Compose Compiler 1.5.1     androidx.compose.animation:* 1.5.0 ...
アニメーションの動きに特殊な効果を加えることができます。 特殊な効果とは、動きが加速したり、減速したり、弾んだり、または向きを変えたり、などです。 上記のような特殊な効果は、動きの軌道がそれぞれ異なる形になるため、ここでは「アニメーションの形状」と表現しています。 AnimationSpecはアニメーションの形状を定義するインターフェースです。そして、Jetpack Composeは実装済みの形状を4つ提供しています。 この中から、「keyframes」と取りあげて、まとめます。 ※環境:Android Studio Iguana | 2023.2.1 Patch 1     Kotlin 1.9.0     Compose Compiler 1.5.1     androidx.compose.animation:* 1.5.0 ...
スポンサーリンク