Skip to content

Commit

Permalink
Merge pull request #35014 from janicduplessis/@janic/camera-fixes
Browse files Browse the repository at this point in the history
Add tap to focus and fix orientation
  • Loading branch information
mountiny authored Feb 2, 2024
2 parents 02d8a0a + 3fb005d commit d968010
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 10 deletions.
61 changes: 51 additions & 10 deletions src/pages/iou/request/step/IOURequestStepScan/index.native.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import lodashGet from 'lodash/get';
import React, {useCallback, useEffect, useRef, useState} from 'react';
import {ActivityIndicator, Alert, AppState, View} from 'react-native';
import {Gesture, GestureDetector} from 'react-native-gesture-handler';
import {RESULTS} from 'react-native-permissions';
import Animated, {runOnJS, useAnimatedStyle, useSharedValue, withDelay, withSequence, withSpring, withTiming} from 'react-native-reanimated';
import {useCameraDevices} from 'react-native-vision-camera';
import Hand from '@assets/images/hand.svg';
import Shutter from '@assets/images/shutter.svg';
Expand Down Expand Up @@ -66,6 +68,41 @@ function IOURequestStepScan({

const {translate} = useLocalize();

const focusIndicatorOpacity = useSharedValue(0);
const focusIndicatorScale = useSharedValue(2);
const focusIndicatorPosition = useSharedValue({x: 0, y: 0});

const cameraFocusIndicatorAnimatedStyle = useAnimatedStyle(() => ({
opacity: focusIndicatorOpacity.value,
transform: [{translateX: focusIndicatorPosition.value.x}, {translateY: focusIndicatorPosition.value.y}, {scale: focusIndicatorScale.value}],
}));

const focusCamera = (point) => {
if (!camera.current) {
return;
}

camera.current.focus(point).catch((ex) => {
if (ex.message === '[unknown/unknown] Cancelled by another startFocusAndMetering()') {
return;
}
Log.warn('Error focusing camera', ex);
});
};

const tapGesture = Gesture.Tap()
.enabled(device && device.supportsFocus)
.onStart((ev) => {
const point = {x: ev.x, y: ev.y};

focusIndicatorOpacity.value = withSequence(withTiming(0.8, {duration: 250}), withDelay(1000, withTiming(0, {duration: 250})));
focusIndicatorScale.value = 2;
focusIndicatorScale.value = withSpring(1, {damping: 10, stiffness: 200});
focusIndicatorPosition.value = point;

runOnJS(focusCamera)(point);
});

useEffect(() => {
const refreshCameraPermissionStatus = () => {
CameraPermission.getCameraPermissionStatus()
Expand Down Expand Up @@ -256,16 +293,20 @@ function IOURequestStepScan({
)}
{cameraPermissionStatus === RESULTS.GRANTED && device != null && (
<View style={[styles.cameraView]}>
<View style={styles.flex1}>
<NavigationAwareCamera
ref={camera}
device={device}
style={[styles.flex1]}
zoom={device.neutralZoom}
photo
cameraTabIndex={1}
/>
</View>
<GestureDetector gesture={tapGesture}>
<View style={styles.flex1}>
<NavigationAwareCamera
ref={camera}
device={device}
style={[styles.flex1]}
zoom={device.neutralZoom}
photo
cameraTabIndex={1}
orientation="portrait"
/>
<Animated.View style={[styles.cameraFocusIndicator, cameraFocusIndicatorAnimatedStyle]} />
</View>
</GestureDetector>
</View>
)}
<View style={[styles.flexRow, styles.justifyContentAround, styles.alignItemsCenter, styles.pv3]}>
Expand Down
12 changes: 12 additions & 0 deletions src/styles/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -866,6 +866,18 @@ const styles = (theme: ThemeColors) =>
justifyItems: 'center',
},

cameraFocusIndicator: {
position: 'absolute',
left: -32,
top: -32,
width: 64,
height: 64,
borderRadius: 32,
borderWidth: 2,
borderColor: theme.white,
pointerEvents: 'none',
},

permissionView: {
paddingVertical: 108,
paddingHorizontal: 61,
Expand Down

0 comments on commit d968010

Please sign in to comment.