애니메이션 맞춤설정

많은 Animation API에서는 일반적으로 동작을 맞춤설정하는 매개변수를 사용할 수 있습니다.

AnimationSpec 매개변수로 애니메이션 맞춤설정

대부분의 Animation API에서 개발자가 선택적 AnimationSpec 매개변수로 애니메이션 사양을 맞춤설정할 수 있습니다.

val alpha: Float by animateFloatAsState(
    targetValue = if (enabled) 1f else 0.5f,
    // Configure the animation duration and easing.
    animationSpec = tween(durationMillis = 300, easing = FastOutSlowInEasing)
)

다양한 유형의 애니메이션을 만들 수 있는 여러 AnimationSpec 유형이 있습니다.

spring로 물리학 기반 애니메이션 만들기

spring은 시작 값과 끝 값 사이에 물리학 기반 애니메이션을 만들며 두 매개변수 dampingRatiostiffness를 사용합니다.

dampingRatio는 스프링의 탄성을 정의합니다. 기본값은 Spring.DampingRatioNoBouncy입니다.

그림 1. 다른 스프링 감쇠비 설정

stiffness는 스프링이 종료 값으로 이동하는 속도를 정의합니다. 기본값은 Spring.StiffnessMedium입니다.

그림 2. 다른 스프링 강성 설정

val value by animateFloatAsState(
    targetValue = 1f,
    animationSpec = spring(
        dampingRatio = Spring.DampingRatioHighBouncy,
        stiffness = Spring.StiffnessMedium
    )
)

spring은 애니메이션 도중 타겟 값이 변경될 때 속도의 연속성을 보장하므로 기간 기반 AnimationSpec 유형보다 원활하게 중단을 처리할 수 있습니다. springanimate*AsState, updateTransition 등 많은 Animation API에서 기본 AnimationSpec으로 사용됩니다.

예를 들어 사용자 터치로 구동되는 다음 애니메이션에 spring 구성을 적용하면 애니메이션이 진행되는 동안 애니메이션을 중단할 때 tween 사용 시 spring 사용만큼 원활하게 반응하지 않음을 알 수 있습니다.

그림 3. 애니메이션의 tweenspring 사양을 설정하여 중단하는 중입니다.

tween를 사용하여 이징 곡선으로 시작 값과 끝 값 간 애니메이션 처리

tween은 이징 곡선을 사용하여 지정된 durationMillis 동안 시작 값과 끝 값 간에 애니메이션을 처리합니다. tween는 두 값 사이에 있는 단어의 축약형입니다.

delayMillis를 지정하여 애니메이션 시작을 연기할 수도 있습니다.

val value by animateFloatAsState(
    targetValue = 1f,
    animationSpec = tween(
        durationMillis = 300,
        delayMillis = 50,
        easing = LinearOutSlowInEasing
    )
)

자세한 내용은 이징을 참고하세요.

keyframes를 사용하여 특정 타이밍에서 특정 값에 애니메이션 적용

keyframes는 애니메이션 기간에 여러 타임스탬프에서 지정된 스냅샷 값을 기반으로 애니메이션을 처리합니다. 언제나 애니메이션 값은 두 키프레임 값 사이에 보간됩니다. 키프레임마다 이징을 지정하여 보간 유형 곡선을 결정할 수 있습니다.

0밀리초 및 지속 시간에 값을 지정할 수도 있습니다. 이 값을 지정하지 않으면 각각 애니메이션의 시작 값과 종료 값으로 기본 설정됩니다.

val value by animateFloatAsState(
    targetValue = 1f,
    animationSpec = keyframes {
        durationMillis = 375
        0.0f at 0 with LinearOutSlowInEasing // for 0-15 ms
        0.2f at 15 with FastOutLinearInEasing // for 15-75 ms
        0.4f at 75 // ms
        0.4f at 225 // ms
    }
)

repeatable로 애니메이션 반복

repeatable은 지정된 반복 횟수에 도달할 때까지 기간 기반 애니메이션(예: tween 또는 keyframes)을 반복적으로 실행합니다. repeatMode 매개변수를 전달하여 처음(RepeatMode.Restart)부터 또는 끝(RepeatMode.Reverse)부터 시작하여 애니메이션을 반복할지 여부를 지정할 수 있습니다.

val value by animateFloatAsState(
    targetValue = 1f,
    animationSpec = repeatable(
        iterations = 3,
        animation = tween(durationMillis = 300),
        repeatMode = RepeatMode.Reverse
    )
)

infiniteRepeatable로 애니메이션 무한 반복

infiniteRepeatablerepeatable과 유사하지만 무한 반복됩니다.

val value by animateFloatAsState(
    targetValue = 1f,
    animationSpec = infiniteRepeatable(
        animation = tween(durationMillis = 300),
        repeatMode = RepeatMode.Reverse
    )
)

