1
- import { useCallback , useEffect , useMemo , useRef } from 'react' ;
1
+ import { useCallback , useEffect , useRef } from 'react' ;
2
2
import { Platform } from 'react-native' ;
3
3
4
4
import { utils } from '@monkvision/toolkit' ;
@@ -15,6 +15,27 @@ const diff = 1;
15
15
const imageType = utils . supportsWebP ? 'image/webp' : 'image/jpeg' ;
16
16
const imageFilenameExtension = imageType . substring ( 'image/' . length ) ;
17
17
18
+ function calculateCanvasResolution ( resolutionWidth , resolutionHeight , videoWidth , videoHeight ) {
19
+ let calculationRatio = 1 ;
20
+ let canvasWidth = resolutionWidth ;
21
+ let canvasHeight = resolutionHeight ;
22
+
23
+ if ( videoWidth && videoHeight ) {
24
+ const videoAspectRatio = ( videoWidth / videoHeight ) . toFixed ( 2 ) ;
25
+ const canvasAspectRatio = ( resolutionWidth / resolutionHeight ) . toFixed ( 2 ) ;
26
+
27
+ if ( videoAspectRatio !== canvasAspectRatio ) {
28
+ const widthRatio = resolutionWidth / videoWidth ;
29
+ const heightRatio = resolutionHeight / videoHeight ;
30
+ calculationRatio = ( widthRatio < heightRatio ) ? widthRatio : heightRatio ;
31
+ canvasWidth = Math . ceil ( videoWidth * calculationRatio ) ;
32
+ canvasHeight = Math . ceil ( videoHeight * calculationRatio ) ;
33
+ }
34
+ }
35
+
36
+ return { canvasWidth, canvasHeight } ;
37
+ }
38
+
18
39
/**
19
40
* `useCamera` is a hook that takes the `canvasResolution` which holds the dimensions of the canvas,
20
41
* and an object `options`, containing getUserMedia constraints and `onCameraReady`.
@@ -48,29 +69,16 @@ export default function useCamera({
48
69
}
49
70
} , [ stream , error ] ) ;
50
71
51
- const canvasResolution = useMemo ( ( ) => {
52
- let calculationRatio = 1 ;
53
- let canvasWidth = width ;
54
- let canvasHeight = height ;
55
-
56
- if ( videoRef . current && videoRef . current ?. videoWidth && videoRef . current ?. videoHeight ) {
57
- const { videoWidth, videoHeight } = videoRef . current ;
58
- const videoAspectRatio = ( videoWidth / videoHeight ) . toFixed ( 2 ) ;
59
- const canvasAspectRatio = ( width / height ) . toFixed ( 2 ) ;
60
-
61
- if ( videoAspectRatio !== canvasAspectRatio ) {
62
- const widthRatio = width / videoWidth ;
63
- const heightRatio = height / videoHeight ;
64
- calculationRatio = ( widthRatio < heightRatio ) ? widthRatio : heightRatio ;
65
- canvasWidth = Math . ceil ( videoWidth * calculationRatio ) ;
66
- canvasHeight = Math . ceil ( videoHeight * calculationRatio ) ;
67
- }
68
- }
69
-
70
- return { canvasWidth, canvasHeight } ;
71
- } , [ width , height , stream ] ) ;
72
-
73
72
const takePicture = useCallback ( async ( ) => {
73
+ if ( ! videoRef ?. current ?. videoWidth || ! videoRef ?. current ?. videoHeight ) {
74
+ throw new Error ( 'Video width or height not defined' ) ;
75
+ }
76
+ const canvasResolution = calculateCanvasResolution (
77
+ width ,
78
+ height ,
79
+ videoRef . current . videoWidth ,
80
+ videoRef . current . videoHeight ,
81
+ ) ;
74
82
if ( ! videoRef . current || ! stream ) { throw new Error ( 'Camera is not ready!' ) ; }
75
83
76
84
// create and use the separate canvas for each sight pic
@@ -100,7 +108,7 @@ export default function useCamera({
100
108
}
101
109
102
110
return { uri, canvasWidth, canvasHeight, imageType, imageFilenameExtension } ;
103
- } , [ canvasResolution , stream ] ) ;
111
+ } , [ stream , width , height ] ) ;
104
112
105
113
const resumePreview = async ( ) => {
106
114
if ( videoRef . current ) { videoRef . current . play ( ) ; }
0 commit comments