Skip to content

Instantly share code, notes, and snippets.

@jittuu
Created November 28, 2018 08:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jittuu/8d93736a2be93febe62c01b77a5a7969 to your computer and use it in GitHub Desktop.
Save jittuu/8d93736a2be93febe62c01b77a5a7969 to your computer and use it in GitHub Desktop.
QR Code Scanner for React Native
import { debounce } from 'lodash';
import React from 'react';
import {
Dimensions,
StyleSheet,
TouchableOpacity,
View,
ViewStyle,
} from 'react-native';
import { BarCodeType, Point, RNCamera, Size } from 'react-native-camera';
import MaterialIcons from 'react-native-vector-icons/MaterialIcons';
interface Props {
onClose?: () => void;
onQRCodeRead?: (qr: string) => void;
}
interface State {
flashOn: boolean;
}
class QRCodeScanner extends React.Component<Props, State> {
constructor(props: Props) {
super(props);
this.state = { flashOn: false };
this.onBarCodeRead = debounce(
this.onBarCodeRead,
1000,
{ leading: true, trailing: false });
}
onBarCodeRead = (event: {
data: string,
type: keyof BarCodeType,
bounds: [Point<string>, Point<string>] | { origin: Point<string>, size: Size<string> },
}) => {
if (event.data) {
const { onQRCodeRead } = this.props;
if (onQRCodeRead) {
onQRCodeRead(event.data);
}
}
}
handleClose = () => {
const { onClose } = this.props;
if (onClose) {
onClose();
}
}
handleFlash = () => {
this.setState({ flashOn: !this.state.flashOn });
}
render() {
const { flashOn } = this.state;
return (
<View style={[StyleSheet.absoluteFill]}>
<RNCamera
style={StyleSheet.absoluteFill}
type={RNCamera.Constants.Type.back}
onBarCodeRead={this.onBarCodeRead}
flashMode={flashOn ? RNCamera.Constants.FlashMode.torch : RNCamera.Constants.FlashMode.off}
/>
<View style={[StyleSheet.absoluteFill]}>
<View style={styles.overlay} />
<View style={[styles.row]}>
<View style={[styles.overlay]} />
<View
style={[styles.guideWrap]}
>
<View style={[styles.row, styles.guideItem]}>
<View style={[styles.guideItem, styles.guideTopLeft]} />
<View style={styles.guideCenterItem} />
<View style={[styles.guideItem, styles.guideTopRight]} />
</View>
<View style={styles.guideCenterItem} />
<View style={[styles.row, styles.guideItem]}>
<View style={[styles.guideItem, styles.guideBottomLeft]} />
<View style={styles.guideCenterItem} />
<View style={[styles.guideItem, styles.guideBottomRight]} />
</View>
</View>
<View style={[styles.overlay]} />
</View>
<View style={styles.overlay} />
</View>
<TouchableOpacity style={styles.close} onPress={this.handleClose}>
<MaterialIcons name="close" size={30} color="#fff" />
</TouchableOpacity>
<TouchableOpacity style={styles.flash} onPress={this.handleFlash}>
<MaterialIcons name={flashOn ? 'flash-on' : 'flash-off'} size={30} color="#fff" />
</TouchableOpacity>
</View>
);
}
}
const { width } = Dimensions.get('window');
const guideWidth = width - (width / 2.5);
const styles = StyleSheet.create({
row: {
flexDirection: 'row',
} as ViewStyle,
overlay: {
flex: 1,
backgroundColor: '#000',
opacity: 0.4,
} as ViewStyle,
guideWrap: {
width: guideWidth,
height: guideWidth,
} as ViewStyle,
guideItem: {
flex: 1,
borderColor: '#fff',
} as ViewStyle,
guideTopLeft: {
// borderTopLeftRadius: 20,
borderTopWidth: 2,
borderLeftWidth: 2,
overflow: 'hidden',
} as ViewStyle,
guideTopRight: {
// borderTopRightRadius: 20,
borderTopWidth: 2,
borderRightWidth: 2,
} as ViewStyle,
guideBottomLeft: {
// borderBottomLeftRadius: 20,
borderBottomWidth: 2,
borderLeftWidth: 2,
} as ViewStyle,
guideBottomRight: {
// borderBottomRightRadius: 20,
borderBottomWidth: 2,
borderRightWidth: 2,
} as ViewStyle,
guideCenterItem: {
flex: 3,
} as ViewStyle,
close: {
width: 100,
position: 'absolute',
left: 0,
bottom: 0,
padding: 20,
} as ViewStyle,
flash: {
width: 100,
position: 'absolute',
right: 0,
bottom: 0,
padding: 20,
alignItems: 'flex-end',
} as ViewStyle,
});
export default QRCodeScanner;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment