@react-native-ohos/react-native-qr-decode-image-camera 1.1.4-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/COMMITTERS.md +7 -0
  2. package/LICENSE +21 -0
  3. package/OAT.xml +89 -0
  4. package/QrCode.podspec +14 -0
  5. package/README.OpenSource +11 -0
  6. package/README.md +13 -0
  7. package/SECURITY.md +21 -0
  8. package/harmony/qr_decode_image_camera/BuildProfile.ets +17 -0
  9. package/harmony/qr_decode_image_camera/Index.ets +8 -0
  10. package/harmony/qr_decode_image_camera/build-profile.json5 +28 -0
  11. package/harmony/qr_decode_image_camera/hvigorfile.ts +1 -0
  12. package/harmony/qr_decode_image_camera/obfuscation-rules.txt +18 -0
  13. package/harmony/qr_decode_image_camera/oh-package-lock.json5 +18 -0
  14. package/harmony/qr_decode_image_camera/oh-package.json5 +12 -0
  15. package/harmony/qr_decode_image_camera/src/main/cpp/CMakeLists.txt +9 -0
  16. package/harmony/qr_decode_image_camera/src/main/cpp/QrDecodeImageCameraPackage.h +19 -0
  17. package/harmony/qr_decode_image_camera/src/main/cpp/generated/RNOH/generated/BaseReactNativeQrDecodeImageCameraPackage.h +72 -0
  18. package/harmony/qr_decode_image_camera/src/main/cpp/generated/RNOH/generated/turbo_modules/QrDecodeImageCameraNativeModule.cpp +16 -0
  19. package/harmony/qr_decode_image_camera/src/main/cpp/generated/RNOH/generated/turbo_modules/QrDecodeImageCameraNativeModule.h +16 -0
  20. package/harmony/qr_decode_image_camera/src/main/cpp/generated/react/renderer/components/react_native_qr_decode_image_camera/ComponentDescriptors.h +24 -0
  21. package/harmony/qr_decode_image_camera/src/main/cpp/generated/react/renderer/components/react_native_qr_decode_image_camera/EventEmitters.cpp +16 -0
  22. package/harmony/qr_decode_image_camera/src/main/cpp/generated/react/renderer/components/react_native_qr_decode_image_camera/EventEmitters.h +17 -0
  23. package/harmony/qr_decode_image_camera/src/main/cpp/generated/react/renderer/components/react_native_qr_decode_image_camera/Props.cpp +19 -0
  24. package/harmony/qr_decode_image_camera/src/main/cpp/generated/react/renderer/components/react_native_qr_decode_image_camera/Props.h +18 -0
  25. package/harmony/qr_decode_image_camera/src/main/cpp/generated/react/renderer/components/react_native_qr_decode_image_camera/ShadowNodes.cpp +17 -0
  26. package/harmony/qr_decode_image_camera/src/main/cpp/generated/react/renderer/components/react_native_qr_decode_image_camera/ShadowNodes.h +23 -0
  27. package/harmony/qr_decode_image_camera/src/main/cpp/generated/react/renderer/components/react_native_qr_decode_image_camera/States.cpp +16 -0
  28. package/harmony/qr_decode_image_camera/src/main/cpp/generated/react/renderer/components/react_native_qr_decode_image_camera/States.h +19 -0
  29. package/harmony/qr_decode_image_camera/src/main/ets/Logger.ts +46 -0
  30. package/harmony/qr_decode_image_camera/src/main/ets/NativeScan.ets +150 -0
  31. package/harmony/qr_decode_image_camera/src/main/ets/RNQrDecodeImageCameraPackage.ts +29 -0
  32. package/harmony/qr_decode_image_camera/src/main/ets/RNQrDecodeImageCameraTurboModule.ts +46 -0
  33. package/harmony/qr_decode_image_camera/src/main/ets/generated/components/NativeScan.ts +125 -0
  34. package/harmony/qr_decode_image_camera/src/main/ets/generated/components/ts.ts +8 -0
  35. package/harmony/qr_decode_image_camera/src/main/ets/generated/index.ets +5 -0
  36. package/harmony/qr_decode_image_camera/src/main/ets/generated/ts.ts +6 -0
  37. package/harmony/qr_decode_image_camera/src/main/ets/generated/turboModules/QrDecodeImageCameraNativeModule.ts +16 -0
  38. package/harmony/qr_decode_image_camera/src/main/ets/generated/turboModules/ts.ts +5 -0
  39. package/harmony/qr_decode_image_camera/src/main/ets/pages/Index.ets +26 -0
  40. package/harmony/qr_decode_image_camera/src/main/ets/qr_decode_image_camera/qr_decode_image_camera.ets +47 -0
  41. package/harmony/qr_decode_image_camera/src/main/module.json5 +11 -0
  42. package/harmony/qr_decode_image_camera/src/main/resources/base/element/color.json +8 -0
  43. package/harmony/qr_decode_image_camera/src/main/resources/base/element/string.json +16 -0
  44. package/harmony/qr_decode_image_camera/src/main/resources/base/media/background.png +0 -0
  45. package/harmony/qr_decode_image_camera/src/main/resources/base/media/foreground.png +0 -0
  46. package/harmony/qr_decode_image_camera/src/main/resources/base/media/layered_image.json +7 -0
  47. package/harmony/qr_decode_image_camera/src/main/resources/base/media/startIcon.png +0 -0
  48. package/harmony/qr_decode_image_camera/src/main/resources/base/profile/main_pages.json +5 -0
  49. package/harmony/qr_decode_image_camera/src/main/resources/en_US/element/string.json +16 -0
  50. package/harmony/qr_decode_image_camera/src/main/resources/zh_CN/element/string.json +16 -0
  51. package/harmony/qr_decode_image_camera/src/mock/mock-config.json5 +2 -0
  52. package/harmony/qr_decode_image_camera/src/ohosTest/ets/test/Ability.test.ets +35 -0
  53. package/harmony/qr_decode_image_camera/src/ohosTest/ets/test/List.test.ets +5 -0
  54. package/harmony/qr_decode_image_camera/src/ohosTest/ets/testability/TestAbility.ets +47 -0
  55. package/harmony/qr_decode_image_camera/src/ohosTest/ets/testability/pages/Index.ets +17 -0
  56. package/harmony/qr_decode_image_camera/src/ohosTest/ets/testrunner/OpenHarmonyTestRunner.ets +90 -0
  57. package/harmony/qr_decode_image_camera/src/ohosTest/module.json5 +36 -0
  58. package/harmony/qr_decode_image_camera/src/ohosTest/resources/base/element/color.json +8 -0
  59. package/harmony/qr_decode_image_camera/src/ohosTest/resources/base/element/string.json +16 -0
  60. package/harmony/qr_decode_image_camera/src/ohosTest/resources/base/media/icon.png +0 -0
  61. package/harmony/qr_decode_image_camera/src/ohosTest/resources/base/profile/test_pages.json +5 -0
  62. package/harmony/qr_decode_image_camera/src/test/List.test.ets +5 -0
  63. package/harmony/qr_decode_image_camera/src/test/LocalUnit.test.ets +33 -0
  64. package/harmony/qr_decode_image_camera/ts.ts +8 -0
  65. package/harmony/qr_decode_image_camera.har +0 -0
  66. package/index.js +15 -0
  67. package/package.json +39 -0
  68. package/src/Camera.tsx +58 -0
  69. package/src/NativeQrDecodeImageCamera.ts +17 -0
  70. package/src/NativeScan.ts +25 -0
  71. package/src/QRScanner.harmony.jsx +225 -0
  72. package/src/QRScanner.jsx +281 -0
  73. package/src/QRScannerView.js +381 -0
