How to add a mask on top of the react-native-camera?
I'm building the UI for a React Native QRCode scanner app using react-native-camera.
The overlay mask on top of the camera should be in light grey color, but the middle part must keep transparent (see-through).
But when I change the backgroundColor on my outer mask, it seems also affect the center part. I mean, of course, it is behind its child view.
The code down below is a simplified version of the snapshot.
<Camera
ref={cam => {
this.camera = cam;
}}
onBarCodeRead={this._onBarCodeRead}
style={styles.cameraView}
aspect={Camera.constants.Aspect.fill}
playSoundOnCapture
>
<View
style={{
position: 'absolute',
top: 0,
left: 0,
width: '100%',
height: '100%',
backgroundColor: 'rgba(0.2, 0.2, 0.2, 0.2)',
alignItems: 'center',
justifyContent: 'space-around',
}}
>
<View
style={{
width: 300,
height: 300,
backgroundColor: 'transparent',
borderColor: 'white',
borderWidth: 1,
}}
/>
</View>
</Camera>
Any idea how to get this done?
I finally figure out this one. The idea is to create 3 rows like a burger and then calculate the height and width at runtime.
The center row has 3 view components, the middle one has a transparent background and white border.
(the value, 300, comes from the size of the center view (transparent area), I divided it by 10 to compute a smaller ratio for flexboxes)
export default class CameraScreen extends React.Component<any, any> {
render() {
const { height, width } = Dimensions.get('window');
const maskRowHeight = Math.round((AppStore.height - 300) / 20);
const maskColWidth = (width - 300) / 2;
return (
<View style={styles.container}>
<Camera
ref={cam => {
this.camera = cam;
}}
onBarCodeRead={this._onBarCodeRead}
style={styles.cameraView}
aspect={Camera.constants.Aspect.fill}
playSoundOnCapture
>
<View style={styles.maskOutter}>
<View style={[{ flex: maskRowHeight }, styles.maskRow, styles.maskFrame]} />
<View style={[{ flex: 30 }, styles.maskCenter]}>
<View style={[{ width: maskColWidth }, styles.maskFrame]} />
<View style={styles.maskInner} />
<View style={[{ width: maskColWidth }, styles.maskFrame]} />
</View>
<View style={[{ flex: maskRowHeight }, styles.maskRow, styles.maskFrame]} />
</View>
</Camera>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
cameraView: {
flex: 1,
justifyContent: 'flex-start',
},
maskOutter: {
position: 'absolute',
top: 0,
left: 0,
width: '100%',
height: '100%',
alignItems: 'center',
justifyContent: 'space-around',
},
maskInner: {
width: 300,
backgroundColor: 'transparent',
borderColor: 'white',
borderWidth: 1,
},
maskFrame: {
backgroundColor: 'rgba(1,1,1,0.6)',
},
maskRow: {
width: '100%',
},
maskCenter: { flexDirection: 'row' },
});
Update:
The height ratio changes between the different brand phones depend on it uses physical/soft buttons. I replaced the fixed height with flex
instead.