Skip to content

Instantly share code, notes, and snippets.

@junsuk5
Created January 21, 2025 11:49
Show Gist options
  • Save junsuk5/c35b58f221ca182cd1b4965b2e3abbed to your computer and use it in GitHub Desktop.
Save junsuk5/c35b58f221ca182cd1b4965b2e3abbed to your computer and use it in GitHub Desktop.
PageCurlDemo.kt
@Composable
fun BookPageFlip() {
var offsetX by remember { mutableStateOf(0f) }
var currentPage by remember { mutableStateOf(0) }
val animatedOffset = animateFloatAsState(
targetValue = offsetX,
animationSpec = spring(
dampingRatio = 0.8f,
stiffness = Spring.StiffnessLow
)
)
Box(
modifier = Modifier
.fillMaxSize()
.pointerInput(Unit) {
detectDragGestures(
onDragEnd = {
// 드래그가 끝났을 때 페이지 전환 여부 결정
val threshold = size.width * 0.4f
if (abs(offsetX) > threshold) {
if (offsetX > 0 && currentPage > 0) {
currentPage--
} else if (offsetX < 0) {
currentPage++
}
}
offsetX = 0f
},
onDrag = { change, dragAmount ->
change.consume()
offsetX += dragAmount.x
}
)
}
) {
// 현재 페이지
Box(
modifier = Modifier
.fillMaxSize()
.graphicsLayer {
val pageRotation = (offsetX / size.width) * 180f
rotationY = pageRotation
cameraDistance = 12f * density
}
) {
BookPage(currentPage)
}
// 다음/이전 페이지 (뒷면)
Box(
modifier = Modifier
.fillMaxSize()
.graphicsLayer {
val pageRotation = ((offsetX / size.width) * 180f) + 180f
rotationY = pageRotation
cameraDistance = 12f * density
}
) {
if (offsetX > 0 && currentPage > 0) {
BookPage(currentPage - 1)
} else if (offsetX < 0) {
BookPage(currentPage + 1)
}
}
}
}
@Composable
fun BookPage(pageNumber: Int) {
Box(
modifier = Modifier
.fillMaxSize()
.background(Color.White)
.shadow(8.dp)
) {
// 페이지 내용
Column(
modifier = Modifier
.fillMaxSize()
.padding(16.dp)
) {
Text(
text = "Page ${pageNumber + 1}",
style = MaterialTheme.typography.bodyLarge,
modifier = Modifier.padding(bottom = 16.dp)
)
Text(
text = "Lorem ipsum dolor sit amet...",
style = MaterialTheme.typography.bodyMedium
)
}
}
}
// 페이지 그림자 효과
@Composable
fun PageShadow(progress: Float) {
Box(
modifier = Modifier
.fillMaxHeight()
.width(8.dp)
.background(
brush = Brush.horizontalGradient(
colors = listOf(
Color.Black.copy(alpha = 0.2f * (1 - progress)),
Color.Transparent
)
)
)
)
}
// 사용 예시
@Preview(showBackground = true)
@Composable
fun BookReader() {
Surface(
modifier = Modifier.fillMaxSize().systemBarsPadding(),
color = Color.White
) {
BookPageFlip()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment