I'm building a RN app using Expo, which uses expo-camera's Camera component. I'm trying to implement zoom on pinch functionality, which basically is computing a number between 0 (no zoom) and 1 (max zoom) based on the gesture.
MRE: https://snack.expo.dev/@fpicoral/expo-camera-zoom
// from https://stackoverflow.com/a/72524084/10893256
const onPinch = useCallback((event: GestureUpdateEvent<PinchGestureHandlerEventPayload>) => {
const velocity = event.velocity / 20;
let newZoom =
velocity > 0
? zoom + event.scale * velocity * (Platform.OS === 'ios' ? 0.01 : 25)
: zoom - event.scale * Math.abs(velocity) * (Platform.OS === 'ios' ? 0.02 : 50);
if (newZoom < 0) newZoom = 0;
else if (newZoom > 0.5) newZoom = 0.5;
setZoom(newZoom);
},
[zoom, setZoom]
);
This is working decently well, but the problem is zooming out. If you never let your fingers off the screen, everything is smooth. However, if you zoom in a lot, lift your fingers, and try to zoom out, it takes a lot of pinches to zoom out properly.
This problem is related to the fact that event.scale will be too small if the user stops the gesture after zooming in. I tried to keep track of the cumulative scale, resetting it when the gesture swapped between zoom in and zoom out, but it didn't help either.
EDIT: It's working decently well on iOS only. On Android, even with the multiplier, it's not zooming in almost at all. When I kept track of the cumulative sum, both iOS and Android had the same behavior, but the problem of zooming out was still present in both platforms.
I've had the same problem with zooming out. I solved it by adding zoom out factor depending on the last zoom (bigger zoom = bigger factor):
hope it helps