Skip to content

Instantly share code, notes, and snippets.

@jqn
Last active September 29, 2020 06:30
Show Gist options
  • Save jqn/9b1bc690eebf601df17ef5e6e708e82f to your computer and use it in GitHub Desktop.
Save jqn/9b1bc690eebf601df17ef5e6e708e82f to your computer and use it in GitHub Desktop.
RN Camera with rotating icons
import React, {Component} from 'react';
import {View, TouchableOpacity, Dimensions, Text} from 'react-native';
import Orientation from 'react-native-orientation-locker';
import FontAwesome from 'react-native-vector-icons/FontAwesome';
import {RNCamera} from 'react-native-camera';
import * as Animatable from 'react-native-animatable';
const SCREEN_HEIGHT = Dimensions.get('window').height;
const SCREEN_WIDTH = Dimensions.get('window').width;
export default class App extends Component {
constructor() {
super();
this.state = {
orientation: 'PORTRAIT',
barcode: '',
};
}
componentDidMount() {
Orientation.lockToPortrait();
Orientation.addDeviceOrientationListener(
this._addDeviceOrientationListener.bind(this),
);
Orientation.addOrientationListener(this._onOrientationDidChange);
}
componentWillUnmount() {
Orientation.removeDeviceOrientationListener(
this._addDeviceOrientationListener,
);
Orientation.removeOrientationListener(this._onOrientationDidChange);
}
_addDeviceOrientationListener(deviceOrientation) {
console.log(
'App -> _addDeviceOrientationListener -> deviceOrientation',
deviceOrientation,
);
this.setState({orientation: deviceOrientation});
}
_onOrientationDidChange = (orientation) => {
console.log('App -> _onOrientationDidChange -> orientation', orientation);
if (orientation == 'LANDSCAPE-LEFT') {
//do something with landscape left layout
} else {
//do something with portrait layout
}
};
makeSlideOutTranslation(translationType, fromValue) {
return {
from: {
[translationType]: SCREEN_WIDTH * -0.18,
},
to: {
[translationType]: fromValue,
},
};
}
onBarCodeRead = (e) => {
this.setState({barcode: e.data});
};
render() {
return (
<View style={style.container}>
<RNCamera
onBarCodeRead={this.onBarCodeRead}
ref={(ref) => {
this.camera = ref;
}}
style={{
flex: 1,
width: '100%',
}}>
<Text
style={{
...style.scanText,
top:
this.state.orientation == 'LANDSCAPE-LEFT' ||
this.state.orientation == 'LANDSCAPE-RIGHT'
? '45%'
: '25%',
left:
this.state.orientation == 'LANDSCAPE-LEFT'
? '75%'
: this.state.orientation == 'LANDSCAPE-RIGHT'
? '-5%'
: '35%',
transform: [
{
rotate:
this.state.orientation == 'LANDSCAPE-LEFT'
? '90deg'
: this.state.orientation == 'LANDSCAPE-RIGHT'
? '270deg'
: '0deg',
},
],
}}>
Scan QRCODE
</Text>
<View style={style.scanView}>
<Animatable.View
style={style.scanBar}
direction="alternate-reverse"
iterationCount="infinite"
duration={1700}
easing="linear"
animation={this.makeSlideOutTranslation(
'translateY',
SCREEN_WIDTH * -0.54,
)}
/>
</View>
<Text
style={{
alignSelf: 'center',
fontSize: 25,
color: '#000',
justifyContent: 'center',
top:
this.state.orientation == 'LANDSCAPE-LEFT' ||
this.state.orientation == 'LANDSCAPE-RIGHT'
? SCREEN_HEIGHT / 2
: '80%',
left:
this.state.orientation == 'LANDSCAPE-LEFT'
? '-40%'
: this.state.orientation == 'LANDSCAPE-RIGHT'
? '40%'
: '0%',
transform: [
{
rotate:
this.state.orientation == 'LANDSCAPE-LEFT'
? '90deg'
: this.state.orientation == 'LANDSCAPE-RIGHT'
? '270deg'
: '0deg',
},
],
}}>
{this.state.barcode}
</Text>
</RNCamera>
<View style={style.cameraIcon}>
<TouchableOpacity
style={{
...style.capture,
transform: [
{
rotate:
this.state.orientation == 'LANDSCAPE-LEFT'
? '90deg'
: this.state.orientation == 'LANDSCAPE-RIGHT'
? '270deg'
: '0deg',
},
],
}}>
<FontAwesome name="camera" color={'white'} size={50} />
</TouchableOpacity>
</View>
<View style={style.flashIcon}>
<TouchableOpacity
style={{
...style.capture,
transform: [
{
rotate:
this.state.orientation == 'LANDSCAPE-LEFT'
? '90deg'
: this.state.orientation == 'LANDSCAPE-RIGHT'
? '270deg'
: '0deg',
},
],
}}>
<FontAwesome name="bolt" color={'white'} size={50} />
</TouchableOpacity>
</View>
</View>
);
}
}
const style = {
container: {
flex: 1,
flexDirection: 'column',
backgroundColor: 'black',
},
scanBar: {
width: '78%',
height: 1,
backgroundColor: 'red',
marginLeft: 30,
marginTop: 300,
},
scanText: {
position: 'absolute',
fontSize: 25,
color: '#000',
justifyContent: 'center',
},
scanView: {
borderWidth: 2,
position: 'absolute',
top: '30%',
left: '20%',
borderColor: '#F00',
justifyContent: 'center',
backgroundColor: 'rgba(255, 255, 255, 0.9)',
padding: 10,
width: '65%',
height: '35%',
backgroundColor: 'transparent',
},
preview: {
flex: 1,
justifyContent: 'flex-end',
alignItems: 'center',
},
capture: {
flex: 0,
padding: 15,
alignSelf: 'center',
margin: 20,
},
cameraIcon: {
position: 'absolute',
bottom: 0,
left: '33%',
},
flashIcon: {
position: 'absolute',
bottom: 0,
left: '70%',
},
};
import React, {Component} from 'react';
import {View, TouchableOpacity, Dimensions, Text} from 'react-native';
import Orientation from 'react-native-orientation-locker';
import FontAwesome from 'react-native-vector-icons/FontAwesome';
import {RNCamera} from 'react-native-camera';
import * as Animatable from 'react-native-animatable';
const SCREEN_HEIGHT = Dimensions.get('window').height;
const SCREEN_WIDTH = Dimensions.get('window').width;
export default class App extends Component {
constructor() {
super();
this.state = {
orientation: 'PORTRAIT',
barcode: '',
};
}
componentDidMount = () => {
Orientation.lockToPortrait();
Orientation.addDeviceOrientationListener(
this._addDeviceOrientationListener,
);
};
componentWillUnmount = () => {
Orientation.removeDeviceOrientationListener(
this._addDeviceOrientationListener,
);
};
_addDeviceOrientationListener = (deviceOrientation) => {
console.log(
'App -> _addDeviceOrientationListener -> deviceOrientation',
deviceOrientation,
);
this.setState({orientation: deviceOrientation});
};
makeSlideOutTranslation(translationType, fromValue) {
return {
from: {
[translationType]: SCREEN_WIDTH * -0.18,
},
to: {
[translationType]: fromValue,
},
};
}
onBarCodeRead = (e) => {
this.setState({barcode: e.data});
};
render() {
return (
<View style={style.container}>
<RNCamera
onBarCodeRead={this.onBarCodeRead}
captureAudio={false}
ref={(ref) => {
this.camera = ref;
}}
style={{
flex: 1,
width: '100%',
}}>
<Text
style={{
...style.scanText,
top:
this.state.orientation == 'LANDSCAPE-LEFT' ||
this.state.orientation == 'LANDSCAPE-RIGHT'
? '45%'
: '25%',
left:
this.state.orientation == 'LANDSCAPE-LEFT'
? '75%'
: this.state.orientation == 'LANDSCAPE-RIGHT'
? '-5%'
: '35%',
transform: [
{
rotate:
this.state.orientation == 'LANDSCAPE-LEFT'
? '90deg'
: this.state.orientation == 'LANDSCAPE-RIGHT'
? '270deg'
: '0deg',
},
],
}}>
Scan QRCODE
</Text>
<View style={style.scanView}>
<Animatable.View
style={style.scanBar}
direction="alternate-reverse"
iterationCount="infinite"
duration={1700}
easing="linear"
animation={this.makeSlideOutTranslation(
'translateY',
SCREEN_WIDTH * -0.54,
)}
/>
</View>
<Text
style={{
alignSelf: 'center',
fontSize: 25,
color: '#000',
justifyContent: 'center',
top:
this.state.orientation == 'LANDSCAPE-LEFT' ||
this.state.orientation == 'LANDSCAPE-RIGHT'
? SCREEN_HEIGHT / 2
: '80%',
left:
this.state.orientation == 'LANDSCAPE-LEFT'
? '-40%'
: this.state.orientation == 'LANDSCAPE-RIGHT'
? '40%'
: '0%',
transform: [
{
rotate:
this.state.orientation == 'LANDSCAPE-LEFT'
? '90deg'
: this.state.orientation == 'LANDSCAPE-RIGHT'
? '270deg'
: '0deg',
},
],
}}>
{this.state.barcode}
</Text>
</RNCamera>
<View style={style.cameraIcon}>
<TouchableOpacity
style={{
...style.capture,
transform: [
{
rotate:
this.state.orientation == 'LANDSCAPE-LEFT'
? '90deg'
: this.state.orientation == 'LANDSCAPE-RIGHT'
? '270deg'
: '0deg',
},
],
}}>
<FontAwesome name="camera" color={'white'} size={50} />
</TouchableOpacity>
</View>
<View style={style.flashIcon}>
<TouchableOpacity
style={{
...style.capture,
transform: [
{
rotate:
this.state.orientation == 'LANDSCAPE-LEFT'
? '90deg'
: this.state.orientation == 'LANDSCAPE-RIGHT'
? '270deg'
: '0deg',
},
],
}}>
<FontAwesome name="bolt" color={'white'} size={50} />
</TouchableOpacity>
</View>
</View>
);
}
}
const style = {
container: {
flex: 1,
flexDirection: 'column',
backgroundColor: 'black',
},
scanBar: {
width: '78%',
height: 1,
backgroundColor: 'red',
marginLeft: 30,
marginTop: 300,
},
scanText: {
position: 'absolute',
fontSize: 25,
color: '#000',
justifyContent: 'center',
},
scanView: {
borderWidth: 2,
position: 'absolute',
top: '30%',
left: '20%',
borderColor: '#F00',
justifyContent: 'center',
backgroundColor: 'rgba(255, 255, 255, 0.9)',
padding: 10,
width: '65%',
height: '35%',
backgroundColor: 'transparent',
},
preview: {
flex: 1,
justifyContent: 'flex-end',
alignItems: 'center',
},
capture: {
flex: 0,
padding: 15,
alignSelf: 'center',
margin: 20,
},
cameraIcon: {
position: 'absolute',
bottom: 0,
left: '33%',
},
flashIcon: {
position: 'absolute',
bottom: 0,
left: '70%',
},
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment