react-native-rectangle-doc-scanner 3.35.0 → 3.37.0

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.
@@ -117,12 +117,26 @@ const CropEditor = ({ document, overlayColor = 'rgba(0,0,0,0.5)', overlayStrokeC
117
117
  };
118
118
  onCropChange?.(rect);
119
119
  }, [imageSize, onCropChange]);
120
- const imageUri = `file://${document.path}`;
120
+ // Ensure proper file URI format
121
+ const imageUri = document.path.startsWith('file://')
122
+ ? document.path
123
+ : `file://${document.path}`;
124
+ const initialRect = getInitialRectangle();
125
+ console.log('[CropEditor] Rendering with:', {
126
+ imageUri,
127
+ imageSize,
128
+ displaySize,
129
+ initialRect,
130
+ isLoading: isImageLoading,
131
+ hasError: !!loadError,
132
+ });
121
133
  return (react_1.default.createElement(react_native_1.View, { style: styles.container, onLayout: handleLayout }, loadError ? (react_1.default.createElement(react_native_1.View, { style: styles.errorContainer },
122
134
  react_1.default.createElement(react_native_1.Text, { style: styles.errorText }, "Failed to load image"),
123
135
  react_1.default.createElement(react_native_1.Text, { style: styles.errorPath }, imageUri))) : !imageSize || isImageLoading ? (react_1.default.createElement(react_native_1.View, { style: styles.loadingContainer },
124
136
  react_1.default.createElement(react_native_1.ActivityIndicator, { size: "large", color: handlerColor }),
125
- react_1.default.createElement(react_native_1.Text, { style: styles.loadingText }, "Loading image..."))) : (react_1.default.createElement(react_native_perspective_image_cropper_1.default, { height: displaySize.height, width: displaySize.width, image: imageUri, rectangleCoordinates: getInitialRectangle(), overlayColor: overlayColor, overlayStrokeColor: overlayStrokeColor, handlerColor: handlerColor, enablePanStrict: enablePanStrict, onDragEnd: handleDragEnd }))));
137
+ react_1.default.createElement(react_native_1.Text, { style: styles.loadingText }, "Loading image..."))) : (react_1.default.createElement(react_1.default.Fragment, null,
138
+ react_1.default.createElement(react_native_perspective_image_cropper_1.default, { height: displaySize.height, width: displaySize.width, image: imageUri, rectangleCoordinates: initialRect, overlayColor: overlayColor, overlayStrokeColor: overlayStrokeColor, handlerColor: handlerColor, enablePanStrict: enablePanStrict, onDragEnd: handleDragEnd }),
139
+ react_1.default.createElement(react_native_1.Image, { source: { uri: imageUri }, style: styles.debugImage, onLoad: () => console.log('[CropEditor] Debug image loaded'), onError: (e) => console.error('[CropEditor] Debug image error:', e.nativeEvent.error) })))));
126
140
  };
127
141
  exports.CropEditor = CropEditor;
