예시 영상은 티스토리 버그로 동영상 첨부가 안되어, 파일로 첨부합니다.
@Composable
fun ZoomableBox(
modifier: Modifier = Modifier,
enableRotation: Boolean = false,
minScale: Float = 0.5f,
maxScale: Float = 3f,
content: @Composable ZoomableBoxScope.() -> Unit
) {
var rotationZ by remember { mutableStateOf(0f) }
var scale by remember { mutableStateOf(1f) }
var offsetX by remember { mutableStateOf(0f) }
var offsetY by remember { mutableStateOf(0f) }
var size by remember { mutableStateOf(IntSize.Zero) }
Box(
modifier = modifier
.clip(RectangleShape)
.onSizeChanged { size = it }
.pointerInput(Unit) {
detectTransformGestures { _, pan, zoom, rotation ->
scale = maxOf(minScale, minOf(scale * zoom, maxScale))
if (scale > 1f) {
val maxX = (size.width * (scale - 1)) / 2
val minX = -maxX
offsetX = maxOf(minX, minOf(maxX, offsetX + pan.x))
val maxY = (size.height * (scale - 1)) / 2
val minY = -maxY
offsetY = maxOf(minY, minOf(maxY, offsetY + pan.y))
}
if (enableRotation) {
rotationZ += rotation
}
}
}
) {
ZoomableBoxScopeImpl(scale, offsetX, offsetY, rotationZ).content()
}
}
interface ZoomableBoxScope {
val scale: Float
val offsetX: Float
val offsetY: Float
val rotationZ: Float
}
private data class ZoomableBoxScopeImpl(
override val scale: Float,
override val offsetX: Float,
override val offsetY: Float,
override val rotationZ: Float
) : ZoomableBoxScope
사용 예시
ZoomableBox(enableRotation = true) {
AsyncImage(
contentScale = ContentScale.FillHeight,
modifier = Modifier
.fillMaxSize()
.graphicsLayer(
scaleX = scale,
scaleY = scale,
translationX = offsetX,
translationY = offsetY,
rotationZ = rotationZ
),
model = "${BuildConfig.TMDB_IMAGE_ORIGINAL_URL}${movieImageModel.posters[page].filePath}",
placeholder = rememberAsyncImagePainter(model = LoadingView(modifier = Modifier.fillMaxSize())),
contentDescription = "DetailMovieImage"
)
}
혹시나 필요하신 분이 계실까 싶어 올려둡니다 :)
그럼 20000!
'Android > Development Tips' 카테고리의 다른 글
Compose. StateFlow + List 를 활용하여 Recomposition 할 때 Tips (0) | 2023.06.06 |
---|---|
Summary MVI 직접 작성 해야/하지 않아야 하는 이유 (0) | 2023.01.05 |
간단 Tips. FrameLayout 위에 Fragment 를 올리는 것보다 FragmentContainerView 에 Fragment 를 올리는 것이 안전한 이유 (0) | 2022.11.30 |
간단 Tips. Lottie 에서 Url 을 통해 로드할 때, Unable to parse composition 에러가 발생한다면 ? (0) | 2022.11.30 |
간단 Tips. 코루틴 SupervisorJob 또는 SupervisorScope 를 사용해야 하는 경우 (0) | 2022.11.29 |