Reputation:
Image zoom like of Instagram in jetpack compose if anyone can help
I want something like this https://drive.google.com/file/d/18a7SaPIoSObbvrmYxJ0GDhHXEETKpsEV/view?usp=drivesdk
Upvotes: 3
Views: 8303
Reputation: 341
1- Save the scale as a state
var scale by remember { mutableStateOf(1f) }
2- Set the scale of your image to use this state. I recommend using graphicsLayer to set the scale in order to minimize the invalidated content, and add any other transformations you want like the following
Image(
...,
modifier = Modifier
.graphicsLayer(
scaleX = scale,
scaleY = scale
)
)
3- Use Modifier.pointerInput
to detect and apply the zoom effect. with the PointerInputScope you can detect tabs and transformations namely (zoom, rotation and pan). For example you can add the following to detect zoom gestures and modify the scale accordingly.
modifier = Modifier
.pointerInput(Unit) {
detectTransformGestures { _, _, zoom, _ ->
scale = (scale * zoom).coerceIn(0.5f, 3f)
}
}
The other parameters of detectTransformGestures
are centroid, pan and rotation. You don't need them for the zoom transformation but you will if you tried to apply rotation and translation.
If you want to apply the zoom using pan gesture you can use the detectTapGestures
. Here is an example.
modifier = Modifier
.pointerInput(Unit) {
detectTapGestures(
onDoubleTap = {
scale = if (scale > 2f) 1f else 3f
}
)
}
Here is a complete sample using CoilImage. The implementation should be the same for any other Image
@Composable fun SamplePreview(imageUrl: String) {
var scale by remember { mutableStateOf(1f) }
Box {
CoilImage(
data = imageUrl,
contentDescription = null,
contentScale = ContentScale.FillWidth,
modifier = Modifier
.align(Alignment.Center)
.graphicsLayer(
scaleX = scale,
scaleY = scale
)
.pointerInput(Unit) {
detectTransformGestures { _, _, zoom, _ ->
scale = (scale * zoom).coerceIn(0.5f, 3f)
}
}
) {
CircularProgressIndicator()
}
}
Upvotes: 13
Reputation: 9
Did you make any progress? I am able to zoom the image, but I can't restore the image to the original size when user terminates the gesture.
To zoom the image what I did was:
Created a scale and state variables. The if(scale < 1)
is to not let the user minimize the image.
var scale by remember { mutableStateOf(1f) }
val state = rememberTransformableState { zoomChange, _, _ ->
scale *= zoomChange
if(scale < 1){
scale = 1F
}
}
In the image, I used the graphicsLayer and the transformable.
.graphicsLayer{
scaleX = scale;
scaleY = scale
}
.transformable(state = state)
I tried to capture the MotionEvent of the user, but didn't find a MotionEvent that observed the pinch gesture.
Also, in the .pointerInput
I can't use detectTapGestures
and detectTransformGestures
together, because the pointer just considers one.
Upvotes: 0