react-native-rectangle-doc-scanner 0.64.0 → 0.65.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.
package/src/external.d.ts CHANGED
@@ -1,78 +1,46 @@
1
- declare module 'react-native-vision-camera' {
1
+ declare module 'react-native-document-scanner-plugin' {
2
2
  import type { ComponentType } from 'react';
3
3
  import type { ViewStyle } from 'react-native';
4
4
 
5
- export type CameraDevice = {
6
- id: string;
7
- name: string;
8
- } | null;
9
-
10
- export type Frame = {
11
- width: number;
12
- height: number;
5
+ export type RectangleCoordinates = {
6
+ topLeft: { x: number; y: number };
7
+ topRight: { x: number; y: number };
8
+ bottomRight: { x: number; y: number };
9
+ bottomLeft: { x: number; y: number };
13
10
  };
14
11
 
15
- export type TakePhotoOptions = {
16
- qualityPrioritization?: 'balanced' | 'quality' | 'speed';
12
+ export type RectangleEvent = {
13
+ rectangleCoordinates?: RectangleCoordinates;
14
+ stableCounter?: number;
15
+ lastDetectionType?: 'initial' | 'updated' | 'lost';
17
16
  };
18
17
 
19
- export type CameraRef = {
20
- takePhoto: (options?: TakePhotoOptions) => Promise<{
21
- path: string;
22
- }>;
18
+ export type CaptureResult = {
19
+ croppedImage?: string;
20
+ initialImage?: string;
21
+ width?: number;
22
+ height?: number;
23
23
  };
24
24
 
25
- export type CameraProps = {
26
- ref?: (value: CameraRef | null) => void;
25
+ export type DocumentScannerProps = {
26
+ ref?: (value: DocumentScannerHandle | null) => void;
27
27
  style?: ViewStyle;
28
- device: CameraDevice;
29
- isActive?: boolean;
30
- photo?: boolean;
31
- frameProcessor?: (frame: Frame) => void;
32
- frameProcessorFps?: number;
33
- };
34
-
35
- export const Camera: ComponentType<CameraProps>;
36
- export function useCameraDevice(position?: 'back' | 'front'): CameraDevice;
37
- export function useCameraPermission(): {
38
- hasPermission: boolean;
39
- requestPermission: () => Promise<void>;
40
- };
41
- export function useFrameProcessor(
42
- processor: (frame: Frame) => void,
43
- deps?: ReadonlyArray<unknown>
44
- ): (frame: Frame) => void;
45
- }
46
-
47
- declare module 'react-native-reanimated' {
48
- export function runOnJS<T extends (...args: any[]) => any>(fn: T): T;
49
- }
50
-
51
- declare module 'vision-camera-resize-plugin' {
52
- import type { Frame } from 'react-native-vision-camera';
53
-
54
- type ResizeOptions = {
55
- dataType: 'uint8';
56
- pixelFormat: 'bgr';
57
- scale: {
58
- width: number;
59
- height: number;
60
- };
28
+ overlayColor?: string;
29
+ detectionCountBeforeCapture?: number;
30
+ enableTorch?: boolean;
31
+ hideControls?: boolean;
32
+ useBase64?: boolean;
33
+ quality?: number;
34
+ onRectangleDetect?: (event: RectangleEvent) => void;
35
+ onPictureTaken?: (result: CaptureResult) => void;
61
36
  };
62
37
 
63
- export function useResizePlugin(): {
64
- resize: (frame: Frame, options: ResizeOptions) => ArrayBuffer;
38
+ export type DocumentScannerHandle = {
39
+ capture: () => Promise<CaptureResult>;
65
40
  };
66
- }
67
41
 
68
- declare module 'react-native-fast-opencv' {
69
- export const OpenCV: any;
70
- export const ColorConversionCodes: any;
71
- export const MorphTypes: any;
72
- export const MorphShapes: any;
73
- export const RetrievalModes: any;
74
- export const ContourApproximationModes: any;
75
- export const ObjectType: any;
42
+ const DocumentScanner: ComponentType<DocumentScannerProps>;
43
+ export default DocumentScanner;
76
44
  }
77
45
 
78
46
  declare module '@shopify/react-native-skia' {
@@ -3,21 +3,41 @@ import { View, StyleSheet, useWindowDimensions } from 'react-native';
3
3
  import { Canvas, Path, Skia } from '@shopify/react-native-skia';
4
4
  import type { Point } from '../types';
5
5
 
6
+ const lerp = (start: Point, end: Point, t: number): Point => ({
7
+ x: start.x + (end.x - start.x) * t,
8
+ y: start.y + (end.y - start.y) * t,
9
+ });
10
+
6
11
  type OverlayProps = {
7
12
  quad: Point[] | null;
8
13
  color?: string;
9
14
  frameSize: { width: number; height: number } | null;
15
+ showGrid?: boolean;
16
+ gridColor?: string;
17
+ gridLineWidth?: number;
18
+ };
19
+
20
+ type OverlayGeometry = {
21
+ outlinePath: ReturnType<typeof Skia.Path.Make> | null;
22
+ gridPaths: ReturnType<typeof Skia.Path.Make>[];
10
23
  };
11
24
 
12
- export const Overlay: React.FC<OverlayProps> = ({ quad, color = '#e7a649', frameSize }) => {
25
+ export const Overlay: React.FC<OverlayProps> = ({
26
+ quad,
27
+ color = '#e7a649',
28
+ frameSize,
29
+ showGrid = true,
30
+ gridColor = 'rgba(231, 166, 73, 0.35)',
31
+ gridLineWidth = 2,
32
+ }) => {
13
33
  const { width: screenWidth, height: screenHeight } = useWindowDimensions();
14
34
 
15
- const path = useMemo(() => {
35
+ const { outlinePath, gridPaths }: OverlayGeometry = useMemo(() => {
16
36
  if (!quad || !frameSize) {
17
37
  if (__DEV__) {
18
38
  console.log('[Overlay] no quad or frameSize', { quad, frameSize });
19
39
  }
20
- return null;
40
+ return { outlinePath: null, gridPaths: [] };
21
41
  }
22
42
 
23
43
  if (__DEV__) {
@@ -76,8 +96,33 @@ export const Overlay: React.FC<OverlayProps> = ({ quad, color = '#e7a649', frame
76
96
  skPath.moveTo(transformedQuad[0].x, transformedQuad[0].y);
77
97
  transformedQuad.slice(1).forEach((p) => skPath.lineTo(p.x, p.y));
78
98
  skPath.close();
79
- return skPath;
80
- }, [quad, color, screenWidth, screenHeight, frameSize]);
99
+ const grid: ReturnType<typeof Skia.Path.Make>[] = [];
100
+
101
+ if (showGrid) {
102
+ const [topLeft, topRight, bottomRight, bottomLeft] = transformedQuad;
103
+ const steps = [1 / 3, 2 / 3];
104
+
105
+ steps.forEach((t) => {
106
+ const start = lerp(topLeft, topRight, t);
107
+ const end = lerp(bottomLeft, bottomRight, t);
108
+ const verticalPath = Skia.Path.Make();
109
+ verticalPath.moveTo(start.x, start.y);
110
+ verticalPath.lineTo(end.x, end.y);
111
+ grid.push(verticalPath);
112
+ });
113
+
114
+ steps.forEach((t) => {
115
+ const start = lerp(topLeft, bottomLeft, t);
116
+ const end = lerp(topRight, bottomRight, t);
117
+ const horizontalPath = Skia.Path.Make();
118
+ horizontalPath.moveTo(start.x, start.y);
119
+ horizontalPath.lineTo(end.x, end.y);
120
+ grid.push(horizontalPath);
121
+ });
122
+ }
123
+
124
+ return { outlinePath: skPath, gridPaths: grid };
125
+ }, [quad, screenWidth, screenHeight, frameSize, showGrid]);
81
126
 
82
127
  if (__DEV__) {
83
128
  console.log('[Overlay] rendering Canvas with dimensions:', screenWidth, 'x', screenHeight);
@@ -86,10 +131,20 @@ export const Overlay: React.FC<OverlayProps> = ({ quad, color = '#e7a649', frame
86
131
  return (
87
132
  <View style={styles.container} pointerEvents="none">
88
133
  <Canvas style={{ width: screenWidth, height: screenHeight }}>
89
- {path && (
134
+ {outlinePath && (
90
135
  <>
91
- <Path path={path} color={color} style="stroke" strokeWidth={8} />
92
- <Path path={path} color="rgba(231, 166, 73, 0.2)" style="fill" />
136
+ <Path path={outlinePath} color={color} style="stroke" strokeWidth={8} />
137
+ <Path path={outlinePath} color="rgba(231, 166, 73, 0.2)" style="fill" />
138
+ {gridPaths.map((gridPath, index) => (
139
+ <Path
140
+ // eslint-disable-next-line react/no-array-index-key
141
+ key={`grid-${index}`}
142
+ path={gridPath}
143
+ color={gridColor}
144
+ style="stroke"
145
+ strokeWidth={gridLineWidth}
146
+ />
147
+ ))}
93
148
  </>
94
149
  )}
95
150
  </Canvas>
@@ -1,8 +0,0 @@
1
- import type { DependencyList } from 'react';
2
-
3
- declare module 'react-native-worklets-core' {
4
- export function useRunOnJS<T extends (...args: any[]) => any>(
5
- callback: T,
6
- deps: DependencyList
7
- ): (...args: Parameters<T>) => void;
8
- }