Open gmikhail opened 4 months ago
I've been wanting to do this, but haven't been able to find time yet. Wanna help me out? 🙂
We can add a PanSpec
class along the lines of ZoomSpec.
Next week I'll try to see how it's done in Subsampling Scale Image View.
I haven't looked at the Telephoto source code yet, so I'm not sure how long it will take to implement this functionality.
I made a working implementation of this feature using Coil. The implementation itself is quite simple. We calculate the available boundaries and then constrain the offset
within them.
var imageWidth by remember { mutableIntStateOf(0) }
var imageHeight by remember { mutableIntStateOf(0) }
var zoom by remember { mutableFloatStateOf(1f) }
var offsetX by remember { mutableFloatStateOf(0f) }
var offsetY by remember { mutableFloatStateOf(0f) }
val minScale = 1f
val maxScale = 5f
// Gesture container
Box(
modifier = Modifier
.fillMaxSize()
.checkerboardBackground()
.pointerInput(Unit) {
detectTransformGestures(
onGesture = { _, pan, gestureZoom, _ ->
zoom = (zoom * gestureZoom).coerceIn(minScale, maxScale)
// --- PAN_LIMIT_CENTER implementation start ---
val imageWidthHalf = (imageWidth / 2f) * zoom
val imageHeightHalf = (imageHeight / 2f) * zoom
val newOffsetX = offsetX + pan.x
val newOffsetY = offsetY + pan.y
offsetX = newOffsetX.coerceIn(-imageWidthHalf, imageWidthHalf)
offsetY = newOffsetY.coerceIn(-imageHeightHalf, imageHeightHalf)
// --- PAN_LIMIT_CENTER implementation end ---
LogUtil.log(TAG, "offsetX = $offsetX, offsetY = $offsetY")
}
)
}
contentAlignment = Alignment.Center
) {
// Image
AsyncImage(
model = ImageRequest.Builder(LocalContext.current)
.data(uri)
.listener(
onSuccess = { _, result ->
val bitmap = result.drawable.toBitmap()
imageWidth = bitmap.width
imageHeight = bitmap.height
// TODO work with bitmap
}
)
.build(),
contentDescription = null,
modifier = Modifier
.graphicsLayer(
scaleX = zoom,
scaleY = zoom,
translationX = offsetX,
translationY = offsetY,
)
)
}
Could you help with integration into Telephoto?
I want to achieve this behavior:
https://github.com/saket/telephoto/assets/4838367/1d29b3d5-0e43-45fe-9b93-4af06923cf3b
How can I do it?
In Subsampling Scale Image View I only have to
setPanLimit(SubsamplingScaleImageView.PAN_LIMIT_CENTER)
for this.