package com.suno.android.ui.screens.hooks.overlay import androidx.compose.animation.core.Animatable import androidx.compose.animation.core.FastOutSlowInEasing import androidx.compose.animation.core.Spring import androidx.compose.animation.core.spring import androidx.compose.animation.core.tween import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.offset import androidx.compose.foundation.layout.size import androidx.compose.material3.Icon import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.graphicsLayer import androidx.compose.ui.res.painterResource import androidx.compose.ui.unit.IntOffset import androidx.compose.ui.unit.dp import com.suno.android.common_ui.R import com.suno.android.common_ui.theme.SunoPink import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.delay import kotlinx.coroutines.launch import kotlin.math.roundToInt private const val HEART_SIZE_DP = 64 private const val UPWARD_MOVEMENT_DELAY_MS = 600 private const val UPWARD_MOVEMENT_DURATION_MS = 1000 private const val FADE_OUT_DELAY_MS = 700 private const val FADE_OUT_DURATION_MS = 300 @Composable fun AnimatedHeart( modifier: Modifier = Modifier, onAnimationComplete: () -> Unit = {}, ) { val scale = remember { Animatable(0f) } val yOffset = remember { Animatable(0f) } val opacity = remember { Animatable(1f) } LaunchedEffect(Unit) { coroutineScope { launch { scale.animateTo( targetValue = 1f, animationSpec = spring( dampingRatio = Spring.DampingRatioMediumBouncy, stiffness = Spring.StiffnessLow, ), ) } launch { delay(UPWARD_MOVEMENT_DELAY_MS.toLong()) yOffset.animateTo( targetValue = -2000f, animationSpec = tween( durationMillis = UPWARD_MOVEMENT_DURATION_MS, easing = FastOutSlowInEasing, ), ) } launch { delay(FADE_OUT_DELAY_MS.toLong()) opacity.animateTo( targetValue = 0f, animationSpec = tween( durationMillis = FADE_OUT_DURATION_MS, easing = FastOutSlowInEasing, ), ) onAnimationComplete() } } } Box( modifier = modifier .offset { IntOffset( x = 0, y = yOffset.value.roundToInt(), ) } .graphicsLayer( scaleX = scale.value, scaleY = scale.value, alpha = opacity.value, ), contentAlignment = Alignment.Center, ) { Icon( painter = painterResource(R.drawable.heart_v2), contentDescription = null, tint = SunoPink, modifier = Modifier.size(HEART_SIZE_DP.dp), ) } }