@@ -0,0 +1,281 @@
1
+ import React, { PureComponent, Component } from "react";
2
+ import { RNCamera } from "react-native-camera";
3
+ import PropTypes from "prop-types";
4
+
5
+ import {
6
+ StyleSheet,
7
+ View,
8
+ Text,
9
+ Vibration,
10
+ Platform,
11
+ } from "react-native";
12
+ import QRScannerView from "./QRScannerView";
13
+ import QRScannerHarmony from "./QRScanner.harmony.jsx"
14
+ /**
15
+ * Scan interface
16
+ */
17
+
18
+
19
+ export default class QRScanner extends Component {
20
+
21
+ constructor(props) {
22
+ super(props);
23
+ this.state = {
24
+ scanning: false,
25
+ barCodeSize: {}
26
+ };
27
+ }
28
+
29
+ static defaultProps = {
30
+ onRead: () => { },
31
+ renderTopView: () => { },
32
+ renderBottomView: () => (
33
+ <View style={{ flex: 1, backgroundColor: "#0000004D" }} />
34
+ ),
35
+ rectHeight: 200,
36
+ rectWidth: 200,
37
+ flashMode: false, // Flashlight mode
38
+ finderX: 0, // Viewfinder X-axis offset
39
+ finderY: 0, // Viewfinder Y-axis offset
40
+ zoom: 0.2, // Zoom range 0 - 1
41
+ translucent: false,
42
+ isRepeatScan: false,
43
+ cameraType: "back",
44
+ notAuthorizedView: () => (
45
+ <View style={styles.authorizationContainer}>
46
+ <Text style={styles.notAuthorizedText}>Camera not authorized</Text>
47
+ </View>
48
+ ),
49
+ vibrate: true,
50
+ };
51
+
52
+ render() {
53
+ if (Platform.OS == 'harmony') {
54
+ return (
55
+ <QRScannerHarmony {...this.props} />
56
+ )
57
+ } else {
58
+ return (
59
+ <View
60
+ style={{
61
+ flex: 1
62
+ }}
63
+ >
64
+ <RNCamera
65
+ style={{
66
+ flex: 1
67
+ }}
68
+ captureAudio={false}
69
+ onBarCodeRead={this._handleBarCodeRead}
70
+ androidCameraPermissionOptions={null}
71
+ androidRecordAudioPermissionOptions={null}
72
+ notAuthorizedView={this.props.notAuthorizedView()}
73
+ barCodeTypes={[RNCamera.Constants.BarCodeType.qr]}
74
+ flashMode={
75
+ !this.props.flashMode
76
+ ? RNCamera.Constants.FlashMode.off
77
+ : RNCamera.Constants.FlashMode.torch
78
+ }
79
+ zoom={this.props.zoom}
80
+ type={this.props.cameraType}
81
+ >
82
+ <View style={[styles.topButtonsContainer, this.props.topViewStyle]}>
83
+ {this.props.renderTopView()}
84
+ </View>
85
+ <QRScannerView
86
+ maskColor={this.props.maskColor}
87
+ cornerColor={this.props.cornerColor}
88
+ borderColor={this.props.borderColor}
89
+ rectHeight={this.props.rectHeight}
90
+ rectWidth={this.props.rectWidth}
91
+ borderWidth={this.props.borderWidth}
92
+ cornerBorderWidth={this.props.cornerBorderWidth}
93
+ cornerBorderLength={this.props.cornerBorderLength}
94
+ cornerOffsetSize={this.props.cornerOffsetSize}
95
+ isCornerOffset={this.props.isCornerOffset}
96
+ bottomHeight={this.props.bottomHeight}
97
+ scanBarAnimateTime={this.props.scanBarAnimateTime}
98
+ scanBarColor={this.props.scanBarColor}
99
+ scanBarHeight={this.props.scanBarHeight}
100
+ scanBarMargin={this.props.scanBarMargin}
101
+ hintText={this.props.hintText}
102
+ hintTextStyle={this.props.hintTextStyle}
103
+ scanBarImage={this.props.scanBarImage}
104
+ hintTextPosition={this.props.hintTextPosition}
105
+ isShowScanBar={this.props.isShowScanBar}
106
+ finderX={this.props.finderX}
107
+ finderY={this.props.finderY}
108
+ returnSize={this.barCodeSize}
109
+ />
110
+ <View
111
+ style={[styles.bottomButtonsContainer, this.props.bottomViewStyle]}
112
+ >
113
+ {this.props.renderBottomView()}
114
+ </View>
115
+ </RNCamera>
116
+ </View>
117
+ );
118
+ }
119
+
120
+ }
121
+
122
+ isShowCode = false;
123
+
124
+ barCodeSize = size => this.setState({ barCodeSize: size });
125
+
126
+ returnMax = (a, b) => (a > b ? a : b);
127
+
128
+ returnMin = (a, b) => (a < b ? a : b);
129
+
130
+ iosBarCode = e => {
131
+ let x = Number(e.bounds.origin.x);
132
+ let y = Number(e.bounds.origin.y);
133
+ let width = e.bounds.size.width;
134
+ let height = e.bounds.size.height;
135
+ let viewMinX = this.state.barCodeSize.x - this.props.finderX;
136
+ let viewMinY = this.state.barCodeSize.y - this.props.finderY;
137
+ let viewMaxX =
138
+ this.state.barCodeSize.x +
139
+ this.state.barCodeSize.width -
140
+ width -
141
+ this.props.finderX;
142
+ let viewMaxY =
143
+ this.state.barCodeSize.y +
144
+ this.state.barCodeSize.height -
145
+ height -
146
+ this.props.finderY;
147
+ if (x > viewMinX && y > viewMinY && x < viewMaxX && y < viewMaxY) {
148
+ if (this.props.isRepeatScan) {
149
+ if (this.props.vibrate) {
150
+ Vibration.vibrate();
151
+ }
152
+ this.props.onRead(e);
153
+ } else {
154
+ if (!this.isShowCode) {
155
+ this.isShowCode = true;
156
+ if (this.props.vibrate) {
157
+ Vibration.vibrate();
158
+ }
159
+ this.props.onRead(e);
160
+ }
161
+ }
162
+ }
163
+ };
164
+
165
+ androidBarCode = e => {
166
+ // if (!e.bounds[0] || !e.bounds[1] || !e.bounds[2] || !e.bounds[3]) return null;
167
+ // const leftBottom = {x: e.bounds[0].x / pixelRatio, y: e.bounds[0].y / pixelRatio}
168
+ // const leftTop= {x: e.bounds[1].x / pixelRatio, y: e.bounds[1].y / pixelRatio}
169
+ // const rightTop = {x: e.bounds[2].x / pixelRatio, y: e.bounds[2].y / pixelRatio}
170
+ // const rightBottom = {x: e.bounds[3].x / pixelRatio, y: e.bounds[3].y / pixelRatio}
171
+ // let x = this.returnMin(leftTop.x, leftBottom.x);
172
+ // let y = this.returnMin(leftTop.y, rightTop.y);
173
+ // let width = this.returnMax(rightTop.x - leftTop.x, rightBottom.x - leftBottom.x)
174
+ // let height = this.returnMax(leftBottom.y - leftTop.y , rightBottom.y - rightTop.y)
175
+ // let viewMinX = this.state.barCodeSize.x - this.props.finderX * 4 / pixelRatio - (this.props.finderX > 0 ? this.props.finderX/10 : 0)
176
+ // let viewMinY = this.state.barCodeSize.y - this.props.finderY * 4 / pixelRatio - (this.props.translucent ? 0 : StatusBar.currentHeight)*2/pixelRatio - (this.props.finderY > 0 ? this.props.finderY/3 : this.props.finderY/10*(-1))
177
+ // let viewMaxX = this.state.barCodeSize.x + 20 + this.state.barCodeSize.width*2 / pixelRatio - width - this.props.finderX *4/pixelRatio - (this.props.finderX < 0 ? 0 : this.props.finderX/5)
178
+ // let viewMaxY = this.state.barCodeSize.y + this.state.barCodeSize.height*2 / pixelRatio - height - this.props.finderY *4/pixelRatio - (this.props.translucent ? 0 : StatusBar.currentHeight)*2/pixelRatio - (this.props.finderY < 0 ? this.props.finderY/5 : 0 )
179
+ // if(x&&y) {
180
+ // if ((x > viewMinX && y > viewMinY) && (x < viewMaxX && y < viewMaxY)) {
181
+ // if (this.props.isRepeatScan) {
182
+ // Vibration.vibrate();
183
+ // this.props.onRead(e)
184
+ // } else {
185
+ // if (!this.isShowCode) {
186
+ // this.isShowCode = true;
187
+ // Vibration.vibrate();
188
+ // this.props.onRead(e)
189
+ // }
190
+ // }
191
+ // }
192
+ // }
193
+
194
+ // The following are unrestricted scanning areas
195
+ if (this.props.isRepeatScan) {
196
+ Vibration.vibrate();
197
+ this.props.onRead(e);
198
+ } else {
199
+ if (!this.isShowCode) {
200
+ this.isShowCode = true;
201
+ Vibration.vibrate();
202
+ this.props.onRead(e);
203
+ }
204
+ }
205
+ };
206
+
207
+ _handleBarCodeRead = e => {
208
+ switch (Platform.OS) {
209
+ case "ios":
210
+ this.iosBarCode(e);
211
+ break;
212
+ case "android":
213
+ this.androidBarCode(e);
214
+ break;
215
+ default:
216
+ break;
217
+ }
218
+ };
219
+ }
220
+
221
+ const styles = StyleSheet.create({
222
+ topButtonsContainer: {
223
+ position: "absolute",
224
+ height: 100,
225
+ top: 0,
226
+ left: 0,
227
+ right: 0
228
+ },
229
+ bottomButtonsContainer: {
230
+ position: "absolute",
231
+ height: 100,
232
+ bottom: 0,
233
+ left: 0,
234
+ right: 0
235
+ },
236
+ authorizationContainer: {
237
+ flex: 1,
238
+ alignItems: "center",
239
+ justifyContent: "center"
240
+ },
241
+ notAuthorizedText: {
242
+ textAlign: "center",
243
+ fontSize: 16
244
+ }
245
+ });
246
+
247
+ QRScanner.propTypes = {
248
+ isRepeatScan: PropTypes.bool,
249
+ onRead: PropTypes.func,
250
+ maskColor: PropTypes.string,
251
+ borderColor: PropTypes.string,
252
+ cornerColor: PropTypes.string,
253
+ borderWidth: PropTypes.number,
254
+ cornerBorderWidth: PropTypes.number,
255
+ cornerBorderLength: PropTypes.number,
256
+ rectHeight: PropTypes.number,
257
+ rectWidth: PropTypes.number,
258
+ isCornerOffset: PropTypes.bool, //Whether the corners are offset
259
+ cornerOffsetSize: PropTypes.number,
260
+ bottomHeight: PropTypes.number,
261
+ scanBarAnimateTime: PropTypes.number,
262
+ scanBarColor: PropTypes.string,
263
+ scanBarImage: PropTypes.any,
264
+ scanBarHeight: PropTypes.number,
265
+ scanBarMargin: PropTypes.number,
266
+ hintText: PropTypes.string,
267
+ hintTextStyle: PropTypes.object,
268
+ hintTextPosition: PropTypes.number,
269
+ renderTopView: PropTypes.func,
270
+ renderBottomView: PropTypes.func,
271
+ isShowScanBar: PropTypes.bool,
272
+ topViewStyle: PropTypes.object,
273
+ bottomViewStyle: PropTypes.object,
274
+ flashMode: PropTypes.bool,
275
+ finderX: PropTypes.number,
276
+ finderY: PropTypes.number,
277
+ zoom: PropTypes.number,
278
+ translucent: PropTypes.bool,
279
+ cameraType: PropTypes.string,
280
+ vibrate: PropTypes.bool,
281
+ };
@@ -0,0 +1,381 @@
1
+ import React, {Component} from 'react';
2
+ import {
3
+ ActivityIndicator,
4
+ StyleSheet,
5
+ View,
6
+ Animated,
7
+ Easing,
8
+ Text,
9
+ Image,
10
+ Vibration,
11
+ Platform,
12
+ PixelRatio,
13
+ StatusBar
14
+ } from 'react-native';
15
+ /**
16
+ * Scanning Interface Mask
17
+ * Write a separate class for easy copying
18
+ */
19
+ export default class QRScannerView extends Component {
20
+ static defaultProps = {
21
+ maskColor: '#0000004D',
22
+ cornerColor: '#22ff00',
23
+ borderColor: '#000000',
24
+ rectHeight: 200,
25
+ rectWidth: 200,
26
+ borderWidth: 0,
27
+ cornerBorderWidth: 4,
28
+ cornerBorderLength: 20,
29
+ cornerOffsetSize: 1,
30
+ isCornerOffset: true,
31
+ bottomHeight: 100,
32
+ scanBarAnimateTime: 2500,
33
+ scanBarColor: '#22ff00',
34
+ scanBarImage: null,
35
+ scanBarHeight: 1.5,
36
+ scanBarMargin: 6,
37
+ hintText: 'Put the QR code / bar code into the box and it will scan automatically',
38
+ hintTextStyle: {
39
+ color: '#fff',
40
+ fontSize: 14,
41
+ backgroundColor: 'transparent'
42
+ },
43
+ hintTextPosition: 130,
44
+ isShowScanBar: true
45
+ };
46
+
47
+ constructor(props) {
48
+ super(props);
49
+ this.state = {
50
+ topWidth: 0,
51
+ topHeight: 0,
52
+ leftWidth: 0,
53
+ animatedValue: new Animated.Value(0)
54
+ }
55
+ this.isClosed = false;
56
+ }
57
+
58
+ //Get background color
59
+ getBackgroundColor = () => {
60
+ return ({backgroundColor: this.props.maskColor});
61
+ }
62
+
63
+ //Get scan box background size
64
+ getRectSize = () => {
65
+ return ({height: this.props.rectHeight, width: this.props.rectWidth});
66
+ }
67
+
68
+ //Get scan frame border size
69
+
70
+ getBorderSize = () => {
71
+ if (this.props.isCornerOffset) {
72
+ return ({
73
+ height: this.props.rectHeight - this.props.cornerOffsetSize * 2,
74
+ width: this.props.rectWidth - this.props.cornerOffsetSize * 2
75
+ });
76
+ } else {
77
+ return ({height: this.props.rectHeight, width: this.props.rectWidth});
78
+ }
79
+ }
80
+
81
+ //Get the color of the corner of the scan frame
82
+ getCornerColor = () => {
83
+ return ({borderColor: this.props.cornerColor});
84
+ }
85
+
86
+ //Get the size of the corner of the scan frame
87
+ getCornerSize = () => {
88
+ return ({height: this.props.cornerBorderLength, width: this.props.cornerBorderLength});
89
+ }
90
+
91
+ //Get scan frame size
92
+ getBorderWidth = () => {
93
+ return ({borderWidth: this.props.borderWidth});
94
+ }
95
+
96
+ //Get scan box color
97
+ getBorderColor = () => {
98
+ return ({borderColor: this.props.borderColor});
99
+ }
100
+
101
+ //Measure the size of the entire scanning component
102
+ measureTotalSize = (e) => {
103
+ let totalSize = e.layout;
104
+ this.setState({topWidth: totalSize.width})
105
+ }
106
+
107
+ //Measure the position of the scan frame
108
+ measureRectPosition = (e) => {
109
+ let rectSize = e.layout;
110
+ rectSize.x += this.props.finderX
111
+ rectSize.y += this.props.finderY
112
+ this.props.returnSize(rectSize)
113
+ this.setState({topHeight: rectSize.y, leftWidth: rectSize.x})
114
+ }
115
+
116
+ //Get top mask height
117
+ getTopMaskHeight = () => {
118
+ if (this.props.isCornerOffset) {
119
+ return this.state.topHeight + this.props.rectHeight - this.props.cornerOffsetSize;
120
+ } else {
121
+ return this.state.topHeight + this.props.rectHeight;
122
+ }
123
+ }
124
+
125
+ //Get bottom mask height
126
+ getBottomMaskHeight = () => {
127
+ if (this.props.isCornerOffset) {
128
+ return this.props.rectHeight + this.state.topHeight - this.props.cornerOffsetSize;
129
+ } else {
130
+ return this.state.topHeight + this.props.rectHeight;
131
+ }
132
+ }
133
+
134
+ //Get the left and right mask height
135
+ getSideMaskHeight = () => {
136
+ if (this.props.isCornerOffset) {
137
+ return this.props.rectHeight - this.props.cornerOffsetSize * 2;
138
+ } else {
139
+ return this.props.rectHeight;
140
+ }
141
+ }
142
+
143
+ //Get left and right mask width
144
+ getSideMaskWidth = () => {
145
+ if (this.props.isCornerOffset) {
146
+ return this.state.leftWidth + this.props.cornerOffsetSize;
147
+ } else {
148
+ return this.state.leftWidth;
149
+ }
150
+ }
151
+
152
+ getBottomHeight = () => {
153
+ return ({bottom: this.props.bottomHeight});
154
+ }
155
+
156
+ getScanBarMargin = () => {
157
+ return ({marginRight: this.props.scanBarMargin, marginLeft: this.props.scanBarMargin})
158
+ }
159
+
160
+ getScanImageWidth = () => {
161
+ return this.props.rectWidth - this.props.scanBarMargin * 2
162
+ }
163
+
164
+ //Draw scan lines
165
+ _renderScanBar = () => {
166
+ if (!this.props.isShowScanBar)
167
+ return;
168
+ if (this.props.scanBarImage) {
169
+ return <Image
170
+ style={{
171
+ resizeMode: 'contain',
172
+ width: this.getScanImageWidth(),
173
+ height:this.props.scanBarHeight
174
+ }}
175
+ source={this.props.scanBarImage}/>
176
+ } else {
177
+ return <View
178
+ style={[
179
+ this.getScanBarMargin(), {
180
+ backgroundColor: this.props.scanBarColor,
181
+ height: this.props.scanBarHeight
182
+ }
183
+ ]}/>
184
+ }
185
+ }
186
+
187
+ render() {
188
+ const animatedStyle = {
189
+ transform: [
190
+ {
191
+ translateY: this.state.animatedValue
192
+ }
193
+ ]
194
+ };
195
+ return (
196
+ <View
197
+ onLayout={({nativeEvent: e}) => this.measureTotalSize(e)}
198
+ style={[
199
+ styles.container, this.getBottomHeight()
200
+ ]}>
201
+ {/* <View style={{flex:1}}></View> */}
202
+ <View
203
+ style={[
204
+ styles.viewfinder, this.getRectSize(),{top:this.props.finderY,left:this.props.finderX}
205
+ ]}
206
+ onLayout={({nativeEvent: e}) => this.measureRectPosition(e)}>
207
+ <View
208
+ style={[
209
+ this.getBorderSize(),
210
+ this.getBorderColor(),
211
+ this.getBorderWidth()
212
+ ]}>
213
+
214
+ <Animated.View style={[animatedStyle]}>
215
+ {this._renderScanBar()}
216
+ </Animated.View>
217
+
218
+ </View>
219
+ <View
220
+ style={[
221
+ this.getCornerColor(),
222
+ this.getCornerSize(),
223
+ styles.topLeftCorner, {
224
+ borderLeftWidth: this.props.cornerBorderWidth,
225
+ borderTopWidth: this.props.cornerBorderWidth
226
+ }
227
+ ]}/>
228
+ <View
229
+ style={[
230
+ this.getCornerColor(),
231
+ this.getCornerSize(),
232
+ styles.topRightCorner, {
233
+ borderRightWidth: this.props.cornerBorderWidth,
234
+ borderTopWidth: this.props.cornerBorderWidth
235
+ }
236
+ ]}/>
237
+ <View
238
+ style={[
239
+ this.getCornerColor(),
240
+ this.getCornerSize(),
241
+ styles.bottomLeftCorner, {
242
+ borderLeftWidth: this.props.cornerBorderWidth,
243
+ borderBottomWidth: this.props.cornerBorderWidth
244
+ }
245
+ ]}/>
246
+ <View
247
+ style={[
248
+ this.getCornerColor(),
249
+ this.getCornerSize(),
250
+ styles.bottomRightCorner, {
251
+ borderRightWidth: this.props.cornerBorderWidth,
252
+ borderBottomWidth: this.props.cornerBorderWidth
253
+ }
254
+ ]}/>
255
+ </View>
256
+
257
+ <View
258
+ style={[
259
+ this.getBackgroundColor(),
260
+ styles.topMask, {
261
+ bottom: this.getTopMaskHeight() - this.props.finderY * 3,
262
+ top: 0,
263
+ width: this.state.topWidth
264
+ }
265
+ ]
266
+ }/>
267
+
268
+ <View
269
+ style={[
270
+ this.getBackgroundColor(),
271
+ styles.leftMask, {
272
+ height: this.getSideMaskHeight(),
273
+ width: this.getSideMaskWidth() - this.props.finderX ,
274
+ bottom: this.getTopMaskHeight() - this.props.finderY * 3 - this.getSideMaskHeight()
275
+ }
276
+ ]}/>
277
+
278
+ <View
279
+ style={[
280
+ this.getBackgroundColor(),
281
+ styles.rightMask, {
282
+ height: this.getSideMaskHeight(),
283
+ width: this.getSideMaskWidth() - this.props.finderX * 3,
284
+ bottom: this.getTopMaskHeight() - this.props.finderY * 3 - this.getSideMaskHeight()
285
+ }
286
+ ]}/>
287
+
288
+ <View
289
+ style={[
290
+ this.getBackgroundColor(),
291
+ styles.bottomMask, {
292
+ top: this.getBottomMaskHeight() - this.props.finderY,
293
+ width: this.state.topWidth
294
+ }
295
+ ]}/>
296
+
297
+ <View
298
+ style={{
299
+ position: 'absolute',
300
+ bottom: this.props.hintTextPosition
301
+ }}>
302
+ <Text style={[this.props.hintTextStyle,{top:this.props.finderY,left:this.props.finderX}]}>{this.props.hintText}</Text>
303
+ </View>
304
+
305
+ </View>
306
+ );
307
+ }
308
+
309
+ componentDidMount() {
310
+ this.scannerLineMove();
311
+ }
312
+
313
+ componentWillUnmount() {
314
+ this.isClosed = true;
315
+ }
316
+
317
+ scannerLineMove() {
318
+ if (this.isClosed) {
319
+ return;
320
+ }
321
+ this.state.animatedValue.setValue(0); //重置Rotate动画值为0
322
+ Animated.timing(
323
+ this.state.animatedValue,
324
+ {toValue: this.props.rectHeight,
325
+ duration: this.props.scanBarAnimateTime,
326
+ easing: Easing.linear,
327
+ useNativeDriver: true
328
+ }).start(() => this.scannerLineMove());
329
+ }
330
+ }
331
+
332
+ const styles = StyleSheet.create({
333
+ container: {
334
+ alignItems: 'center',
335
+ justifyContent: 'center',
336
+ position: 'absolute',
337
+ top: 0,
338
+ right: 0,
339
+ left: 0,
340
+ },
341
+ viewfinder: {
342
+ alignItems: 'center',
343
+ justifyContent: 'center'
344
+ },
345
+ topLeftCorner: {
346
+ position: 'absolute',
347
+ top: 0,
348
+ left: 0
349
+ },
350
+ topRightCorner: {
351
+ position: 'absolute',
352
+ top: 0,
353
+ right: 0
354
+ },
355
+ bottomLeftCorner: {
356
+ position: 'absolute',
357
+ bottom: 0,
358
+ left: 0
359
+ },
360
+ bottomRightCorner: {
361
+ position: 'absolute',
362
+ bottom: 0,
363
+ right: 0
364
+ },
365
+ topMask: {
366
+ position: 'absolute',
367
+ top: 0
368
+ },
369
+ leftMask: {
370
+ position: 'absolute',
371
+ left: 0
372
+ },
373
+ rightMask: {
374
+ position: 'absolute',
375
+ right: 0
376
+ },
377
+ bottomMask: {
378
+ position: 'absolute',
379
+ bottom: 0
380
+ }
381
+ });