UNPKG

@hashiprobr/expo-camera

Version:

A modified version of expo-camera with automatic ratio in Android and additional configurability

141 lines (123 loc) 3.92 kB
import React, { forwardRef, useState } from 'react'; import hoistNonReactStatics from 'hoist-non-react-statics'; import { Platform, View } from 'react-native'; import { Camera as OriginalCamera } from 'expo-camera'; import { useUpdate } from '@hashiprobr/react-use-mount-and-update'; import AndroidCamera from './AndroidCamera'; const Camera = forwardRef((props, ref) => { const [width, setWidth] = useState(0); const [height, setHeight] = useState(0); const [basis, setBasis] = useState(0); function onViewLayout({ nativeEvent }) { setWidth(nativeEvent.layout.width); setHeight(nativeEvent.layout.height); if (onLayout) { onLayout({ nativeEvent }); } } useUpdate(() => { if (width > 0 && height > 0) { let large; let small; if (width < height) { large = height; small = width; } else { large = width; small = height; } setBasis((large - small) / 2); } else { setBasis(0); } }, [width, height]); const style = { ...props.style }; const { onLayout, children, ...childless } = props; childless.style = { flexGrow: 1, }; childless.ref = ref; const cropStyle = { flexBasis: basis, backgroundColor: props.cropColor || '#000000', opacity: props.cropAlpha || 0.5, }; return ( <View style={{ ...props.viewStyle, flexGrow: style.flexGrow, alignSelf: style.alignSelf, flexDirection: 'column', flexWrap: 'nowrap', justifyContent: 'flex-start', alignItems: 'stretch', margin: style.margin, marginTop: style.marginTop, marginRight: style.marginRight, marginBottom: style.marginBottom, marginLeft: style.marginLeft, padding: 0, paddingTop: 0, paddingRight: 0, paddingBottom: 0, paddingLeft: 0, overflow: 'visible', }} onLayout={onViewLayout} > {Platform.OS === 'android' ? ( <AndroidCamera {...childless} /> ) : ( <OriginalCamera {...childless} /> )} {props.crop && ( <View style={{ flexGrow: 1, flexDirection: width < height ? 'column' : 'row', justifyContent: 'space-between', position: 'absolute', top: 0, right: 0, bottom: 0, left: 0, }} > <View style={cropStyle} /> <View style={cropStyle} /> </View> )} <View style={{ ...style, flexGrow: 1, alignSelf: 'stretch', position: 'absolute', top: 0, right: 0, bottom: 0, left: 0, margin: 0, marginTop: 0, marginRight: 0, marginBottom: 0, marginLeft: 0, }} > {children} </View> </View> ); }); hoistNonReactStatics(Camera, OriginalCamera); Camera.displayName = 'Camera'; export default Camera;