import React, {Component} from 'react'; import Camera from 'react-native-camera'; import PropTypes from 'prop-types'; import { ActivityIndicator, StyleSheet, View, Animated, Easing, Text, Image } from 'react-native'; /** * 扫描界面遮罩 * 单独写一个类,方便拷贝使用 */ class QRScannerRectView extends Component { static defaultProps = { maskColor: '#0000004D', cornerColor: '#22ff00', borderColor: '#000000', rectHeight: 200, rectWidth: 200, borderWidth: 0, cornerBorderWidth: 4, cornerBorderLength: 20, isLoading: false, cornerOffsetSize: 0, isCornerOffset: false, bottomMenuHeight: 0, scanBarAnimateTime: 2500, scanBarColor: '#22ff00', scanBarImage: null, scanBarHeight: 1.5, scanBarMargin: 6, hintText: '将二维码/条码放入框内,即可自动扫描', hintTextStyle: {color: '#fff', fontSize: 14,backgroundColor:'transparent'}, hintTextPosition: 130, isShowScanBar:true }; constructor(props) { super(props); this.getBackgroundColor = this.getBackgroundColor.bind(this); this.getRectSize = this.getRectSize.bind(this); this.getCornerSize = this.getCornerSize.bind(this); this.renderLoadingIndicator = this.renderLoadingIndicator.bind(this); this.state = { topWidth: 0, topHeight: 0, leftWidth: 0, animatedValue: new Animated.Value(0), } } //获取背景颜色 getBackgroundColor() { return ({ backgroundColor: this.props.maskColor, }); } //获取扫描框背景大小 getRectSize() { return ({ height: this.props.rectHeight, width: this.props.rectWidth, }); } //获取扫描框边框大小 getBorderSize() { if (this.props.isCornerOffset) { return ({ height: this.props.rectHeight - this.props.cornerOffsetSize * 2, width: this.props.rectWidth - this.props.cornerOffsetSize * 2, }); } else { return ({ height: this.props.rectHeight, width: this.props.rectWidth, }); } } //获取扫描框转角的颜色 getCornerColor() { return ({ borderColor: this.props.cornerColor, }); } //获取扫描框转角的大小 getCornerSize() { return ({ height: this.props.cornerBorderLength, width: this.props.cornerBorderLength, }); } //获取扫描框大小 getBorderWidth() { return ({ borderWidth: this.props.borderWidth, }); } //获取扫描框颜色 getBorderColor() { return ({ borderColor: this.props.borderColor, }); } //渲染加载动画 renderLoadingIndicator() { if (!this.props.isLoading) { return null; } return ( ); } //测量整个扫描组件的大小 measureTotalSize(e) { let totalSize = e.layout; this.setState({ topWidth: totalSize.width, }) } //测量扫描框的位置 measureRectPosition(e) { let rectSize = e.layout; this.setState({ topHeight: rectSize.y, leftWidth: rectSize.x, }) } //获取顶部遮罩高度 getTopMaskHeight() { if (this.props.isCornerOffset) { return this.state.topHeight + this.props.rectHeight - this.props.cornerOffsetSize; } else { return this.state.topHeight + this.props.rectHeight; } } //获取底部遮罩高度 getBottomMaskHeight() { if (this.props.isCornerOffset) { return this.props.rectHeight + this.state.topHeight - this.props.cornerOffsetSize; } else { return this.state.topHeight + this.props.rectHeight; } } //获取左右两边遮罩高度 getSideMaskHeight() { if (this.props.isCornerOffset) { return this.props.rectHeight - this.props.cornerOffsetSize * 2; } else { return this.props.rectHeight; } } //获取左右两边遮罩宽度 getSideMaskWidth() { if (this.props.isCornerOffset) { return this.state.leftWidth + this.props.cornerOffsetSize; } else { return this.state.leftWidth; } } getBottomMenuHeight() { return ({ bottom: this.props.bottomMenuHeight, }); } getScanBarMargin() { return ({ marginRight: this.props.scanBarMargin, marginLeft: this.props.scanBarMargin, }) } getScanImageWidth() { return this.props.rectWidth - this.props.scanBarMargin * 2 } //绘制扫描线 _renderScanBar() { if(!this.props.isShowScanBar) return; if (this.props.scanBarImage) { return } else { return } } render() { const animatedStyle = { transform: [ {translateY: this.state.animatedValue} ] }; return ( this.measureTotalSize(e)} style={[styles.container, this.getBottomMenuHeight()]}> this.measureRectPosition(e)} > {/*扫描框边线*/} {this._renderScanBar()} {/*扫描框转角-左上角*/} {/*扫描框转角-右上角*/} {/*加载动画*/} {this.renderLoadingIndicator()} {/*扫描框转角-左下角*/} {/*扫描框转角-右下角*/} {this.props.hintText} ); } componentDidMount() { this.scannerLineMove(); } scannerLineMove() { this.state.animatedValue.setValue(0); //重置Rotate动画值为0 Animated.timing(this.state.animatedValue, { toValue: this.props.rectHeight, duration: this.props.scanBarAnimateTime, easing: Easing.linear }).start(() => this.scannerLineMove()); } } /** * 扫描界面 */ export default class QRScannerView extends Component { static propTypes = { maskColor: PropTypes.string, borderColor: PropTypes.string, cornerColor: PropTypes.string, borderWidth: PropTypes.number, cornerBorderWidth: PropTypes.number, cornerBorderLength: PropTypes.number, rectHeight: PropTypes.number, rectWidth: PropTypes.number, isLoading: PropTypes.bool, isCornerOffset: PropTypes.bool,//边角是否偏移 cornerOffsetSize: PropTypes.number, bottomMenuHeight: PropTypes.number, scanBarAnimateTime: PropTypes.number, scanBarColor: PropTypes.string, scanBarImage: PropTypes.any, scanBarHeight: PropTypes.number, scanBarMargin: PropTypes.number, hintText: PropTypes.string, hintTextStyle: PropTypes.object, hintTextPosition:PropTypes.number, renderTopBarView:PropTypes.func, renderBottomMenuView:PropTypes.func, isShowScanBar:PropTypes.bool, bottomMenuStyle:PropTypes.object, onScanResultReceived:PropTypes.func, }; constructor(props) { super(props); //通过这句代码屏蔽 YellowBox console.disableYellowBox = true; } render() { return ( {/*绘制顶部标题栏组件*/} {this.props.renderTopBarView()} {/*绘制扫描遮罩*/} {/*绘制底部操作栏*/} {this.props.renderBottomMenuView()} ); } } const styles = StyleSheet.create({ buttonsContainer: { position: 'absolute', height: 100, bottom: 0, left: 0, right: 0, }, container: { alignItems: 'center', justifyContent: 'center', position: 'absolute', top: 0, right: 0, left: 0, }, viewfinder: { alignItems: 'center', justifyContent: 'center', }, topLeftCorner: { position: 'absolute', top: 0, left: 0, }, topRightCorner: { position: 'absolute', top: 0, right: 0, }, bottomLeftCorner: { position: 'absolute', bottom: 0, left: 0, }, bottomRightCorner: { position: 'absolute', bottom: 0, right: 0, }, topMask: { position: 'absolute', top: 0, }, leftMask: { position: 'absolute', left: 0, }, rightMask: { position: 'absolute', right: 0, }, bottomMask: { position: 'absolute', bottom: 0, } });