ComposeTestRule을 사용하는 테스트에서 infiniteRepeatable을 사용하는 애니메이션은 실행되지 않습니다. 구성요소는 각 애니메이션된 값의 초깃값을 사용하여 렌더링됩니다.

snap를 사용하여 즉시 끝 값에 맞추기

snap은 값을 즉시 종료 값으로 변환하는 특수 AnimationSpec입니다. delayMillis를 지정하여 애니메이션 시작을 지연시킬 수 있습니다.

val value by animateFloatAsState(
    targetValue = 1f,
    animationSpec = snap(delayMillis = 50)
)

맞춤 이징 함수 설정

기간 기반 AnimationSpec 작업(예: tween 또는 keyframes)은 Easing을 사용하여 애니메이션의 분수 값을 조정합니다. 이렇게 하면 애니메이션 값이 일정한 속도로 움직이는 대신 더 빨라지고 느려질 수 있습니다. 비율은 애니메이션의 현재 지점을 나타내는 0(시작)과 1.0(끝) 사이의 값입니다.

이징은 실제로는 0과 1.0 사이의 분수 값을 가져와 부동 소수점 수를 반환하는 함수입니다. 반환된 값은 목표를 초과하거나 목표에 미달한 값을 나타내기 위해 경계를 벗어날 수 있습니다. 아래의 코드와 같이 맞춤 이징을 만들 수 있습니다.

val CustomEasing = Easing { fraction -> fraction * fraction }

@Composable
fun EasingUsage() {
    val value by animateFloatAsState(
        targetValue = 1f,
        animationSpec = tween(
            durationMillis = 300,
            easing = CustomEasing
        )
    )
    // ……
}

Compose는 대부분의 사용 사례가 포함되는 여러 내장 Easing 함수를 제공합니다. 시나리오에 따라 이징에서 사용해야 하는 항목에 관한 자세한 내용은 속도 - Material Design을 참고하세요.

  • FastOutSlowInEasing
  • LinearOutSlowInEasing
  • FastOutLinearEasing
  • LinearEasing
  • CubicBezierEasing
  • 더 보기

AnimationVector로 변환하여 맞춤 데이터 유형에 애니메이션 적용

대부분의 Compose Animation API는 기본적으로 Float, Color, Dp 및 기타 기본 데이터 유형을 애니메이션 값으로 지원하지만 맞춤 데이터 유형을 포함하여 다른 데이터 유형에 애니메이션을 적용해야 하는 경우도 있습니다. 애니메이션 중에 모든 애니메이션 값은 AnimationVector로 표시됩니다. 값은 핵심 애니메이션 시스템이 균일하게 처리할 수 있도록 상응하는 TwoWayConverter에 의해 AnimationVector로 변환되며 그 반대로도 변환됩니다. 예를 들어 Int는 단일 부동 소수점 값을 보유한 AnimationVector1D로 표시됩니다. IntTwoWayConverter는 다음과 같습니다.

val IntToVector: TwoWayConverter<Int, AnimationVector1D> =
    TwoWayConverter({ AnimationVector1D(it.toFloat()) }, { it.value.toInt() })

Color는 기본적으로 빨간색, 녹색, 파란색, 알파 등 네 값의 집합이므로 Color는 네 개의 부동 소수점 값을 보유한 AnimationVector4D로 변환됩니다. 애니메이션에 사용되는 모든 데이터 유형은 이러한 방식으로 차원에 따라 AnimationVector1D, AnimationVector2D, AnimationVector3D 또는 AnimationVector4D로 변환됩니다. 따라서 객체의 여러 구성요소를 각각 자체 속도 추적 기능을 사용하여 독립적으로 애니메이션 처리할 수 있습니다. 기본 데이터 유형의 내장 변환기는 Color.VectorConverter 또는 Dp.VectorConverter와 같은 변환기를 사용하여 액세스할 수 있습니다.

새 데이터 유형 지원 기능을 애니메이션 값으로 추가하려면 자체 TwoWayConverter를 만들어 API에 제공하면 됩니다. 예를 들어 다음과 같이 animateValueAsState를 사용하여 맞춤 데이터 유형을 애니메이션 처리할 수 있습니다.

data class MySize(val width: Dp, val height: Dp)

@Composable
fun MyAnimation(targetSize: MySize) {
    val animSize: MySize by animateValueAsState(
        targetSize,
        TwoWayConverter(
            convertToVector = { size: MySize ->
                // Extract a float value from each of the `Dp` fields.
                AnimationVector2D(size.width.value, size.height.value)
            },
            convertFromVector = { vector: AnimationVector2D ->
                MySize(vector.v1.dp, vector.v2.dp)
            }
        )
    )
}

다음 목록에는 내장된 VectorConverter가 포함되어 있습니다.