128
142
  const styles = react_native_1.StyleSheet.create({
@@ -157,10 +171,14 @@ const styles = react_native_1.StyleSheet.create({
157
171
  fontSize: 12,
158
172
  textAlign: 'center',
159
173
  },
160
- hiddenImage: {
161
- width: 1,
162
- height: 1,
163
- opacity: 0,
174
+ debugImage: {
164
175
  position: 'absolute',
176
+ width: 100,
177
+ height: 100,
178
+ top: 10,
179
+ right: 10,
180
+ opacity: 0.5,
181
+ borderWidth: 2,
182
+ borderColor: 'red',
165
183
  },
166
184
  });
@@ -69,13 +69,13 @@ const FullDocScanner = ({ onResult, onClose, detectionConfig, overlayColor = '#3
69
69
  const processingCaptureRef = (0, react_1.useRef)(false);
70
70
  const cropInitializedRef = (0, react_1.useRef)(false);
71
71
  const mergedStrings = (0, react_1.useMemo)(() => ({
72
- captureHint: strings?.captureHint ?? 'Align the document within the frame.',
73
- manualHint: strings?.manualHint ?? 'Tap the button below to capture.',
74
- cancel: strings?.cancel ?? 'Cancel',
75
- confirm: strings?.confirm ?? 'Use photo',
76
- retake: strings?.retake ?? 'Retake',
77
- cropTitle: strings?.cropTitle ?? 'Adjust the corners',
78
- processing: strings?.processing ?? 'Processing…',
72
+ captureHint: strings?.captureHint ?? '',
73
+ manualHint: strings?.manualHint ?? '',
74
+ cancel: strings?.cancel ?? '',
75
+ confirm: strings?.confirm ?? '',
76
+ retake: strings?.retake ?? '',
77
+ cropTitle: strings?.cropTitle ?? '',
78
+ processing: strings?.processing ?? '',
79
79
  }), [strings]);
80
80
  (0, react_1.useEffect)(() => {
81
81
  if (!capturedDoc) {
@@ -205,27 +205,16 @@ const FullDocScanner = ({ onResult, onClose, detectionConfig, overlayColor = '#3
205
205
  return;
206
206
  }
207
207
  const normalizedDoc = normalizeCapturedDocument(document);
208
- const wantsManualFlow = manualCapture || manualCapturePending.current || document.origin === 'manual';
209
- console.log('[FullDocScanner] wantsManualFlow:', wantsManualFlow, {
210
- manualCapture,
211
- manualCapturePending: manualCapturePending.current,
212
- origin: document.origin,
213
- });
214
- if (wantsManualFlow) {
215
- console.log('[FullDocScanner] Starting manual flow - showing crop editor');
216
- manualCapturePending.current = false;
217
- processingCaptureRef.current = false;
218
- cropInitializedRef.current = false;
219
- setCapturedDoc(normalizedDoc);
220
- setImageSize(null);
221
- setCropRectangle(null);
222
- setScreen('crop');
223
- return;
224
- }
225
- console.log('[FullDocScanner] Starting auto flow - processing capture');
226
- processingCaptureRef.current = true;
227
- processAutoCapture(document);
228
- }, [manualCapture, processAutoCapture]);
208
+ // 자동 촬영이든 수동 촬영이든 모두 crop 화면으로 이동
209
+ console.log('[FullDocScanner] Moving to crop/preview screen');
210
+ manualCapturePending.current = false;
211
+ processingCaptureRef.current = false;
212
+ cropInitializedRef.current = false;
213
+ setCapturedDoc(normalizedDoc);
214
+ setImageSize(null);
215
+ setCropRectangle(null);
216
+ setScreen('crop');
217
+ }, []);
229
218
  const handleCropChange = (0, react_1.useCallback)((rectangle) => {
230
219
  setCropRectangle(rectangle);
231
220
  }, []);
@@ -325,25 +314,25 @@ const FullDocScanner = ({ onResult, onClose, detectionConfig, overlayColor = '#3
325
314
  }, [onClose, resetState]);
326
315
  return (react_1.default.createElement(react_native_1.View, { style: styles.container },
327
316
  screen === 'scanner' && (react_1.default.createElement(react_native_1.View, { style: styles.flex },
328
- react_1.default.createElement(DocScanner_1.DocScanner, { ref: docScannerRef, autoCapture: !manualCapture, overlayColor: overlayColor, showGrid: showGrid, gridColor: resolvedGridColor, gridLineWidth: gridLineWidth, minStableFrames: minStableFrames ?? 6, detectionConfig: detectionConfig, onCapture: handleCapture, showManualCaptureButton: true },
329
- react_1.default.createElement(react_native_1.View, { style: styles.overlay, pointerEvents: "box-none" },
317
+ react_1.default.createElement(DocScanner_1.DocScanner, { ref: docScannerRef, autoCapture: !manualCapture, overlayColor: overlayColor, showGrid: showGrid, gridColor: resolvedGridColor, gridLineWidth: gridLineWidth, minStableFrames: minStableFrames ?? 6, detectionConfig: detectionConfig, onCapture: handleCapture, showManualCaptureButton: false },
318
+ react_1.default.createElement(react_native_1.View, { style: styles.overlayTop, pointerEvents: "box-none" },
330
319
  react_1.default.createElement(react_native_1.TouchableOpacity, { style: styles.closeButton, onPress: handleClose, accessibilityLabel: mergedStrings.cancel, accessibilityRole: "button" },
331
- react_1.default.createElement(react_native_1.Text, { style: styles.closeButtonLabel }, "\u00D7")),
332
- react_1.default.createElement(react_native_1.View, { style: styles.instructions, pointerEvents: "none" },
333
- react_1.default.createElement(react_native_1.Text, { style: styles.captureText }, mergedStrings.captureHint),
334
- react_1.default.createElement(react_native_1.Text, { style: styles.captureText }, mergedStrings.manualHint)),
320
+ react_1.default.createElement(react_native_1.Text, { style: styles.closeButtonLabel }, "\u00D7"))),
321
+ (mergedStrings.captureHint || mergedStrings.manualHint) && (react_1.default.createElement(react_native_1.View, { style: styles.instructionsContainer, pointerEvents: "none" },
322
+ react_1.default.createElement(react_native_1.View, { style: styles.instructions },
323
+ mergedStrings.captureHint && (react_1.default.createElement(react_native_1.Text, { style: styles.captureText }, mergedStrings.captureHint)),
324
+ mergedStrings.manualHint && (react_1.default.createElement(react_native_1.Text, { style: styles.captureText }, mergedStrings.manualHint))))),
325
+ react_1.default.createElement(react_native_1.View, { style: styles.shutterContainer, pointerEvents: "box-none" },
335
326
  react_1.default.createElement(react_native_1.TouchableOpacity, { style: [styles.shutterButton, processing && styles.shutterButtonDisabled], onPress: triggerManualCapture, disabled: processing, accessibilityLabel: mergedStrings.manualHint, accessibilityRole: "button" },
336
327
  react_1.default.createElement(react_native_1.View, { style: styles.shutterInner })))))),
337
328
  screen === 'crop' && capturedDoc && (react_1.default.createElement(react_native_1.View, { style: styles.flex },
338
329
  react_1.default.createElement(CropEditor_1.CropEditor, { document: capturedDoc, overlayColor: "rgba(0,0,0,0.6)", overlayStrokeColor: overlayStrokeColor, handlerColor: handlerColor, onCropChange: handleCropChange }),
339
330
  react_1.default.createElement(react_native_1.View, { style: styles.cropFooter },
340
- react_1.default.createElement(react_native_1.TouchableOpacity, { style: [styles.actionButton, styles.secondaryButton], onPress: handleRetake },
341
- react_1.default.createElement(react_native_1.Text, { style: styles.buttonText }, mergedStrings.retake)),
342
- react_1.default.createElement(react_native_1.TouchableOpacity, { style: [styles.actionButton, styles.primaryButton], onPress: handleConfirm },
343
- react_1.default.createElement(react_native_1.Text, { style: styles.buttonText }, mergedStrings.confirm))))),
331
+ react_1.default.createElement(react_native_1.TouchableOpacity, { style: [styles.actionButton, styles.secondaryButton], onPress: handleRetake }, mergedStrings.retake && react_1.default.createElement(react_native_1.Text, { style: styles.buttonText }, mergedStrings.retake)),
332
+ react_1.default.createElement(react_native_1.TouchableOpacity, { style: [styles.actionButton, styles.primaryButton], onPress: handleConfirm }, mergedStrings.confirm && react_1.default.createElement(react_native_1.Text, { style: styles.buttonText }, mergedStrings.confirm))))),
344
333
  processing && (react_1.default.createElement(react_native_1.View, { style: styles.processingOverlay },
345
334
  react_1.default.createElement(react_native_1.ActivityIndicator, { size: "large", color: overlayStrokeColor }),
346
- react_1.default.createElement(react_native_1.Text, { style: styles.processingText }, mergedStrings.processing)))));
335
+ mergedStrings.processing && (react_1.default.createElement(react_native_1.Text, { style: styles.processingText }, mergedStrings.processing))))));
347
336
  };
