|
import androidx.compose.animation.AnimatedVisibility |
|
import androidx.compose.animation.core.animateDpAsState |
|
import androidx.compose.animation.core.animateFloatAsState |
|
import androidx.compose.animation.core.tween |
|
import androidx.compose.animation.fadeIn |
|
import androidx.compose.animation.fadeOut |
|
import androidx.compose.animation.scaleIn |
|
import androidx.compose.animation.scaleOut |
|
import androidx.compose.foundation.Canvas |
|
import androidx.compose.foundation.Image |
|
import androidx.compose.foundation.clickable |
|
import androidx.compose.foundation.layout.* |
|
import androidx.compose.foundation.shape.RoundedCornerShape |
|
import androidx.compose.material3.* |
|
import androidx.compose.runtime.* |
|
import androidx.compose.ui.Alignment |
|
import androidx.compose.ui.Modifier |
|
import androidx.compose.ui.draw.clip |
|
import androidx.compose.ui.geometry.Offset |
|
import androidx.compose.ui.geometry.Size |
|
import androidx.compose.ui.graphics.Color |
|
import androidx.compose.ui.graphics.drawscope.Stroke |
|
import androidx.compose.ui.graphics.graphicsLayer |
|
import androidx.compose.ui.layout.ContentScale |
|
import androidx.compose.ui.res.painterResource |
|
import androidx.compose.ui.text.font.FontWeight |
|
import androidx.compose.ui.text.style.TextAlign |
|
import androidx.compose.ui.text.style.TextDecoration |
|
import androidx.compose.ui.unit.dp |
|
import androidx.compose.ui.unit.sp |
|
import com.example.pikachudiscountcard.R |
|
import kotlinx.coroutines.delay |
|
|
|
@Composable |
|
fun FlipPokeball() { |
|
var isOpen by remember { mutableStateOf(false) } |
|
var hideBall by remember { mutableStateOf(false) } |
|
var showCard by remember { mutableStateOf(false) } |
|
|
|
val angle by animateFloatAsState( |
|
targetValue = if (isOpen) 90f else 0f, |
|
animationSpec = tween(durationMillis = 600), |
|
label = "angleAnim" |
|
) |
|
|
|
val ballAlpha by animateFloatAsState( |
|
targetValue = if (hideBall) 0f else 1f, |
|
animationSpec = tween(durationMillis = 600), |
|
label = "alphaAnim" |
|
) |
|
|
|
val cardOffset by animateDpAsState( |
|
targetValue = if (hideBall) 0.dp else 60.dp, |
|
animationSpec = tween(durationMillis = 600), |
|
label = "cardOffsetAnim" |
|
) |
|
|
|
Column(horizontalAlignment = Alignment.CenterHorizontally) { |
|
Box(modifier = Modifier |
|
.clickable { |
|
if (!isOpen) { |
|
isOpen = true |
|
} |
|
}) { |
|
if (!hideBall) { |
|
Canvas(modifier = Modifier.size(200.dp).graphicsLayer { alpha = ballAlpha }) { |
|
val canvasSize = size.minDimension |
|
val radius = canvasSize / 2 |
|
val center = Offset(size.width / 2, size.height / 2) |
|
|
|
drawArc( |
|
color = Color.Red, |
|
startAngle = 180f - angle, |
|
sweepAngle = 180f, |
|
useCenter = true, |
|
topLeft = Offset(center.x - radius, center.y - radius), |
|
size = Size(radius * 2, radius * 2) |
|
) |
|
|
|
drawArc( |
|
color = Color.White, |
|
startAngle = 0f - angle, |
|
sweepAngle = 180f, |
|
useCenter = true, |
|
topLeft = Offset(center.x - radius, center.y - radius), |
|
size = Size(radius * 2, radius * 2) |
|
) |
|
|
|
val angleRad = Math.toRadians(angle.toDouble()).toFloat() |
|
val dx = radius * kotlin.math.cos(angleRad) |
|
val dy = radius * kotlin.math.sin(angleRad) |
|
|
|
drawLine( |
|
color = Color.Black, |
|
start = Offset(center.x - dx, center.y + dy), |
|
end = Offset(center.x + dx, center.y - dy), |
|
strokeWidth = 17f |
|
) |
|
|
|
drawCircle( |
|
color = Color.White, |
|
radius = radius / 5, |
|
center = center |
|
) |
|
drawCircle( |
|
color = Color.Black, |
|
radius = radius / 5, |
|
center = center, |
|
style = Stroke(width = 17f) |
|
) |
|
} |
|
} |
|
} |
|
|
|
LaunchedEffect(isOpen) { |
|
if (isOpen) { |
|
delay(1000) |
|
hideBall = true |
|
} |
|
} |
|
|
|
LaunchedEffect(hideBall) { |
|
if (hideBall) { |
|
delay(1) |
|
showCard = true |
|
} |
|
} |
|
|
|
if (isOpen) { |
|
Spacer(modifier = Modifier.height(cardOffset)) |
|
AnimatedVisibility( |
|
visible = showCard, |
|
enter = fadeIn(tween(500)) + scaleIn(tween(500)), |
|
exit = fadeOut(tween(500)) + scaleOut(tween(500)) |
|
) { |
|
Box(modifier = Modifier.clickable { |
|
showCard = false |
|
hideBall = false |
|
isOpen = false |
|
}) { |
|
PikachuCard() |
|
} |
|
} |
|
} |
|
} |
|
} |
|
|
|
@Composable |
|
fun PikachuCard() { |
|
Surface( |
|
modifier = Modifier |
|
.width(280.dp) |
|
.height(180.dp) |
|
.clip(RoundedCornerShape(16.dp)), |
|
color = Color.White, |
|
shadowElevation = 4.dp |
|
) { |
|
Row( |
|
modifier = Modifier |
|
.fillMaxSize() |
|
.padding(12.dp), |
|
verticalAlignment = Alignment.CenterVertically, |
|
horizontalArrangement = Arrangement.SpaceBetween |
|
) { |
|
Image( |
|
painter = painterResource(id = R.drawable.pikachu), |
|
contentDescription = "Pikachu", |
|
contentScale = ContentScale.Fit, |
|
modifier = Modifier.size(100.dp) |
|
) |
|
Column(verticalArrangement = Arrangement.Center) { |
|
Text("SPECIAL OFFER", fontSize = 12.sp, color = Color.Gray) |
|
Text("Pikachu", fontWeight = FontWeight.Bold, fontSize = 18.sp) |
|
Row(verticalAlignment = Alignment.CenterVertically) { |
|
Text("50$", fontSize = 14.sp, color = Color.Gray, textAlign = TextAlign.Start, textDecoration = TextDecoration.LineThrough) |
|
Spacer(modifier = Modifier.width(6.dp)) |
|
Text("39$", fontSize = 16.sp, color = Color.Red, fontWeight = FontWeight.Bold) |
|
} |
|
Spacer(modifier = Modifier.height(4.dp)) |
|
Button(onClick = {}, colors = ButtonDefaults.buttonColors(containerColor = Color(0xFFFFD700))) { |
|
Text("GET THIS OFFER", color = Color.Black) |
|
} |
|
} |
|
} |
|
} |
|
} |