1 Star 1 Fork 0

飞鱼/ReactNativeToWebview

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
App.js 15.11 KB
一键复制 编辑 原始数据 按行查看 历史
飞鱼 提交于 2020-11-25 20:52 +08:00 . rn
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564
/* eslint-disable no-console */
import React from 'react';
import {
StyleSheet,
Text,
View,
TouchableOpacity,
Slider,
TouchableWithoutFeedback,
Dimensions,
} from 'react-native';
// eslint-disable-next-line import/no-unresolved
import { RNCamera } from 'react-native-camera';
const flashModeOrder = {
off: 'on',
on: 'auto',
auto: 'torch',
torch: 'off',
};
const wbOrder = {
auto: 'sunny',
sunny: 'cloudy',
cloudy: 'shadow',
shadow: 'fluorescent',
fluorescent: 'incandescent',
incandescent: 'auto',
};
const landmarkSize = 2;
export default class CameraScreen extends React.Component {
state = {
flash: 'off',
zoom: 0,
autoFocus: 'on',
autoFocusPoint: {
normalized: { x: 0.5, y: 0.5 }, // normalized values required for autoFocusPointOfInterest
drawRectPosition: {
x: Dimensions.get('window').width * 0.5 - 32,
y: Dimensions.get('window').height * 0.5 - 32,
},
},
depth: 0,
type: 'back',
whiteBalance: 'auto',
ratio: '16:9',
recordOptions: {
mute: false,
maxDuration: 5,
quality: RNCamera.Constants.VideoQuality['288p'],
},
isRecording: false,
canDetectFaces: false,
canDetectText: false,
canDetectBarcode: false,
faces: [],
textBlocks: [],
barcodes: [],
};
toggleFacing() {
this.setState({
type: this.state.type === 'back' ? 'front' : 'back',
});
}
toggleFlash() {
this.setState({
flash: flashModeOrder[this.state.flash],
});
}
toggleWB() {
this.setState({
whiteBalance: wbOrder[this.state.whiteBalance],
});
}
toggleFocus() {
this.setState({
autoFocus: this.state.autoFocus === 'on' ? 'off' : 'on',
});
}
touchToFocus(event) {
const { pageX, pageY } = event.nativeEvent;
const screenWidth = Dimensions.get('window').width;
const screenHeight = Dimensions.get('window').height;
const isPortrait = screenHeight > screenWidth;
let x = pageX / screenWidth;
let y = pageY / screenHeight;
// Coordinate transform for portrait. See autoFocusPointOfInterest in docs for more info
if (isPortrait) {
x = pageY / screenHeight;
y = -(pageX / screenWidth) + 1;
}
this.setState({
autoFocusPoint: {
normalized: { x, y },
drawRectPosition: { x: pageX, y: pageY },
},
});
}
zoomOut() {
this.setState({
zoom: this.state.zoom - 0.1 < 0 ? 0 : this.state.zoom - 0.1,
});
}
zoomIn() {
this.setState({
zoom: this.state.zoom + 0.1 > 1 ? 1 : this.state.zoom + 0.1,
});
}
setFocusDepth(depth) {
this.setState({
depth,
});
}
takePicture = async function() {
if (this.camera) {
const data = await this.camera.takePictureAsync();
console.warn('takePicture ', data);
}
};
takeVideo = async () => {
const { isRecording } = this.state;
if (this.camera && !isRecording) {
try {
const promise = this.camera.recordAsync(this.state.recordOptions);
if (promise) {
this.setState({ isRecording: true });
const data = await promise;
console.warn('takeVideo', data);
}
} catch (e) {
console.error(e);
}
}
};
toggle = value => () => this.setState(prevState => ({ [value]: !prevState[value] }));
facesDetected = ({ faces }) => this.setState({ faces });
renderFace = ({ bounds, faceID, rollAngle, yawAngle }) => (
<View
key={faceID}
transform={[
{ perspective: 600 },
{ rotateZ: `${rollAngle.toFixed(0)}deg` },
{ rotateY: `${yawAngle.toFixed(0)}deg` },
]}
style={[
styles.face,
{
...bounds.size,
left: bounds.origin.x,
top: bounds.origin.y,
},
]}
>
<Text style={styles.faceText}>ID: {faceID}</Text>
<Text style={styles.faceText}>rollAngle: {rollAngle.toFixed(0)}</Text>
<Text style={styles.faceText}>yawAngle: {yawAngle.toFixed(0)}</Text>
</View>
);
renderLandmarksOfFace(face) {
const renderLandmark = position =>
position && (
<View
style={[
styles.landmark,
{
left: position.x - landmarkSize / 2,
top: position.y - landmarkSize / 2,
},
]}
/>
);
return (
<View key={`landmarks-${face.faceID}`}>
{renderLandmark(face.leftEyePosition)}
{renderLandmark(face.rightEyePosition)}
{renderLandmark(face.leftEarPosition)}
{renderLandmark(face.rightEarPosition)}
{renderLandmark(face.leftCheekPosition)}
{renderLandmark(face.rightCheekPosition)}
{renderLandmark(face.leftMouthPosition)}
{renderLandmark(face.mouthPosition)}
{renderLandmark(face.rightMouthPosition)}
{renderLandmark(face.noseBasePosition)}
{renderLandmark(face.bottomMouthPosition)}
</View>
);
}
renderFaces = () => (
<View style={styles.facesContainer} pointerEvents="none">
{this.state.faces.map(this.renderFace)}
</View>
);
renderLandmarks = () => (
<View style={styles.facesContainer} pointerEvents="none">
{this.state.faces.map(this.renderLandmarksOfFace)}
</View>
);
renderTextBlocks = () => (
<View style={styles.facesContainer} pointerEvents="none">
{this.state.textBlocks.map(this.renderTextBlock)}
</View>
);
renderTextBlock = ({ bounds, value }) => (
<React.Fragment key={value + bounds.origin.x}>
<Text style={[styles.textBlock, { left: bounds.origin.x, top: bounds.origin.y }]}>
{value}
</Text>
<View
style={[
styles.text,
{
...bounds.size,
left: bounds.origin.x,
top: bounds.origin.y,
},
]}
/>
</React.Fragment>
);
textRecognized = object => {
const { textBlocks } = object;
this.setState({ textBlocks });
};
barcodeRecognized = ({ barcodes }) => this.setState({ barcodes });
renderBarcodes = () => (
<View style={styles.facesContainer} pointerEvents="none">
{this.state.barcodes.map(this.renderBarcode)}
</View>
);
renderBarcode = ({ bounds, data, type }) => (
<React.Fragment key={data + bounds.origin.x}>
<View
style={[
styles.text,
{
...bounds.size,
left: bounds.origin.x,
top: bounds.origin.y,
},
]}
>
<Text style={[styles.textBlock]}>{`${data} ${type}`}</Text>
</View>
</React.Fragment>
);
renderRecording = () => {
const { isRecording } = this.state;
const backgroundColor = isRecording ? 'white' : 'darkred';
const action = isRecording ? this.stopVideo : this.takeVideo;
const button = isRecording ? this.renderStopRecBtn() : this.renderRecBtn();
return (
<TouchableOpacity
style={[
styles.flipButton,
{
flex: 0.3,
alignSelf: 'flex-end',
backgroundColor,
},
]}
onPress={() => action()}
>
{button}
</TouchableOpacity>
);
};
stopVideo = async () => {
await this.camera.stopRecording();
this.setState({ isRecording: false });
};
renderRecBtn() {
return <Text style={styles.flipText}> REC </Text>;
}
renderStopRecBtn() {
return <Text style={styles.flipText}> </Text>;
}
renderCamera() {
const { canDetectFaces, canDetectText, canDetectBarcode } = this.state;
const drawFocusRingPosition = {
top: this.state.autoFocusPoint.drawRectPosition.y - 32,
left: this.state.autoFocusPoint.drawRectPosition.x - 32,
};
return (
<RNCamera
ref={ref => {
this.camera = ref;
}}
style={{
flex: 1,
justifyContent: 'space-between',
}}
type={this.state.type}
flashMode={this.state.flash}
autoFocus={this.state.autoFocus}
autoFocusPointOfInterest={this.state.autoFocusPoint.normalized}
zoom={this.state.zoom}
whiteBalance={this.state.whiteBalance}
ratio={this.state.ratio}
focusDepth={this.state.depth}
androidCameraPermissionOptions={{
title: 'Permission to use camera',
message: 'We need your permission to use your camera',
buttonPositive: 'Ok',
buttonNegative: 'Cancel',
}}
faceDetectionLandmarks={
RNCamera.Constants.FaceDetection.Landmarks
? RNCamera.Constants.FaceDetection.Landmarks.all
: undefined
}
onFacesDetected={canDetectFaces ? this.facesDetected : null}
onTextRecognized={canDetectText ? this.textRecognized : null}
onGoogleVisionBarcodesDetected={canDetectBarcode ? this.barcodeRecognized : null}
>
<View style={StyleSheet.absoluteFill}>
<View style={[styles.autoFocusBox, drawFocusRingPosition]} />
<TouchableWithoutFeedback onPress={this.touchToFocus.bind(this)}>
<View style={{ flex: 1 }} />
</TouchableWithoutFeedback>
</View>
<View
style={{
flex: 0.5,
height: 72,
backgroundColor: 'transparent',
flexDirection: 'row',
justifyContent: 'space-around',
}}
>
<View
style={{
backgroundColor: 'transparent',
flexDirection: 'row',
justifyContent: 'space-around',
}}
>
<TouchableOpacity style={styles.flipButton} onPress={this.toggleFacing.bind(this)}>
<Text style={styles.flipText}> FLIP </Text>
</TouchableOpacity>
<TouchableOpacity style={styles.flipButton} onPress={this.toggleFlash.bind(this)}>
<Text style={styles.flipText}> FLASH: {this.state.flash} </Text>
</TouchableOpacity>
<TouchableOpacity style={styles.flipButton} onPress={this.toggleWB.bind(this)}>
<Text style={styles.flipText}> WB: {this.state.whiteBalance} </Text>
</TouchableOpacity>
</View>
<View
style={{
backgroundColor: 'transparent',
flexDirection: 'row',
justifyContent: 'space-around',
}}
>
<TouchableOpacity onPress={this.toggle('canDetectFaces')} style={styles.flipButton}>
<Text style={styles.flipText}>
{!canDetectFaces ? 'Detect Faces' : 'Detecting Faces'}
</Text>
</TouchableOpacity>
<TouchableOpacity onPress={this.toggle('canDetectText')} style={styles.flipButton}>
<Text style={styles.flipText}>
{!canDetectText ? 'Detect Text' : 'Detecting Text'}
</Text>
</TouchableOpacity>
<TouchableOpacity onPress={this.toggle('canDetectBarcode')} style={styles.flipButton}>
<Text style={styles.flipText}>
{!canDetectBarcode ? 'Detect Barcode' : 'Detecting Barcode'}
</Text>
</TouchableOpacity>
</View>
</View>
<View style={{ bottom: 0 }}>
<View
style={{
height: 20,
backgroundColor: 'transparent',
flexDirection: 'row',
alignSelf: 'flex-end',
}}
>
<Slider
style={{ width: 150, marginTop: 15, alignSelf: 'flex-end' }}
onValueChange={this.setFocusDepth.bind(this)}
step={0.1}
disabled={this.state.autoFocus === 'on'}
/>
</View>
<View
style={{
height: 56,
backgroundColor: 'transparent',
flexDirection: 'row',
alignSelf: 'flex-end',
}}
>
{this.renderRecording()}
</View>
{this.state.zoom !== 0 && (
<Text style={[styles.flipText, styles.zoomText]}>Zoom: {this.state.zoom}</Text>
)}
<View
style={{
height: 56,
backgroundColor: 'transparent',
flexDirection: 'row',
alignSelf: 'flex-end',
}}
>
<TouchableOpacity
style={[styles.flipButton, { flex: 0.1, alignSelf: 'flex-end' }]}
onPress={this.zoomIn.bind(this)}
>
<Text style={styles.flipText}> + </Text>
</TouchableOpacity>
<TouchableOpacity
style={[styles.flipButton, { flex: 0.1, alignSelf: 'flex-end' }]}
onPress={this.zoomOut.bind(this)}
>
<Text style={styles.flipText}> - </Text>
</TouchableOpacity>
<TouchableOpacity
style={[styles.flipButton, { flex: 0.25, alignSelf: 'flex-end' }]}
onPress={this.toggleFocus.bind(this)}
>
<Text style={styles.flipText}> AF : {this.state.autoFocus} </Text>
</TouchableOpacity>
<TouchableOpacity
style={[styles.flipButton, styles.picButton, { flex: 0.3, alignSelf: 'flex-end' }]}
onPress={this.takePicture.bind(this)}
>
<Text style={styles.flipText}> SNAP </Text>
</TouchableOpacity>
</View>
</View>
{!!canDetectFaces && this.renderFaces()}
{!!canDetectFaces && this.renderLandmarks()}
{!!canDetectText && this.renderTextBlocks()}
{!!canDetectBarcode && this.renderBarcodes()}
</RNCamera>
);
}
render() {
return <View style={styles.container}>{this.renderCamera()}</View>;
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
paddingTop: 10,
backgroundColor: '#000',
},
flipButton: {
flex: 0.3,
height: 40,
marginHorizontal: 2,
marginBottom: 10,
marginTop: 10,
borderRadius: 8,
borderColor: 'white',
borderWidth: 1,
padding: 5,
alignItems: 'center',
justifyContent: 'center',
},
autoFocusBox: {
position: 'absolute',
height: 64,
width: 64,
borderRadius: 12,
borderWidth: 2,
borderColor: 'white',
opacity: 0.4,
},
flipText: {
color: 'white',
fontSize: 15,
},
zoomText: {
position: 'absolute',
bottom: 70,
zIndex: 2,
left: 2,
},
picButton: {
backgroundColor: 'darkseagreen',
},
facesContainer: {
position: 'absolute',
bottom: 0,
right: 0,
left: 0,
top: 0,
},
face: {
padding: 10,
borderWidth: 2,
borderRadius: 2,
position: 'absolute',
borderColor: '#FFD700',
justifyContent: 'center',
backgroundColor: 'rgba(0, 0, 0, 0.5)',
},
landmark: {
width: landmarkSize,
height: landmarkSize,
position: 'absolute',
backgroundColor: 'red',
},
faceText: {
color: '#FFD700',
fontWeight: 'bold',
textAlign: 'center',
margin: 10,
backgroundColor: 'transparent',
},
text: {
padding: 10,
borderWidth: 2,
borderRadius: 2,
position: 'absolute',
borderColor: '#F00',
justifyContent: 'center',
},
textBlock: {
color: '#F00',
position: 'absolute',
textAlign: 'center',
backgroundColor: 'transparent',
},
});
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/ggxx/react-native-to-webview.git
git@gitee.com:ggxx/react-native-to-webview.git
ggxx
react-native-to-webview
ReactNativeToWebview
master

搜索帮助