348
337
  exports.FullDocScanner = FullDocScanner;
349
338
  const styles = react_native_1.StyleSheet.create({
@@ -354,12 +343,27 @@ const styles = react_native_1.StyleSheet.create({
354
343
  flex: {
355
344
  flex: 1,
356
345
  },
357
- overlay: {
358
- ...react_native_1.StyleSheet.absoluteFillObject,
359
- justifyContent: 'space-between',
360
- paddingTop: 48,
361
- paddingBottom: 64,
362
- paddingHorizontal: 24,
346
+ overlayTop: {
347
+ position: 'absolute',
348
+ top: 48,
349
+ right: 24,
350
+ zIndex: 10,
351
+ },
352
+ instructionsContainer: {
353
+ position: 'absolute',
354
+ top: '40%',
355
+ left: 0,
356
+ right: 0,
357
+ alignItems: 'center',
358
+ zIndex: 5,
359
+ },
360
+ shutterContainer: {
361
+ position: 'absolute',
362
+ bottom: 64,
363
+ left: 0,
364
+ right: 0,
365
+ alignItems: 'center',
366
+ zIndex: 10,
363
367
  },
364
368
  closeButton: {
365
369
  width: 40,
@@ -368,7 +372,6 @@ const styles = react_native_1.StyleSheet.create({
368
372
  backgroundColor: 'rgba(0,0,0,0.5)',
369
373
  justifyContent: 'center',
370
374
  alignItems: 'center',
371
- alignSelf: 'flex-end',
372
375
  },
373
376
  closeButtonLabel: {
374
377
  color: '#fff',
@@ -377,7 +380,6 @@ const styles = react_native_1.StyleSheet.create({
377
380
  marginTop: -3,
378
381
  },
379
382
  instructions: {
380
- alignSelf: 'center',
381
383
  backgroundColor: 'rgba(0,0,0,0.55)',
382
384
  borderRadius: 16,
383
385
  paddingHorizontal: 20,
@@ -389,7 +391,6 @@ const styles = react_native_1.StyleSheet.create({
389
391
  textAlign: 'center',
390
392
  },
391
393
  shutterButton: {
392
- alignSelf: 'center',
393
394
  width: 80,
394
395
  height: 80,
395
396
  borderRadius: 40,
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "react-native-rectangle-doc-scanner",
3
- "version": "3.35.0",
3
+ "version": "3.37.0",
4
4
  "description": "Native-backed document scanner for React Native with customizable overlays.",
5
5
  "license": "MIT",
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/index.d.ts",
8
8
  "repository": {
9
9
  "type": "git",
10
- "url": "https://github.com/danchew90/react-native-rectangle-doc-scanner.git"
10
+ "url": "git+https://github.com/danchew90/react-native-rectangle-doc-scanner.git"
11
11
  },
12
12
  "homepage": "https://github.com/danchew90/react-native-rectangle-doc-scanner",
13
13
  "bugs": {
@@ -120,7 +120,21 @@ export const CropEditor: React.FC<CropEditorProps> = ({
120
120
  onCropChange?.(rect);
121
121
  }, [imageSize, onCropChange]);
122
122
 
123
- const imageUri = `file://${document.path}`;
123
+ // Ensure proper file URI format
124
+ const imageUri = document.path.startsWith('file://')
125
+ ? document.path
126
+ : `file://${document.path}`;
127
+
128
+ const initialRect = getInitialRectangle();
129
+
130
+ console.log('[CropEditor] Rendering with:', {
131
+ imageUri,
132
+ imageSize,
133
+ displaySize,
134
+ initialRect,
135
+ isLoading: isImageLoading,
136
+ hasError: !!loadError,
137
+ });
124
138
 
125
139
  return (
126
140
  <View style={styles.container} onLayout={handleLayout}>
@@ -136,17 +150,26 @@ export const CropEditor: React.FC<CropEditorProps> = ({
136
150
  <Text style={styles.loadingText}>Loading image...</Text>
137
151
  </View>
138
152
  ) : (
139
- <CustomImageCropper
140
- height={displaySize.height}
141
- width={displaySize.width}
142
- image={imageUri}
143
- rectangleCoordinates={getInitialRectangle()}
144
- overlayColor={overlayColor}
145
- overlayStrokeColor={overlayStrokeColor}
146
- handlerColor={handlerColor}
147
- enablePanStrict={enablePanStrict}
148
- onDragEnd={handleDragEnd}
149
- />
153
+ <>
154
+ <CustomImageCropper
155
+ height={displaySize.height}
156
+ width={displaySize.width}
157
+ image={imageUri}
158
+ rectangleCoordinates={initialRect}
159
+ overlayColor={overlayColor}
160
+ overlayStrokeColor={overlayStrokeColor}
161
+ handlerColor={handlerColor}
162
+ enablePanStrict={enablePanStrict}
163
+ onDragEnd={handleDragEnd}
164
+ />
165
+ {/* Debug: Show image in background to verify it loads */}
166
+ <Image
167
+ source={{ uri: imageUri }}
168
+ style={styles.debugImage}
169
+ onLoad={() => console.log('[CropEditor] Debug image loaded')}
170
+ onError={(e) => console.error('[CropEditor] Debug image error:', e.nativeEvent.error)}
171
+ />
172
+ </>
150
173
  )}
151
174
  </View>
152
175
  );
@@ -184,10 +207,14 @@ const styles = StyleSheet.create({
184
207
  fontSize: 12,
185
208
  textAlign: 'center',
186
209
  },
187
- hiddenImage: {
188
- width: 1,
189
- height: 1,
190
- opacity: 0,
210
+ debugImage: {
191
211
  position: 'absolute',
212
+ width: 100,
213
+ height: 100,
214
+ top: 10,
215
+ right: 10,
216
+ opacity: 0.5,
217
+ borderWidth: 2,
218
+ borderColor: 'red',
192
219
  },
193
220
  });
@@ -122,15 +122,15 @@ export const FullDocScanner: React.FC<FullDocScannerProps> = ({
122
122
  const processingCaptureRef = useRef(false);
123
123
  const cropInitializedRef = useRef(false);
124
124
 
125
- const mergedStrings = useMemo<Required<FullDocScannerStrings>>(
125
+ const mergedStrings = useMemo(
126
126
  () => ({
127
- captureHint: strings?.captureHint ?? 'Align the document within the frame.',
128
- manualHint: strings?.manualHint ?? 'Tap the button below to capture.',
129
- cancel: strings?.cancel ?? 'Cancel',
130
- confirm: strings?.confirm ?? 'Use photo',
131
- retake: strings?.retake ?? 'Retake',
132
- cropTitle: strings?.cropTitle ?? 'Adjust the corners',
133
- processing: strings?.processing ?? 'Processing…',
127
+ captureHint: strings?.captureHint ?? '',
128
+ manualHint: strings?.manualHint ?? '',
129
+ cancel: strings?.cancel ?? '',
130
+ confirm: strings?.confirm ?? '',
131
+ retake: strings?.retake ?? '',
132
+ cropTitle: strings?.cropTitle ?? '',
133
+ processing: strings?.processing ?? '',
134
134
  }),
135
135
  [strings],
136
136
  );
@@ -323,32 +323,18 @@ export const FullDocScanner: React.FC<FullDocScannerProps> = ({
323
323
  }
324
324
 
325
325
  const normalizedDoc = normalizeCapturedDocument(document);
326
- const wantsManualFlow =
327
- manualCapture || manualCapturePending.current || document.origin === 'manual';
328
326
 
329
- console.log('[FullDocScanner] wantsManualFlow:', wantsManualFlow, {
330
- manualCapture,
331
- manualCapturePending: manualCapturePending.current,
332
- origin: document.origin,
333
- });
334
-
335
- if (wantsManualFlow) {
336
- console.log('[FullDocScanner] Starting manual flow - showing crop editor');
337
- manualCapturePending.current = false;
338
- processingCaptureRef.current = false;
339
- cropInitializedRef.current = false;
340
- setCapturedDoc(normalizedDoc);
341
- setImageSize(null);
342
- setCropRectangle(null);
343
- setScreen('crop');
344
- return;
345
- }
346
-
347
- console.log('[FullDocScanner] Starting auto flow - processing capture');
348
- processingCaptureRef.current = true;
349
- processAutoCapture(document);
327
+ // 자동 촬영이든 수동 촬영이든 모두 crop 화면으로 이동
328
+ console.log('[FullDocScanner] Moving to crop/preview screen');
329
+ manualCapturePending.current = false;
330
+ processingCaptureRef.current = false;
331
+ cropInitializedRef.current = false;
332
+ setCapturedDoc(normalizedDoc);
333
+ setImageSize(null);
334
+ setCropRectangle(null);
335
+ setScreen('crop');
350
336
  },
351
- [manualCapture, processAutoCapture],
337
+ [],
352
338
  );
353
339
 
354
340
  const handleCropChange = useCallback((rectangle: Rectangle) => {
@@ -491,9 +477,9 @@ export const FullDocScanner: React.FC<FullDocScannerProps> = ({
491
477
  minStableFrames={minStableFrames ?? 6}
492
478
  detectionConfig={detectionConfig}
493
479
  onCapture={handleCapture}
494
- showManualCaptureButton
480
+ showManualCaptureButton={false}
495
481
  >
496
- <View style={styles.overlay} pointerEvents="box-none">
482
+ <View style={styles.overlayTop} pointerEvents="box-none">
497
483
  <TouchableOpacity
498
484
  style={styles.closeButton}
499
485
  onPress={handleClose}
@@ -502,10 +488,20 @@ export const FullDocScanner: React.FC<FullDocScannerProps> = ({
502
488
  >
503
489
  <Text style={styles.closeButtonLabel}>×</Text>
504
490
  </TouchableOpacity>
505
- <View style={styles.instructions} pointerEvents="none">
506
- <Text style={styles.captureText}>{mergedStrings.captureHint}</Text>
507
- <Text style={styles.captureText}>{mergedStrings.manualHint}</Text>
491
+ </View>
492
+ {(mergedStrings.captureHint || mergedStrings.manualHint) && (
493
+ <View style={styles.instructionsContainer} pointerEvents="none">
494
+ <View style={styles.instructions}>
495
+ {mergedStrings.captureHint && (
496
+ <Text style={styles.captureText}>{mergedStrings.captureHint}</Text>
497
+ )}
498
+ {mergedStrings.manualHint && (
499
+ <Text style={styles.captureText}>{mergedStrings.manualHint}</Text>
500
+ )}
501
+ </View>
508
502
  </View>
503
+ )}
504
+ <View style={styles.shutterContainer} pointerEvents="box-none">
509
505
  <TouchableOpacity
510
506
  style={[styles.shutterButton, processing && styles.shutterButtonDisabled]}
511
507
  onPress={triggerManualCapture}
@@ -531,10 +527,10 @@ export const FullDocScanner: React.FC<FullDocScannerProps> = ({
531
527
  />
532
528
  <View style={styles.cropFooter}>
533
529
  <TouchableOpacity style={[styles.actionButton, styles.secondaryButton]} onPress={handleRetake}>
534
- <Text style={styles.buttonText}>{mergedStrings.retake}</Text>
530
+ {mergedStrings.retake && <Text style={styles.buttonText}>{mergedStrings.retake}</Text>}
535
531
  </TouchableOpacity>
536
532
  <TouchableOpacity style={[styles.actionButton, styles.primaryButton]} onPress={handleConfirm}>
537
- <Text style={styles.buttonText}>{mergedStrings.confirm}</Text>
533
+ {mergedStrings.confirm && <Text style={styles.buttonText}>{mergedStrings.confirm}</Text>}
538
534
  </TouchableOpacity>
539
535
  </View>
540
536
  </View>
@@ -543,7 +539,9 @@ export const FullDocScanner: React.FC<FullDocScannerProps> = ({
543
539
  {processing && (
544
540
  <View style={styles.processingOverlay}>
545
541
  <ActivityIndicator size="large" color={overlayStrokeColor} />
546
- <Text style={styles.processingText}>{mergedStrings.processing}</Text>
542
+ {mergedStrings.processing && (
543
+ <Text style={styles.processingText}>{mergedStrings.processing}</Text>
544
+ )}
547
545
  </View>
548
546
  )}
549
547
  </View>
@@ -558,12 +556,27 @@ const styles = StyleSheet.create({
558
556
  flex: {
559
557
  flex: 1,
560
558
  },
561
- overlay: {
562
- ...StyleSheet.absoluteFillObject,
563
- justifyContent: 'space-between',
564
- paddingTop: 48,
565
- paddingBottom: 64,
566
- paddingHorizontal: 24,
559
+ overlayTop: {
560
+ position: 'absolute',
561
+ top: 48,
562
+ right: 24,
563
+ zIndex: 10,
564
+ },
565
+ instructionsContainer: {
566
+ position: 'absolute',
567
+ top: '40%',
568
+ left: 0,
569
+ right: 0,
570
+ alignItems: 'center',
571
+ zIndex: 5,
572
+ },
573
+ shutterContainer: {
574
+ position: 'absolute',
575
+ bottom: 64,
576
+ left: 0,
577
+ right: 0,
578
+ alignItems: 'center',
579
+ zIndex: 10,
567
580
  },
568
581
  closeButton: {
569
582
  width: 40,
@@ -572,7 +585,6 @@ const styles = StyleSheet.create({
572
585
  backgroundColor: 'rgba(0,0,0,0.5)',
573
586
  justifyContent: 'center',
574
587
  alignItems: 'center',
575
- alignSelf: 'flex-end',
576
588
  },
577
589
  closeButtonLabel: {
578
590
  color: '#fff',
@@ -581,7 +593,6 @@ const styles = StyleSheet.create({
581
593
  marginTop: -3,
582
594
  },
583
595
  instructions: {
584
- alignSelf: 'center',
585
596
  backgroundColor: 'rgba(0,0,0,0.55)',
586
597
  borderRadius: 16,
587
598
  paddingHorizontal: 20,
@@ -593,7 +604,6 @@ const styles = StyleSheet.create({
593
604
  textAlign: 'center',
594
605
  },
595
606
  shutterButton: {
596
- alignSelf: 'center',
597
607
  width: 80,
598
608
  height: 80,
599
609
  borderRadius: 40,