Separate each Android gallery swipe from pinch and pan gestures
This commit is contained in:
1 parent
3f4df4233b
commit
cee3228e5f
1 file changed
+21
-7
+21
-7
@@ -2,7 +2,11 @@ package com.utun.chat.ui.components
|
||||
|
||||
import android.graphics.Bitmap
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.gestures.detectTransformGestures
|
||||
import androidx.compose.foundation.gestures.awaitEachGesture
|
||||
import androidx.compose.foundation.gestures.awaitFirstDown
|
||||
import androidx.compose.foundation.gestures.calculateCentroid
|
||||
import androidx.compose.foundation.gestures.calculatePan
|
||||
import androidx.compose.foundation.gestures.calculateZoom
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.BoxWithConstraints
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
@@ -12,6 +16,7 @@ import androidx.compose.ui.geometry.Offset
|
||||
import androidx.compose.ui.graphics.asImageBitmap
|
||||
import androidx.compose.ui.graphics.graphicsLayer
|
||||
import androidx.compose.ui.input.pointer.pointerInput
|
||||
import androidx.compose.ui.input.pointer.positionChanged
|
||||
import androidx.compose.ui.layout.ContentScale
|
||||
import androidx.compose.ui.platform.LocalDensity
|
||||
|
||||
@@ -31,6 +36,7 @@ fun ZoomableImage(bitmap: Bitmap, modifier: Modifier = Modifier, contentScale: C
|
||||
onSwipe: ((Int) -> Unit)? = null) {
|
||||
var zoomScale by remember(bitmap) { mutableStateOf(1f) }
|
||||
var zoomOffset by remember(bitmap) { mutableStateOf(Offset.Zero) }
|
||||
val navigate by rememberUpdatedState(onSwipe)
|
||||
|
||||
BoxWithConstraints(modifier) {
|
||||
val density = LocalDensity.current
|
||||
@@ -60,13 +66,19 @@ fun ZoomableImage(bitmap: Bitmap, modifier: Modifier = Modifier, contentScale: C
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.pointerInput(bitmap,cW,cH,onSwipe) {
|
||||
var swipe=0f
|
||||
detectTransformGestures { centroid, pan, zoom, _ ->
|
||||
if (onSwipe!=null && zoomScale==1f && zoom==1f && kotlin.math.abs(pan.x)>kotlin.math.abs(pan.y)) {
|
||||
.pointerInput(bitmap,cW,cH) {
|
||||
awaitEachGesture {
|
||||
awaitFirstDown(requireUnconsumed=false)
|
||||
var swipe=0f; var swiped=false; var canSwipe=zoomScale==1f
|
||||
do {
|
||||
val event=awaitPointerEvent()
|
||||
val centroid=event.calculateCentroid(useCurrent=false)
|
||||
val pan=event.calculatePan(); val zoom=event.calculateZoom()
|
||||
if (event.changes.count { it.pressed }!=1 || zoom!=1f) canSwipe=false
|
||||
if (canSwipe && !swiped && navigate!=null && kotlin.math.abs(pan.x)>kotlin.math.abs(pan.y)) {
|
||||
swipe+=pan.x
|
||||
if (kotlin.math.abs(swipe)>96*density.density) { onSwipe(if (swipe<0) 1 else -1); swipe=0f }
|
||||
} else swipe=0f
|
||||
if (kotlin.math.abs(swipe)>96*density.density) { navigate?.invoke(if (swipe<0) 1 else -1); swiped=true }
|
||||
}
|
||||
val old = zoomScale
|
||||
val new = (zoomScale * zoom).coerceIn(1f, MAX_ZOOM)
|
||||
val z = new / old
|
||||
@@ -77,6 +89,8 @@ fun ZoomableImage(bitmap: Bitmap, modifier: Modifier = Modifier, contentScale: C
|
||||
)
|
||||
zoomScale = new
|
||||
zoomOffset = clampOffset(new, raw, cW, cH, iw, ih)
|
||||
if (zoom!=1f || pan!=Offset.Zero) event.changes.forEach { if (it.positionChanged()) it.consume() }
|
||||
} while (event.changes.any { it.pressed })
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
Reference in new issue
Block a user