[Android] 물 채워지는 애니메이션 만들기

uuranus·2024년 7월 31일
0
post-thumbnail

클릭할 때마다 height 변경

Box(
    modifier = Modifier
        .fillMaxWidth()
        .height(height)
        .background(Color(0xff10BBE5))
        .clickable {
            targetHeight = contentHeight.coerceAtMost(targetHeight + 200.dp)

            if (targetHeight == contentHeight) {
                targetHeight = 100.dp
            }
        }
)

물을 표현하는 박스를 클릭할 때마다 200.dp씩 높이가 커지고 전체 화면의 높이에 도달하면 다시 초기값으로 돌아오도록 하였다.

Height 변경 애니메이션 적용하기

var targetHeight by remember {
    mutableStateOf(100.dp)
}
val height by animateDpAsState(
    targetValue = targetHeight,
    animationSpec = spring(
        dampingRatio = Spring.DampingRatioMediumBouncy,
        stiffness = Spring.StiffnessLow
    ),
    label = "waterHeight"
)

animateDpAsState를 이용하여 변경된 targetHeight까지 애니메이션을 적용하여 크기가 커지도록 하였다.

spring

물이 차오르는 것처럼 바운스 효과를 주고 싶어서 spring을 이용하였다. 다양한 효과 옵션은 여기에 가면 볼 수 있다.
간단하게 말하자면 damipingRatio은 바운스되는 정도, stiffness는 목적지까지 도달하는 부드러움의 정도이다. damping이 낮아질수록 바운스가 많이 되고 stiffness가 낮아질수록 부드럽게 이동한다.

최종결과

전체코드

@Composable
fun WaterFill() {

    var contentHeight by remember {
        mutableStateOf(0.dp)
    }

    Column(modifier = Modifier.onGloballyPositioned {
        contentHeight = it.size.height.toDp()
    }, verticalArrangement = Arrangement.Bottom) {

        var targetHeight by remember {
            mutableStateOf(100.dp)
        }
        val height by animateDpAsState(
            targetValue = targetHeight,
            animationSpec = spring(
                dampingRatio = Spring.DampingRatioMediumBouncy,
                stiffness = Spring.StiffnessLow
            ), label = "waterHeight"
        )

        Box(
            modifier = Modifier
                .fillMaxWidth()
                .height(height)
                .background(Color(0xff10BBE5))
                .clickable {
                    targetHeight = contentHeight.coerceAtMost(targetHeight + 200.dp)

                    if (targetHeight == contentHeight) {
                        targetHeight = 100.dp
                    }
                }
        )
    }
}

fun Int.toDp(): Dp = (this / Resources.getSystem().displayMetrics.density).dp

깃헙링크

https://github.com/uuranus/compose-animation-playground

profile
Frontend Developer

0개의 댓글