How do I calcuate zoom from pinch event using expo camera?

1.7k Views Asked by At

As far as I googled, zooming with two fingers is called pinch gesture (correct me if I am wrong). Also, as per this question I have to use PinchGestureHandler from react-native-gesture-handler library in order to detect this gesture. Again, as suggested via one of the answers, I need to use:

<PinchGestureHandler
    onGestureEvent={this.onPinchGestureEvent}
  >
    <View>
          <Camera
              type={cameraType}
              flashMode={flashMode}
              //I need to set my zoom here
              zoom={zoom}
              style={styles.preview}
              ref={camera => this.camera = camera}
          />
    </View>
        </PinchGestureHandler>

onPinchGestureEvent = event => {
      console.log(event.nativeEvent.scale);
      //somehow I need to set my zoom here
    }

When I console.log(event.nativeEvent) from my onPinchGestureEvent method I get the following output:

onPinchGestureEvent event:  Object {
  "focalX": 216.5,
  "focalY": 212.5,
  "handlerTag": 8,
  "numberOfPointers": 2,
  "scale": 0.6020446981019169,
  "state": 4,
  "velocity": -0.0031890643353418226,
}

I tried to set up my zoom based on the scale:

const onPinchGestureEvent = (event) => {
    if (event.nativeEvent.scale >= 1) {
      setZoom(1);
    } else if (event.nativeEvent.scale <= 0) {
      setZoom(0);
    } else {
      setZoom(event.nativeEvent.scale);
    }
  };

But it didnt give me smooth results, also I can not zoom out. There is this question too which essentially is the same, but no one answered. According to this blog I need something like the following:

calculateZoom(touch0x, touch0y, touch1x, touch1y) {
    const x = touch0x - touch1x;
    const y = touch0y - touch1y;

    const distance = Math.pow(x, 2) + Math.pow(y, 2);
    
    return Math.sqrt(distance);
  }

but from my console.log(event.nativeEvent) I have only one focalX and one focalY value.

Any suggestions, blogs, ideas will be grant!

1

There are 1 best solutions below

1
On

This is my proposed solution

const onPinchGestureEvent = (nativeEvent) => {
 var scale = nativeEvent.nativeEvent.scale
 var velocity = nativeEvent.nativeEvent.velocity / 20

  let newZoom =
  velocity > 0
  ? zoom + scale * velocity * (Platform.OS === "ios" ? 0.01 : 25)
  : zoom -
    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)
};