@unif/react-native-camera 2.4.0 → 2.6.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.
- package/README.md +30 -6
- package/lib/module/camera/Camera.js +56 -26
- package/lib/module/camera/Camera.js.map +1 -1
- package/lib/module/camera/Container.js +4 -1
- package/lib/module/camera/Container.js.map +1 -1
- package/lib/module/index.js +0 -1
- package/lib/module/index.js.map +1 -1
- package/lib/module/mock.js +0 -3
- package/lib/module/mock.js.map +1 -1
- package/lib/module/utils/util.js +7 -1
- package/lib/module/utils/util.js.map +1 -1
- package/lib/typescript/src/camera/Camera.d.ts.map +1 -1
- package/lib/typescript/src/camera/Container.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +0 -1
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/mock.d.ts +0 -1
- package/lib/typescript/src/mock.d.ts.map +1 -1
- package/lib/typescript/src/utils/interface.d.ts +17 -3
- package/lib/typescript/src/utils/interface.d.ts.map +1 -1
- package/lib/typescript/src/utils/util.d.ts +2 -2
- package/lib/typescript/src/utils/util.d.ts.map +1 -1
- package/package.json +4 -2
- package/src/camera/Camera.tsx +65 -36
- package/src/camera/Container.tsx +4 -1
- package/src/index.tsx +0 -2
- package/src/mock.ts +0 -3
- package/src/utils/interface.ts +19 -3
- package/src/utils/util.ts +8 -1
package/README.md
CHANGED
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
```sh
|
|
12
12
|
yarn add @unif/react-native-camera \
|
|
13
13
|
react-native-vision-camera \
|
|
14
|
+
react-native-vision-camera-worklets \
|
|
14
15
|
react-native-nitro-modules \
|
|
15
16
|
react-native-nitro-image \
|
|
16
17
|
react-native-reanimated \
|
|
@@ -22,6 +23,12 @@ yarn add @unif/react-native-camera \
|
|
|
22
23
|
|
|
23
24
|
iOS 还需 `pod install`。
|
|
24
25
|
|
|
26
|
+
### 关于 `react-native-vision-camera-worklets`
|
|
27
|
+
|
|
28
|
+
vision-camera 5.x 把 Frame Processor / 多线程能力拆到了同伴包 `react-native-vision-camera-worklets`,并在内部通过懒 `require` 引用它。**即使本库不使用任何 Frame Processor**,消费端打包器(Metro 等)在静态解析阶段仍会解析 vision-camera 内部那处 `require`——缺失该包会直接报错:打包期 `Unable to resolve module react-native-vision-camera-worklets`,或运行时 `Cannot use Frame Processors - react-native-vision-camera-worklets is not installed`。
|
|
29
|
+
|
|
30
|
+
因此它是**必装的同伴包**,版本与 `react-native-vision-camera` 对齐(同为 `^5.x`)。vision-camera 自身未将其声明为 peer(视作可选),本库已在 `peerDependencies` 中显式声明,以提醒消费者一并安装。
|
|
31
|
+
|
|
25
32
|
### 权限配置
|
|
26
33
|
|
|
27
34
|
iOS `Info.plist`:
|
|
@@ -52,7 +59,7 @@ const App = () => {
|
|
|
52
59
|
<Text onPress={async () => {
|
|
53
60
|
const res = await api.open({
|
|
54
61
|
cameraMode: [
|
|
55
|
-
{ mode: 'single',
|
|
62
|
+
{ mode: 'single', quality: 0.9 },
|
|
56
63
|
{ mode: 'continuous' },
|
|
57
64
|
],
|
|
58
65
|
dataRetainedMode: 'clear',
|
|
@@ -87,9 +94,11 @@ const App = () => {
|
|
|
87
94
|
|
|
88
95
|
| 字段 | 类型 | 默认 | 说明 |
|
|
89
96
|
|---|---|---|---|
|
|
90
|
-
| `
|
|
91
|
-
| `
|
|
92
|
-
| `
|
|
97
|
+
| `type` | `'back' \| 'front'` | `back` | 初始前/后摄 |
|
|
98
|
+
| `flashMode` | `'auto' \| 'on' \| 'off'` | — | 初始闪光(保留作兼容;闪光实际由相机内 UI 控制) |
|
|
99
|
+
| `mode` | `'single' \| 'continuous' \| 'video'` | — | 拍摄模式 |
|
|
100
|
+
| `quality` | `number` | `0.9` | JPEG 压缩 0~1 |
|
|
101
|
+
| `recTime` | `number` | — | 录制时长上限(秒,video) |
|
|
93
102
|
|
|
94
103
|
### `CameraResult`
|
|
95
104
|
|
|
@@ -99,6 +108,21 @@ const App = () => {
|
|
|
99
108
|
| `data` | `CustomPhotoFile[]` | 拍摄的文件列表 |
|
|
100
109
|
| `message` | `string` | 描述信息 |
|
|
101
110
|
|
|
111
|
+
### `CustomPhotoFile`
|
|
112
|
+
|
|
113
|
+
| 字段 | 类型 | 说明 |
|
|
114
|
+
|---|---|---|
|
|
115
|
+
| `id` | `string` | 唯一 id |
|
|
116
|
+
| `cameraType` | `'back' \| 'front'` | 拍摄时的前/后摄 |
|
|
117
|
+
| `cameraMode` | `'single' \| 'continuous' \| 'video'` | 模式(原版字段名,= `mode`) |
|
|
118
|
+
| `path` | `string` | 本地文件路径 |
|
|
119
|
+
| `uri` | `string` | 文件 uri(`file://`) |
|
|
120
|
+
| `width` | `number` | 宽(px) |
|
|
121
|
+
| `height` | `number` | 高(px) |
|
|
122
|
+
| `mime` | `'image/jpeg' \| 'video/mp4'` | MIME 类型 |
|
|
123
|
+
| `mode` | `'single' \| 'continuous' \| 'video'` | 模式(2.x 字段名,= `cameraMode`) |
|
|
124
|
+
| `duration?` | `number` | 时长(秒,video) |
|
|
125
|
+
|
|
102
126
|
## 测试 (Mock)
|
|
103
127
|
|
|
104
128
|
本库依赖 `react-native-vision-camera` 等 native 模块,jest 环境无法直接加载。消费者在测试里 mock 本库:
|
|
@@ -115,7 +139,7 @@ mock 后 `useCamera()` 返回 `[api, null]`,`api.open` / `api.close` 是 `jest
|
|
|
115
139
|
const [api] = useCamera();
|
|
116
140
|
(api.open as jest.Mock).mockResolvedValueOnce({
|
|
117
141
|
code: 200,
|
|
118
|
-
data: [{ path: '/x.jpg', uri: 'file:///x.jpg', width: 1, height: 1, mime: 'image/jpeg', mode: 'single' }],
|
|
142
|
+
data: [{ id: '1700000000000-0', cameraType: 'back', cameraMode: 'single', path: '/x.jpg', uri: 'file:///x.jpg', width: 1, height: 1, mime: 'image/jpeg', mode: 'single' }],
|
|
119
143
|
message: 'ok',
|
|
120
144
|
});
|
|
121
145
|
```
|
|
@@ -126,7 +150,7 @@ const [api] = useCamera();
|
|
|
126
150
|
|
|
127
151
|
`v2.0.0` 的破坏性变更:
|
|
128
152
|
|
|
129
|
-
- 移除 `cameraMode[i].photoResolution` / `videoResolution` → 改用 `
|
|
153
|
+
- 移除 `cameraMode[i].photoResolution` / `videoResolution` → 改用 `quality`(0~1)控制 JPEG 压缩
|
|
130
154
|
- 移除 `watermark` 配置项(将在 v2.1.x 重新加入)
|
|
131
155
|
- 从顶层 `@unif/react-native-camera` 直接导入类型(不再走 `/lib/typescript/src/utils` deep path)
|
|
132
156
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
3
|
import { forwardRef, useCallback, useImperativeHandle, useRef, useState } from 'react';
|
|
4
|
-
import { StyleSheet, View } from 'react-native';
|
|
4
|
+
import { StyleSheet, useWindowDimensions, View } from 'react-native';
|
|
5
5
|
import { Camera as VisionCamera, useMicrophonePermission, usePhotoOutput, useVideoOutput } from 'react-native-vision-camera';
|
|
6
6
|
import { runOnJS, useSharedValue } from 'react-native-reanimated';
|
|
7
7
|
import { Gesture, GestureDetector } from 'react-native-gesture-handler';
|
|
@@ -19,6 +19,15 @@ export const Camera = /*#__PURE__*/forwardRef(function Camera({
|
|
|
19
19
|
zoomShared
|
|
20
20
|
}, ref) {
|
|
21
21
|
const cameraRef = useRef(null);
|
|
22
|
+
const cameraType = device.position === 'front' ? 'front' : 'back';
|
|
23
|
+
const {
|
|
24
|
+
width: screenW
|
|
25
|
+
} = useWindowDimensions();
|
|
26
|
+
// 取景框比例 = 输出照片比例(targetResolution):4:3→竖屏 高/宽=4/3, 16:9→16/9。
|
|
27
|
+
// 框比例 = 画面比例后,cover 不再裁两侧 → 预览 = 拍照(WYSIWYG)。
|
|
28
|
+
const frameRatio = (aspectRatio ?? '4:3') === '4:3' ? 4 / 3 : 16 / 9;
|
|
29
|
+
const frameW = screenW;
|
|
30
|
+
const frameH = screenW * frameRatio;
|
|
22
31
|
const targetResolution = (aspectRatio ?? '4:3') === '4:3' ? {
|
|
23
32
|
width: 1080,
|
|
24
33
|
height: 1440
|
|
@@ -27,8 +36,9 @@ export const Camera = /*#__PURE__*/forwardRef(function Camera({
|
|
|
27
36
|
height: 1920
|
|
28
37
|
};
|
|
29
38
|
const photoOutput = usePhotoOutput({
|
|
30
|
-
|
|
31
|
-
|
|
39
|
+
// 速度优先级对齐原版 4.x photoQualityBalance='speed'(写死);quality 用回原版字段
|
|
40
|
+
qualityPrioritization: 'speed',
|
|
41
|
+
quality: currentMode.quality ?? 0.9,
|
|
32
42
|
targetResolution
|
|
33
43
|
});
|
|
34
44
|
const videoOutput = useVideoOutput();
|
|
@@ -92,7 +102,7 @@ export const Camera = /*#__PURE__*/forwardRef(function Camera({
|
|
|
92
102
|
path: raw.path,
|
|
93
103
|
width: raw.width,
|
|
94
104
|
height: raw.height
|
|
95
|
-
}, currentMode.mode);
|
|
105
|
+
}, currentMode.mode, cameraType);
|
|
96
106
|
} catch (e) {
|
|
97
107
|
console.warn('capturePhoto failed', e);
|
|
98
108
|
return null;
|
|
@@ -115,7 +125,7 @@ export const Camera = /*#__PURE__*/forwardRef(function Camera({
|
|
|
115
125
|
path: filePath,
|
|
116
126
|
width: 0,
|
|
117
127
|
height: 0
|
|
118
|
-
}, 'video', true);
|
|
128
|
+
}, 'video', cameraType, true);
|
|
119
129
|
activeRecorderRef.current = null;
|
|
120
130
|
finishResolverRef.current?.(file);
|
|
121
131
|
finishResolverRef.current = null;
|
|
@@ -156,30 +166,50 @@ export const Camera = /*#__PURE__*/forwardRef(function Camera({
|
|
|
156
166
|
return null;
|
|
157
167
|
}
|
|
158
168
|
}
|
|
159
|
-
}), [photoOutput, videoOutput, currentMode.mode, hasMic, requestMic, flash]);
|
|
169
|
+
}), [photoOutput, videoOutput, currentMode.mode, hasMic, requestMic, flash, cameraType]);
|
|
160
170
|
const outputs = currentMode.mode === 'video' ? [videoOutput] : [photoOutput];
|
|
161
|
-
return /*#__PURE__*/_jsx(
|
|
162
|
-
|
|
163
|
-
children: /*#__PURE__*/
|
|
164
|
-
|
|
165
|
-
children:
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
isActive: isActive,
|
|
170
|
-
outputs: outputs,
|
|
171
|
-
constraints: [{
|
|
172
|
-
photoHDR: false
|
|
171
|
+
return /*#__PURE__*/_jsx(View, {
|
|
172
|
+
style: styles.root,
|
|
173
|
+
children: /*#__PURE__*/_jsx(GestureDetector, {
|
|
174
|
+
gesture: composed,
|
|
175
|
+
children: /*#__PURE__*/_jsxs(View, {
|
|
176
|
+
style: [styles.frame, {
|
|
177
|
+
width: frameW,
|
|
178
|
+
height: frameH
|
|
173
179
|
}],
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
180
|
+
children: [/*#__PURE__*/_jsx(VisionCamera, {
|
|
181
|
+
ref: cameraRef,
|
|
182
|
+
style: StyleSheet.absoluteFill,
|
|
183
|
+
resizeMode: "cover",
|
|
184
|
+
device: device,
|
|
185
|
+
isActive: isActive,
|
|
186
|
+
outputs: outputs,
|
|
187
|
+
constraints: [{
|
|
188
|
+
photoHDR: false
|
|
189
|
+
}],
|
|
190
|
+
zoom: zoom,
|
|
191
|
+
torchMode: currentMode.mode === 'video' && flash === 'on' ? 'on' : 'off',
|
|
192
|
+
onSubjectAreaChanged: () => cameraRef.current?.resetFocus(),
|
|
193
|
+
nativeID: "vision-camera"
|
|
194
|
+
}), focusPoint && /*#__PURE__*/_jsx(FocusIndicator, {
|
|
195
|
+
point: focusPoint,
|
|
196
|
+
onAnimationEnd: () => setFocusPoint(null)
|
|
197
|
+
}, `${focusPoint.x}-${focusPoint.y}`)]
|
|
198
|
+
})
|
|
182
199
|
})
|
|
183
200
|
});
|
|
184
201
|
});
|
|
202
|
+
const styles = StyleSheet.create({
|
|
203
|
+
// 全屏黑底,把取景框居中 → 框外区域是黑边(letterbox)。
|
|
204
|
+
root: {
|
|
205
|
+
...StyleSheet.absoluteFill,
|
|
206
|
+
backgroundColor: '#000',
|
|
207
|
+
alignItems: 'center',
|
|
208
|
+
justifyContent: 'center'
|
|
209
|
+
},
|
|
210
|
+
// overflow:hidden 裁掉 cover 溢出部分,框内只显示输出比例的画面。
|
|
211
|
+
frame: {
|
|
212
|
+
overflow: 'hidden'
|
|
213
|
+
}
|
|
214
|
+
});
|
|
185
215
|
//# sourceMappingURL=Camera.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["forwardRef","useCallback","useImperativeHandle","useRef","useState","StyleSheet","View","Camera","VisionCamera","useMicrophonePermission","usePhotoOutput","useVideoOutput","runOnJS","useSharedValue","Gesture","GestureDetector","buildPhotoFile","capturePhotoToFile","FocusIndicator","jsx","_jsx","jsxs","_jsxs","NEUTRAL_ZOOM","device","currentMode","isActive","flash","aspectRatio","zoomShared","ref","cameraRef","
|
|
1
|
+
{"version":3,"names":["forwardRef","useCallback","useImperativeHandle","useRef","useState","StyleSheet","useWindowDimensions","View","Camera","VisionCamera","useMicrophonePermission","usePhotoOutput","useVideoOutput","runOnJS","useSharedValue","Gesture","GestureDetector","buildPhotoFile","capturePhotoToFile","FocusIndicator","jsx","_jsx","jsxs","_jsxs","NEUTRAL_ZOOM","device","currentMode","isActive","flash","aspectRatio","zoomShared","ref","cameraRef","cameraType","position","width","screenW","frameRatio","frameW","frameH","targetResolution","height","photoOutput","qualityPrioritization","quality","videoOutput","hasPermission","hasMic","requestPermission","requestMic","activeRecorderRef","preparedRecorderRef","finishResolverRef","internalZoom","zoom","zoomOffset","pinchGesture","Pinch","onBegin","value","onUpdate","e","z","scale","Math","min","max","minZoom","maxZoom","focusPoint","setFocusPoint","handleFocus","x","y","supportsFocusMetering","current","focusTo","responsiveness","adaptiveness","autoResetAfter","console","warn","tapGesture","Tap","onEnd","composed","Simultaneous","capture","raw","flashMode","enableShutterSound","path","mode","startVideo","catch","recorder","createRecorder","startRecording","filePath","_reason","file","error","stopVideo","active","durationSec","recordedDuration","finishedPromise","Promise","resolve","duration","stopRecording","outputs","style","styles","root","children","gesture","frame","absoluteFill","resizeMode","constraints","photoHDR","torchMode","onSubjectAreaChanged","resetFocus","nativeID","point","onAnimationEnd","create","backgroundColor","alignItems","justifyContent","overflow"],"sourceRoot":"../../../src","sources":["camera/Camera.tsx"],"mappings":";;AAAA,SACEA,UAAU,EACVC,WAAW,EACXC,mBAAmB,EACnBC,MAAM,EACNC,QAAQ,QACH,OAAO;AACd,SAASC,UAAU,EAAEC,mBAAmB,EAAEC,IAAI,QAAQ,cAAc;AACpE,SACEC,MAAM,IAAIC,YAAY,EACtBC,uBAAuB,EACvBC,cAAc,EACdC,cAAc,QAMT,4BAA4B;AACnC,SAASC,OAAO,EAAEC,cAAc,QAAQ,yBAAyB;AAEjE,SAASC,OAAO,EAAEC,eAAe,QAAQ,8BAA8B;AAEvE,SAASC,cAAc,QAAQ,mBAAU;AACzC,SAASC,kBAAkB,QAAQ,yBAAsB;AACzD,SAASC,cAAc,QAAQ,qBAAkB;AAAC,SAAAC,GAAA,IAAAC,IAAA,EAAAC,IAAA,IAAAC,KAAA;AAGlD,MAAMC,YAAY,GAAG,CAAC;AAiBtB,OAAO,MAAMhB,MAAM,gBAAGR,UAAU,CAAsB,SAASQ,MAAMA,CACnE;EAAEiB,MAAM;EAAEC,WAAW;EAAEC,QAAQ,GAAG,IAAI;EAAEC,KAAK;EAAEC,WAAW;EAAEC;AAAW,CAAC,EACxEC,GAAG,EACH;EACA,MAAMC,SAAS,GAAG7B,MAAM,CAAY,IAAI,CAAC;EAEzC,MAAM8B,UAAU,GAAGR,MAAM,CAACS,QAAQ,KAAK,OAAO,GAAG,OAAO,GAAG,MAAM;EAEjE,MAAM;IAAEC,KAAK,EAAEC;EAAQ,CAAC,GAAG9B,mBAAmB,CAAC,CAAC;EAChD;EACA;EACA,MAAM+B,UAAU,GAAG,CAACR,WAAW,IAAI,KAAK,MAAM,KAAK,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC;EACpE,MAAMS,MAAM,GAAGF,OAAO;EACtB,MAAMG,MAAM,GAAGH,OAAO,GAAGC,UAAU;EAEnC,MAAMG,gBAAgB,GACpB,CAACX,WAAW,IAAI,KAAK,MAAM,KAAK,GAC5B;IAAEM,KAAK,EAAE,IAAI;IAAEM,MAAM,EAAE;EAAK,CAAC,GAC7B;IAAEN,KAAK,EAAE,IAAI;IAAEM,MAAM,EAAE;EAAK,CAAC;EAEnC,MAAMC,WAAW,GAAG/B,cAAc,CAAC;IACjC;IACAgC,qBAAqB,EAAE,OAAO;IAC9BC,OAAO,EAAElB,WAAW,CAACkB,OAAO,IAAI,GAAG;IACnCJ;EACF,CAAC,CAAC;EAEF,MAAMK,WAAW,GAAGjC,cAAc,CAAC,CAAC;EACpC,MAAM;IAAEkC,aAAa,EAAEC,MAAM;IAAEC,iBAAiB,EAAEC;EAAW,CAAC,GAC5DvC,uBAAuB,CAAC,CAAC;EAE3B,MAAMwC,iBAAiB,GAAG/C,MAAM,CAAkB,IAAI,CAAC;EACvD,MAAMgD,mBAAmB,GAAGhD,MAAM,CAAkB,IAAI,CAAC;EACzD,MAAMiD,iBAAiB,GAAGjD,MAAM,CAE9B,IAAI,CAAC;EAEP,MAAMkD,YAAY,GAAGvC,cAAc,CAACU,YAAY,CAAC;EACjD,MAAM8B,IAAI,GAAGxB,UAAU,IAAIuB,YAAY;EACvC,MAAME,UAAU,GAAGzC,cAAc,CAAC,CAAC,CAAC;EAEpC,MAAM0C,YAAY,GAAGzC,OAAO,CAAC0C,KAAK,CAAC,CAAC,CACjCC,OAAO,CAAC,MAAM;IACb,SAAS;;IACTH,UAAU,CAACI,KAAK,GAAGL,IAAI,CAACK,KAAK;EAC/B,CAAC,CAAC,CACDC,QAAQ,CAAEC,CAAC,IAAK;IACf,SAAS;;IACT,MAAMC,CAAC,GAAGP,UAAU,CAACI,KAAK,GAAGE,CAAC,CAACE,KAAK;IACpCT,IAAI,CAACK,KAAK,GAAGK,IAAI,CAACC,GAAG,CAACD,IAAI,CAACE,GAAG,CAACJ,CAAC,EAAErC,MAAM,CAAC0C,OAAO,CAAC,EAAE1C,MAAM,CAAC2C,OAAO,CAAC;EACpE,CAAC,CAAC;EAEJ,MAAM,CAACC,UAAU,EAAEC,aAAa,CAAC,GAAGlE,QAAQ,CAAe,IAAI,CAAC;EAEhE,MAAMmE,WAAW,GAAGtE,WAAW,CAC7B,OAAOuE,CAAS,EAAEC,CAAS,KAAK;IAC9B,IAAI,CAAChD,MAAM,CAACiD,qBAAqB,EAAE;IACnCJ,aAAa,CAAC;MAAEE,CAAC;MAAEC;IAAE,CAAC,CAAC;IACvB,IAAI;MACF,MAAMzC,SAAS,CAAC2C,OAAO,EAAEC,OAAO,CAAC;QAAEJ,CAAC;QAAEC;MAAE,CAAC,EAAE;QACzCI,cAAc,EAAE,QAAQ;QACxBC,YAAY,EAAE,YAAY;QAC1BC,cAAc,EAAE;MAClB,CAAwB,CAAC;IAC3B,CAAC,CAAC,OAAOlB,CAAC,EAAE;MACVmB,OAAO,CAACC,IAAI,CAAC,gBAAgB,EAAEpB,CAAC,CAAC;IACnC;EACF,CAAC,EACD,CAACpC,MAAM,CAACiD,qBAAqB,CAC/B,CAAC;EAED,MAAMQ,UAAU,GAAGnE,OAAO,CAACoE,GAAG,CAAC,CAAC,CAACC,KAAK,CAAC,CAAC;IAAEZ,CAAC;IAAEC;EAAE,CAAC,KAAK;IACnD,SAAS;;IACT5D,OAAO,CAAC0D,WAAW,CAAC,CAACC,CAAC,EAAEC,CAAC,CAAC;EAC5B,CAAC,CAAC;EAEF,MAAMY,QAAQ,GAAGtE,OAAO,CAACuE,YAAY,CAAC9B,YAAY,EAAE0B,UAAU,CAAC;EAE/DhF,mBAAmB,CACjB6B,GAAG,EACH,OAAO;IACLwD,OAAO,EAAE,MAAAA,CAAA,KAAY;MACnB,IAAI;QACF,MAAMC,GAAG,GAAG,MAAMtE,kBAAkB,CAACwB,WAAW,EAAE;UAChD+C,SAAS,EAAE7D,KAAK,IAAI,KAAK;UACzB8D,kBAAkB,EAAE;QACtB,CAAC,CAAC;QACF,OAAOzE,cAAc,CACnB;UAAE0E,IAAI,EAAEH,GAAG,CAACG,IAAI;UAAExD,KAAK,EAAEqD,GAAG,CAACrD,KAAK;UAAEM,MAAM,EAAE+C,GAAG,CAAC/C;QAAO,CAAC,EACxDf,WAAW,CAACkE,IAAI,EAChB3D,UACF,CAAC;MACH,CAAC,CAAC,OAAO4B,CAAC,EAAE;QACVmB,OAAO,CAACC,IAAI,CAAC,qBAAqB,EAAEpB,CAAC,CAAC;QACtC,OAAO,IAAI;MACb;IACF,CAAC;IAEDgC,UAAU,EAAE,MAAAA,CAAA,KAAY;MACtB,IAAI,CAAC9C,MAAM,EAAE;QACX,MAAME,UAAU,CAAC,CAAC,CAAC6C,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;MACpC;MACA,IAAI;QACF,IAAIC,QAAQ,GAAG5C,mBAAmB,CAACwB,OAAO;QAC1C,IAAIoB,QAAQ,IAAI,IAAI,EAAE;UACpBA,QAAQ,GAAG,MAAMlD,WAAW,CAACmD,cAAc,CAAC,CAAC,CAAC,CAAC;QACjD;QACA7C,mBAAmB,CAACwB,OAAO,GAAG,IAAI;QAClC,IAAIzB,iBAAiB,CAACyB,OAAO,IAAI,IAAI,EAAE;QACvCzB,iBAAiB,CAACyB,OAAO,GAAGoB,QAAQ;QAEpC,MAAMA,QAAQ,CAACE,cAAc,CAC3B,CAACC,QAAQ,EAAEC,OAAO,KAAK;UACrB,MAAMC,IAAI,GAAGnF,cAAc,CACzB;YAAE0E,IAAI,EAAEO,QAAQ;YAAE/D,KAAK,EAAE,CAAC;YAAEM,MAAM,EAAE;UAAE,CAAC,EACvC,OAAO,EACPR,UAAU,EACV,IACF,CAAC;UACDiB,iBAAiB,CAACyB,OAAO,GAAG,IAAI;UAChCvB,iBAAiB,CAACuB,OAAO,GAAGyB,IAAI,CAAC;UACjChD,iBAAiB,CAACuB,OAAO,GAAG,IAAI;QAClC,CAAC,EACA0B,KAAK,IAAK;UACTrB,OAAO,CAACC,IAAI,CAAC,gBAAgB,EAAEoB,KAAK,CAAC;UACrCnD,iBAAiB,CAACyB,OAAO,GAAG,IAAI;UAChCvB,iBAAiB,CAACuB,OAAO,GAAG,IAAI,CAAC;UACjCvB,iBAAiB,CAACuB,OAAO,GAAG,IAAI;QAClC,CAAC,EACD,MAAM,CAAC,CAAC,EACR,MAAM,CAAC,CACT,CAAC;QAEDxB,mBAAmB,CAACwB,OAAO,GAAG,MAAM9B,WAAW,CAACmD,cAAc,CAAC,CAAC,CAAC,CAAC;MACpE,CAAC,CAAC,OAAOnC,CAAC,EAAE;QACVmB,OAAO,CAACC,IAAI,CAAC,uBAAuB,EAAEpB,CAAC,CAAC;QACxCX,iBAAiB,CAACyB,OAAO,GAAG,IAAI;MAClC;IACF,CAAC;IAED2B,SAAS,EAAE,MAAAA,CAAA,KAAY;MACrB,MAAMC,MAAM,GAAGrD,iBAAiB,CAACyB,OAAO;MACxC,IAAI4B,MAAM,IAAI,IAAI,EAAE,OAAO,IAAI;MAC/B,IAAI;QACF,MAAMC,WAAW,GAAGD,MAAM,CAACE,gBAAgB;QAC3C,MAAMC,eAAe,GAAG,IAAIC,OAAO,CAChCC,OAAO,IAAK;UACXxD,iBAAiB,CAACuB,OAAO,GAAIyB,IAAI,IAAK;YACpC,IAAIA,IAAI,IAAI,IAAI,IAAII,WAAW,IAAI,IAAI,EAAE;cACvCI,OAAO,CAAC;gBAAE,GAAGR,IAAI;gBAAES,QAAQ,EAAEL;cAAY,CAAC,CAAC;YAC7C,CAAC,MAAM;cACLI,OAAO,CAACR,IAAI,CAAC;YACf;UACF,CAAC;QACH,CACF,CAAC;QACD,MAAMG,MAAM,CAACO,aAAa,CAAC,CAAC;QAC5B,OAAO,MAAMJ,eAAe;MAC9B,CAAC,CAAC,OAAO7C,CAAC,EAAE;QACVmB,OAAO,CAACC,IAAI,CAAC,sBAAsB,EAAEpB,CAAC,CAAC;QACvCX,iBAAiB,CAACyB,OAAO,GAAG,IAAI;QAChC,OAAO,IAAI;MACb;IACF;EACF,CAAC,CAAC,EACF,CACEjC,WAAW,EACXG,WAAW,EACXnB,WAAW,CAACkE,IAAI,EAChB7C,MAAM,EACNE,UAAU,EACVrB,KAAK,EACLK,UAAU,CAEd,CAAC;EAED,MAAM8E,OAAO,GAAGrF,WAAW,CAACkE,IAAI,KAAK,OAAO,GAAG,CAAC/C,WAAW,CAAC,GAAG,CAACH,WAAW,CAAC;EAE5E,oBACErB,IAAA,CAACd,IAAI;IAACyG,KAAK,EAAEC,MAAM,CAACC,IAAK;IAAAC,QAAA,eACvB9F,IAAA,CAACL,eAAe;MAACoG,OAAO,EAAE/B,QAAS;MAAA8B,QAAA,eACjC5F,KAAA,CAAChB,IAAI;QAACyG,KAAK,EAAE,CAACC,MAAM,CAACI,KAAK,EAAE;UAAElF,KAAK,EAAEG,MAAM;UAAEG,MAAM,EAAEF;QAAO,CAAC,CAAE;QAAA4E,QAAA,gBAC7D9F,IAAA,CAACZ,YAAY;UACXsB,GAAG,EAAEC,SAAU;UACfgF,KAAK,EAAE3G,UAAU,CAACiH,YAAa;UAC/BC,UAAU,EAAC,OAAO;UAClB9F,MAAM,EAAEA,MAAO;UACfE,QAAQ,EAAEA,QAAS;UACnBoF,OAAO,EAAEA,OAAkC;UAC3CS,WAAW,EAAE,CAAC;YAAEC,QAAQ,EAAE;UAAM,CAAC,CAAE;UACnCnE,IAAI,EAAEA,IAAK;UACXoE,SAAS,EACPhG,WAAW,CAACkE,IAAI,KAAK,OAAO,IAAIhE,KAAK,KAAK,IAAI,GAAG,IAAI,GAAG,KACzD;UACD+F,oBAAoB,EAAEA,CAAA,KAAM3F,SAAS,CAAC2C,OAAO,EAAEiD,UAAU,CAAC,CAAE;UAC5DC,QAAQ,EAAC;QAAe,CACzB,CAAC,EACDxD,UAAU,iBACThD,IAAA,CAACF,cAAc;UAEb2G,KAAK,EAAEzD,UAAW;UAClB0D,cAAc,EAAEA,CAAA,KAAMzD,aAAa,CAAC,IAAI;QAAE,GAFrC,GAAGD,UAAU,CAACG,CAAC,IAAIH,UAAU,CAACI,CAAC,EAGrC,CACF;MAAA,CACG;IAAC,CACQ;EAAC,CACd,CAAC;AAEX,CAAC,CAAC;AAEF,MAAMwC,MAAM,GAAG5G,UAAU,CAAC2H,MAAM,CAAC;EAC/B;EACAd,IAAI,EAAE;IACJ,GAAG7G,UAAU,CAACiH,YAAY;IAC1BW,eAAe,EAAE,MAAM;IACvBC,UAAU,EAAE,QAAQ;IACpBC,cAAc,EAAE;EAClB,CAAC;EACD;EACAd,KAAK,EAAE;IAAEe,QAAQ,EAAE;EAAS;AAC9B,CAAC,CAAC","ignoreList":[]}
|
|
@@ -58,8 +58,11 @@ export function Container({
|
|
|
58
58
|
};
|
|
59
59
|
}, [hasPermission, requestPermission]);
|
|
60
60
|
|
|
61
|
+
// 初始前/后摄由 config 首个 mode 的 type 决定(H5 传入),缺省 back。
|
|
62
|
+
// 运行时前后摄翻转是独立功能,不在本次范围。
|
|
61
63
|
// 5.x:physicalDevices 字符串不带 -camera;单 'wide-angle' 规避 iOS #3773
|
|
62
|
-
const
|
|
64
|
+
const initialPosition = config.cameraMode[0]?.type ?? 'back';
|
|
65
|
+
const device = useCameraDevice(initialPosition, {
|
|
63
66
|
physicalDevices: ['wide-angle']
|
|
64
67
|
});
|
|
65
68
|
const cameraRef = useRef(null);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["useCallback","useEffect","useRef","useState","Linking","StyleSheet","View","useCameraDevice","useCameraPermission","useSharedValue","NoCamera","NoPermission","Loading","Camera","PreViewContainer","Footer","SetUp","jsx","_jsx","jsxs","_jsxs","NEUTRAL_ZOOM","Container","config","onSettle","settledRef","settle","r","current","code","data","message","hasPermission","requestPermission","state","setState","cancelled","then","ok","catch","device","physicalDevices","cameraRef","photos","setPhotos","previewing","setPreviewing","recording","setRecording","modeIndex","setModeIndex","currentMode","
|
|
1
|
+
{"version":3,"names":["useCallback","useEffect","useRef","useState","Linking","StyleSheet","View","useCameraDevice","useCameraPermission","useSharedValue","NoCamera","NoPermission","Loading","Camera","PreViewContainer","Footer","SetUp","jsx","_jsx","jsxs","_jsxs","NEUTRAL_ZOOM","Container","config","onSettle","settledRef","settle","r","current","code","data","message","hasPermission","requestPermission","state","setState","cancelled","then","ok","catch","initialPosition","cameraMode","type","device","physicalDevices","cameraRef","photos","setPhotos","previewing","setPreviewing","recording","setRecording","modeIndex","setModeIndex","currentMode","flash","setFlash","aspectRatio","setAspectRatio","zoomShared","lensLabel","setLensLabel","toFixed","onShutter","mode","startVideo","f","stopVideo","capture","prev","onCancel","onOpenSettings","openSettings","style","styles","root","testID","children","files","onRetake","onConfirm","onToggleLens","startsWith","minZoom","value","ref","onChangeFlash","onChangeAspectRatio","modes","currentIndex","onSelectMode","i","dataRetainedMode","onFinishBurst","undefined","burstCount","length","create","flex","backgroundColor","justifyContent","alignItems"],"sourceRoot":"../../../src","sources":["camera/Container.tsx"],"mappings":"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","ignoreList":[]}
|
package/lib/module/index.js
CHANGED
package/lib/module/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["useCamera"
|
|
1
|
+
{"version":3,"names":["useCamera"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":";;AAAA,SAASA,SAAS,QAAQ,kBAAS;AACnC,cAAc,kBAAS","ignoreList":[]}
|
package/lib/module/mock.js
CHANGED
|
@@ -22,9 +22,6 @@
|
|
|
22
22
|
// 类型 + 纯工具函数(toFileUri / buildPhotoFile / depsAreSame / pxToDp)保留真实实现 ——
|
|
23
23
|
// 它们不碰 native,消费者测试里跑真实逻辑比 mock 更有意义。
|
|
24
24
|
export * from "./utils/index.js";
|
|
25
|
-
|
|
26
|
-
// 与 src/index.tsx 保持一致;mock 不能 import index(会触发 native 依赖链,失去 mock 意义)。
|
|
27
|
-
export const VERSION = '2.0.0';
|
|
28
25
|
const cancelled = {
|
|
29
26
|
code: 0,
|
|
30
27
|
data: [],
|
package/lib/module/mock.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["
|
|
1
|
+
{"version":3,"names":["cancelled","code","data","message","useCamera","api","open","jest","fn","close"],"sourceRoot":"../../src","sources":["mock.ts"],"mappings":";;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAIA;AACA;AACA,cAAc,kBAAS;AAEvB,MAAMA,SAAuB,GAAG;EAAEC,IAAI,EAAE,CAAC;EAAEC,IAAI,EAAE,EAAE;EAAEC,OAAO,EAAE;AAAY,CAAC;AAE3E,OAAO,SAASC,SAASA,CAAA,EAAsB;EAC7C,MAAMC,GAAc,GAAG;IACrBC,IAAI,EAAEC,IAAI,CAACC,EAAE,CAAC,YAAYR,SAAS,CAAsB;IACzDS,KAAK,EAAEF,IAAI,CAACC,EAAE,CAAC;EACjB,CAAC;EACD,OAAO,CAACH,GAAG,EAAE,IAAI,CAAC;AACpB","ignoreList":[]}
|
package/lib/module/utils/util.js
CHANGED
|
@@ -4,8 +4,14 @@ export function toFileUri(path) {
|
|
|
4
4
|
if (path.startsWith('file://')) return path;
|
|
5
5
|
return `file://${path}`;
|
|
6
6
|
}
|
|
7
|
-
|
|
7
|
+
|
|
8
|
+
// 单调递增计数器,保证同毫秒多张照片 id 不撞(原版用纯时间戳有撞 id 风险)。
|
|
9
|
+
let photoIdCounter = 0;
|
|
10
|
+
export function buildPhotoFile(raw, mode, cameraType, isVideo = false) {
|
|
8
11
|
return {
|
|
12
|
+
id: `${Date.now()}-${photoIdCounter++}`,
|
|
13
|
+
cameraType,
|
|
14
|
+
cameraMode: mode,
|
|
9
15
|
path: raw.path,
|
|
10
16
|
uri: toFileUri(raw.path),
|
|
11
17
|
width: raw.width,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["toFileUri","path","startsWith","buildPhotoFile","raw","mode","isVideo","uri","width","height","mime","duration"],"sourceRoot":"../../../src","sources":["utils/util.ts"],"mappings":";;AAEA,OAAO,SAASA,SAASA,CAACC,IAAY,EAAU;EAC9C,IAAIA,IAAI,CAACC,UAAU,CAAC,SAAS,CAAC,EAAE,OAAOD,IAAI;EAC3C,OAAO,UAAUA,IAAI,EAAE;AACzB;
|
|
1
|
+
{"version":3,"names":["toFileUri","path","startsWith","photoIdCounter","buildPhotoFile","raw","mode","cameraType","isVideo","id","Date","now","cameraMode","uri","width","height","mime","duration"],"sourceRoot":"../../../src","sources":["utils/util.ts"],"mappings":";;AAEA,OAAO,SAASA,SAASA,CAACC,IAAY,EAAU;EAC9C,IAAIA,IAAI,CAACC,UAAU,CAAC,SAAS,CAAC,EAAE,OAAOD,IAAI;EAC3C,OAAO,UAAUA,IAAI,EAAE;AACzB;;AAEA;AACA,IAAIE,cAAc,GAAG,CAAC;AAEtB,OAAO,SAASC,cAAcA,CAC5BC,GAAuE,EACvEC,IAAoB,EACpBC,UAAsB,EACtBC,OAAgB,GAAG,KAAK,EACP;EACjB,OAAO;IACLC,EAAE,EAAE,GAAGC,IAAI,CAACC,GAAG,CAAC,CAAC,IAAIR,cAAc,EAAE,EAAE;IACvCI,UAAU;IACVK,UAAU,EAAEN,IAAI;IAChBL,IAAI,EAAEI,GAAG,CAACJ,IAAI;IACdY,GAAG,EAAEb,SAAS,CAACK,GAAG,CAACJ,IAAI,CAAC;IACxBa,KAAK,EAAET,GAAG,CAACS,KAAK;IAChBC,MAAM,EAAEV,GAAG,CAACU,MAAM;IAClBC,IAAI,EAAER,OAAO,GAAG,WAAW,GAAG,YAAY;IAC1CF,IAAI;IACJ,IAAID,GAAG,CAACY,QAAQ,IAAI,IAAI,GAAG;MAAEA,QAAQ,EAAEZ,GAAG,CAACY;IAAS,CAAC,GAAG,CAAC,CAAC;EAC5D,CAAC;AACH","ignoreList":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Camera.d.ts","sourceRoot":"","sources":["../../../../src/camera/Camera.tsx"],"names":[],"mappings":"AAQA,OAAO,EAML,KAAK,YAAY,EAIlB,MAAM,4BAA4B,CAAC;AAEpC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAE3D,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"Camera.d.ts","sourceRoot":"","sources":["../../../../src/camera/Camera.tsx"],"names":[],"mappings":"AAQA,OAAO,EAML,KAAK,YAAY,EAIlB,MAAM,4BAA4B,CAAC;AAEpC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAE3D,OAAO,KAAK,EAAE,UAAU,EAAE,eAAe,EAAS,MAAM,UAAU,CAAC;AAInE,OAAO,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAItD,MAAM,MAAM,YAAY,GAAG;IACzB,OAAO,EAAE,MAAM,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAAC;IAC/C,UAAU,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAChC,SAAS,EAAE,MAAM,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAAC;CAClD,CAAC;AAEF,KAAK,KAAK,GAAG;IACX,MAAM,EAAE,YAAY,CAAC;IACrB,WAAW,EAAE,UAAU,CAAC;IACxB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,UAAU,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;CAClC,CAAC;AAEF,eAAO,MAAM,MAAM,gGAgNjB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Container.d.ts","sourceRoot":"","sources":["../../../../src/camera/Container.tsx"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,YAAY,EAAmB,UAAU,EAAE,MAAM,UAAU,CAAC;AAW1E,KAAK,KAAK,GAAG;IACX,MAAM,EAAE,UAAU,CAAC;IACnB,QAAQ,EAAE,CAAC,CAAC,EAAE,YAAY,KAAK,IAAI,CAAC;CACrC,CAAC;AAIF,wBAAgB,SAAS,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,KAAK,
|
|
1
|
+
{"version":3,"file":"Container.d.ts","sourceRoot":"","sources":["../../../../src/camera/Container.tsx"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,YAAY,EAAmB,UAAU,EAAE,MAAM,UAAU,CAAC;AAW1E,KAAK,KAAK,GAAG;IACX,MAAM,EAAE,UAAU,CAAC;IACnB,QAAQ,EAAE,CAAC,CAAC,EAAE,YAAY,KAAK,IAAI,CAAC;CACrC,CAAC;AAIF,wBAAgB,SAAS,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,KAAK,2CAwMpD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpC,cAAc,SAAS,CAAC
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpC,cAAc,SAAS,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mock.d.ts","sourceRoot":"","sources":["../../../src/mock.ts"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAAE,SAAS,EAAgB,MAAM,SAAS,CAAC;AAIvD,cAAc,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"mock.d.ts","sourceRoot":"","sources":["../../../src/mock.ts"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAAE,SAAS,EAAgB,MAAM,SAAS,CAAC;AAIvD,cAAc,SAAS,CAAC;AAIxB,wBAAgB,SAAS,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,CAM7C"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export type CameraType = 'back' | 'front';
|
|
2
|
-
export type
|
|
2
|
+
export type FlashMode = 'auto' | 'on' | 'off';
|
|
3
3
|
export type DataRetainedMode = 'clear' | 'retain';
|
|
4
4
|
export type CameraModeName = 'single' | 'continuous' | 'video';
|
|
5
5
|
export type Point = {
|
|
@@ -7,20 +7,34 @@ export type Point = {
|
|
|
7
7
|
y: number;
|
|
8
8
|
};
|
|
9
9
|
export type CameraMode = {
|
|
10
|
+
/** 初始前/后摄,缺省 back。H5 传入,接线为初始 device position。 */
|
|
11
|
+
type?: CameraType;
|
|
12
|
+
/** 初始闪光(原版字段,保留作 API 兼容)。闪光由相机内 UI 控制,不从 config 接线。 */
|
|
13
|
+
flashMode?: FlashMode;
|
|
14
|
+
/** 拍摄模式。 */
|
|
10
15
|
mode: CameraModeName;
|
|
11
|
-
|
|
12
|
-
|
|
16
|
+
/** JPEG 压缩 0~1,缺省 0.9。内部速度优先级写死 'speed'(对齐原版 4.x photoQualityBalance)。 */
|
|
17
|
+
quality?: number;
|
|
18
|
+
/** 录制时长上限(秒),video 模式。原版字段,保留;未用到则 no-op。 */
|
|
19
|
+
recTime?: number;
|
|
13
20
|
};
|
|
14
21
|
export type OpenConfig = {
|
|
15
22
|
cameraMode: CameraMode[];
|
|
16
23
|
dataRetainedMode: DataRetainedMode;
|
|
17
24
|
};
|
|
18
25
|
export type CustomPhotoFile = {
|
|
26
|
+
/** 唯一 id,时间戳 + 序号(避免同毫秒撞 id)。 */
|
|
27
|
+
id: string;
|
|
28
|
+
/** 拍摄时的前/后摄。 */
|
|
29
|
+
cameraType: CameraType;
|
|
30
|
+
/** 模式(原版字段名,与 mode 同值)。 */
|
|
31
|
+
cameraMode: CameraModeName;
|
|
19
32
|
path: string;
|
|
20
33
|
uri: string;
|
|
21
34
|
width: number;
|
|
22
35
|
height: number;
|
|
23
36
|
mime: 'image/jpeg' | 'video/mp4';
|
|
37
|
+
/** 模式(2.x 字段名,与 cameraMode 同值)。 */
|
|
24
38
|
mode: CameraModeName;
|
|
25
39
|
duration?: number;
|
|
26
40
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"interface.d.ts","sourceRoot":"","sources":["../../../../src/utils/interface.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,OAAO,CAAC;AAE1C,MAAM,MAAM,
|
|
1
|
+
{"version":3,"file":"interface.d.ts","sourceRoot":"","sources":["../../../../src/utils/interface.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,OAAO,CAAC;AAE1C,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,IAAI,GAAG,KAAK,CAAC;AAE9C,MAAM,MAAM,gBAAgB,GAAG,OAAO,GAAG,QAAQ,CAAC;AAElD,MAAM,MAAM,cAAc,GAAG,QAAQ,GAAG,YAAY,GAAG,OAAO,CAAC;AAE/D,MAAM,MAAM,KAAK,GAAG;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAE7C,MAAM,MAAM,UAAU,GAAG;IACvB,kDAAkD;IAClD,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,uDAAuD;IACvD,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,YAAY;IACZ,IAAI,EAAE,cAAc,CAAC;IACrB,0EAA0E;IAC1E,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,6CAA6C;IAC7C,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IACvB,UAAU,EAAE,UAAU,EAAE,CAAC;IACzB,gBAAgB,EAAE,gBAAgB,CAAC;CACpC,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAE5B,iCAAiC;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,gBAAgB;IAChB,UAAU,EAAE,UAAU,CAAC;IACvB,2BAA2B;IAC3B,UAAU,EAAE,cAAc,CAAC;IAE3B,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,YAAY,GAAG,WAAW,CAAC;IACjC,mCAAmC;IACnC,IAAI,EAAE,cAAc,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG,CAAC,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;AAE/D,MAAM,MAAM,YAAY,GAAG;IACzB,IAAI,EAAE,gBAAgB,CAAC;IACvB,IAAI,EAAE,eAAe,EAAE,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,SAAS,GAAG;IACtB,IAAI,EAAE,CAAC,MAAM,EAAE,UAAU,KAAK,OAAO,CAAC,YAAY,CAAC,CAAC;IACpD,KAAK,EAAE,MAAM,IAAI,CAAC;CACnB,CAAC"}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import type { CustomPhotoFile, CameraModeName } from './interface';
|
|
1
|
+
import type { CustomPhotoFile, CameraModeName, CameraType } from './interface';
|
|
2
2
|
export declare function toFileUri(path: string): string;
|
|
3
3
|
export declare function buildPhotoFile(raw: {
|
|
4
4
|
path: string;
|
|
5
5
|
width: number;
|
|
6
6
|
height: number;
|
|
7
7
|
duration?: number;
|
|
8
|
-
}, mode: CameraModeName, isVideo?: boolean): CustomPhotoFile;
|
|
8
|
+
}, mode: CameraModeName, cameraType: CameraType, isVideo?: boolean): CustomPhotoFile;
|
|
9
9
|
//# sourceMappingURL=util.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../../../../src/utils/util.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../../../../src/utils/util.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE/E,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAG9C;AAKD,wBAAgB,cAAc,CAC5B,GAAG,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,EACvE,IAAI,EAAE,cAAc,EACpB,UAAU,EAAE,UAAU,EACtB,OAAO,GAAE,OAAe,GACvB,eAAe,CAajB"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@unif/react-native-camera",
|
|
3
|
-
"version": "2.
|
|
4
|
-
"description": "基于 react-native-vision-camera
|
|
3
|
+
"version": "2.6.1",
|
|
4
|
+
"description": "基于 react-native-vision-camera 5.x 的相机库(单拍/连拍/视频录制)",
|
|
5
5
|
"main": "./lib/module/index.js",
|
|
6
6
|
"types": "./lib/typescript/src/index.d.ts",
|
|
7
7
|
"exports": {
|
|
@@ -104,6 +104,7 @@
|
|
|
104
104
|
"react-native-safe-area-context": "^5.0.0",
|
|
105
105
|
"react-native-svg": "^15.15.5",
|
|
106
106
|
"react-native-vision-camera": "^5.0.0",
|
|
107
|
+
"react-native-vision-camera-worklets": "^5.0.0",
|
|
107
108
|
"react-native-webview": "*",
|
|
108
109
|
"react-native-worklets": "*",
|
|
109
110
|
"react-test-renderer": "19.2.3",
|
|
@@ -125,6 +126,7 @@
|
|
|
125
126
|
"react-native-safe-area-context": ">=5.0.0",
|
|
126
127
|
"react-native-svg": ">=15",
|
|
127
128
|
"react-native-vision-camera": "^5.0.0",
|
|
129
|
+
"react-native-vision-camera-worklets": "^5.0.0",
|
|
128
130
|
"react-native-webview": "*",
|
|
129
131
|
"react-native-worklets": "*"
|
|
130
132
|
},
|
package/src/camera/Camera.tsx
CHANGED
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
useRef,
|
|
6
6
|
useState,
|
|
7
7
|
} from 'react';
|
|
8
|
-
import { StyleSheet, View } from 'react-native';
|
|
8
|
+
import { StyleSheet, useWindowDimensions, View } from 'react-native';
|
|
9
9
|
import {
|
|
10
10
|
Camera as VisionCamera,
|
|
11
11
|
useMicrophonePermission,
|
|
@@ -20,12 +20,7 @@ import {
|
|
|
20
20
|
import { runOnJS, useSharedValue } from 'react-native-reanimated';
|
|
21
21
|
import type { SharedValue } from 'react-native-reanimated';
|
|
22
22
|
import { Gesture, GestureDetector } from 'react-native-gesture-handler';
|
|
23
|
-
import type {
|
|
24
|
-
CameraMode,
|
|
25
|
-
CustomPhotoFile,
|
|
26
|
-
PhotoQuality,
|
|
27
|
-
Point,
|
|
28
|
-
} from '../utils';
|
|
23
|
+
import type { CameraMode, CustomPhotoFile, Point } from '../utils';
|
|
29
24
|
import { buildPhotoFile } from '../utils';
|
|
30
25
|
import { capturePhotoToFile } from './capturePhotoHelper';
|
|
31
26
|
import { FocusIndicator } from './FocusIndicator';
|
|
@@ -54,15 +49,24 @@ export const Camera = forwardRef<CameraHandle, Props>(function Camera(
|
|
|
54
49
|
) {
|
|
55
50
|
const cameraRef = useRef<CameraRef>(null);
|
|
56
51
|
|
|
52
|
+
const cameraType = device.position === 'front' ? 'front' : 'back';
|
|
53
|
+
|
|
54
|
+
const { width: screenW } = useWindowDimensions();
|
|
55
|
+
// 取景框比例 = 输出照片比例(targetResolution):4:3→竖屏 高/宽=4/3, 16:9→16/9。
|
|
56
|
+
// 框比例 = 画面比例后,cover 不再裁两侧 → 预览 = 拍照(WYSIWYG)。
|
|
57
|
+
const frameRatio = (aspectRatio ?? '4:3') === '4:3' ? 4 / 3 : 16 / 9;
|
|
58
|
+
const frameW = screenW;
|
|
59
|
+
const frameH = screenW * frameRatio;
|
|
60
|
+
|
|
57
61
|
const targetResolution =
|
|
58
62
|
(aspectRatio ?? '4:3') === '4:3'
|
|
59
63
|
? { width: 1080, height: 1440 }
|
|
60
64
|
: { width: 1080, height: 1920 };
|
|
61
65
|
|
|
62
66
|
const photoOutput = usePhotoOutput({
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
quality: currentMode.
|
|
67
|
+
// 速度优先级对齐原版 4.x photoQualityBalance='speed'(写死);quality 用回原版字段
|
|
68
|
+
qualityPrioritization: 'speed',
|
|
69
|
+
quality: currentMode.quality ?? 0.9,
|
|
66
70
|
targetResolution,
|
|
67
71
|
});
|
|
68
72
|
|
|
@@ -128,7 +132,8 @@ export const Camera = forwardRef<CameraHandle, Props>(function Camera(
|
|
|
128
132
|
});
|
|
129
133
|
return buildPhotoFile(
|
|
130
134
|
{ path: raw.path, width: raw.width, height: raw.height },
|
|
131
|
-
currentMode.mode
|
|
135
|
+
currentMode.mode,
|
|
136
|
+
cameraType
|
|
132
137
|
);
|
|
133
138
|
} catch (e) {
|
|
134
139
|
console.warn('capturePhoto failed', e);
|
|
@@ -154,6 +159,7 @@ export const Camera = forwardRef<CameraHandle, Props>(function Camera(
|
|
|
154
159
|
const file = buildPhotoFile(
|
|
155
160
|
{ path: filePath, width: 0, height: 0 },
|
|
156
161
|
'video',
|
|
162
|
+
cameraType,
|
|
157
163
|
true
|
|
158
164
|
);
|
|
159
165
|
activeRecorderRef.current = null;
|
|
@@ -202,36 +208,59 @@ export const Camera = forwardRef<CameraHandle, Props>(function Camera(
|
|
|
202
208
|
}
|
|
203
209
|
},
|
|
204
210
|
}),
|
|
205
|
-
[
|
|
211
|
+
[
|
|
212
|
+
photoOutput,
|
|
213
|
+
videoOutput,
|
|
214
|
+
currentMode.mode,
|
|
215
|
+
hasMic,
|
|
216
|
+
requestMic,
|
|
217
|
+
flash,
|
|
218
|
+
cameraType,
|
|
219
|
+
]
|
|
206
220
|
);
|
|
207
221
|
|
|
208
222
|
const outputs = currentMode.mode === 'video' ? [videoOutput] : [photoOutput];
|
|
209
223
|
|
|
210
224
|
return (
|
|
211
|
-
<
|
|
212
|
-
<
|
|
213
|
-
<
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
<FocusIndicator
|
|
229
|
-
key={`${focusPoint.x}-${focusPoint.y}`}
|
|
230
|
-
point={focusPoint}
|
|
231
|
-
onAnimationEnd={() => setFocusPoint(null)}
|
|
225
|
+
<View style={styles.root}>
|
|
226
|
+
<GestureDetector gesture={composed}>
|
|
227
|
+
<View style={[styles.frame, { width: frameW, height: frameH }]}>
|
|
228
|
+
<VisionCamera
|
|
229
|
+
ref={cameraRef}
|
|
230
|
+
style={StyleSheet.absoluteFill}
|
|
231
|
+
resizeMode="cover"
|
|
232
|
+
device={device}
|
|
233
|
+
isActive={isActive}
|
|
234
|
+
outputs={outputs as CameraProps['outputs']}
|
|
235
|
+
constraints={[{ photoHDR: false }]}
|
|
236
|
+
zoom={zoom}
|
|
237
|
+
torchMode={
|
|
238
|
+
currentMode.mode === 'video' && flash === 'on' ? 'on' : 'off'
|
|
239
|
+
}
|
|
240
|
+
onSubjectAreaChanged={() => cameraRef.current?.resetFocus()}
|
|
241
|
+
nativeID="vision-camera"
|
|
232
242
|
/>
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
243
|
+
{focusPoint && (
|
|
244
|
+
<FocusIndicator
|
|
245
|
+
key={`${focusPoint.x}-${focusPoint.y}`}
|
|
246
|
+
point={focusPoint}
|
|
247
|
+
onAnimationEnd={() => setFocusPoint(null)}
|
|
248
|
+
/>
|
|
249
|
+
)}
|
|
250
|
+
</View>
|
|
251
|
+
</GestureDetector>
|
|
252
|
+
</View>
|
|
236
253
|
);
|
|
237
254
|
});
|
|
255
|
+
|
|
256
|
+
const styles = StyleSheet.create({
|
|
257
|
+
// 全屏黑底,把取景框居中 → 框外区域是黑边(letterbox)。
|
|
258
|
+
root: {
|
|
259
|
+
...StyleSheet.absoluteFill,
|
|
260
|
+
backgroundColor: '#000',
|
|
261
|
+
alignItems: 'center',
|
|
262
|
+
justifyContent: 'center',
|
|
263
|
+
},
|
|
264
|
+
// overflow:hidden 裁掉 cover 溢出部分,框内只显示输出比例的画面。
|
|
265
|
+
frame: { overflow: 'hidden' },
|
|
266
|
+
});
|
package/src/camera/Container.tsx
CHANGED
|
@@ -72,8 +72,11 @@ export function Container({ config, onSettle }: Props) {
|
|
|
72
72
|
};
|
|
73
73
|
}, [hasPermission, requestPermission]);
|
|
74
74
|
|
|
75
|
+
// 初始前/后摄由 config 首个 mode 的 type 决定(H5 传入),缺省 back。
|
|
76
|
+
// 运行时前后摄翻转是独立功能,不在本次范围。
|
|
75
77
|
// 5.x:physicalDevices 字符串不带 -camera;单 'wide-angle' 规避 iOS #3773
|
|
76
|
-
const
|
|
78
|
+
const initialPosition = config.cameraMode[0]?.type ?? 'back';
|
|
79
|
+
const device = useCameraDevice(initialPosition, {
|
|
77
80
|
physicalDevices: ['wide-angle'],
|
|
78
81
|
});
|
|
79
82
|
|
package/src/index.tsx
CHANGED
package/src/mock.ts
CHANGED
|
@@ -23,9 +23,6 @@ import type { CameraApi, CameraResult } from './utils';
|
|
|
23
23
|
// 它们不碰 native,消费者测试里跑真实逻辑比 mock 更有意义。
|
|
24
24
|
export * from './utils';
|
|
25
25
|
|
|
26
|
-
// 与 src/index.tsx 保持一致;mock 不能 import index(会触发 native 依赖链,失去 mock 意义)。
|
|
27
|
-
export const VERSION = '2.0.0';
|
|
28
|
-
|
|
29
26
|
const cancelled: CameraResult = { code: 0, data: [], message: 'cancelled' };
|
|
30
27
|
|
|
31
28
|
export function useCamera(): [CameraApi, null] {
|
package/src/utils/interface.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export type CameraType = 'back' | 'front';
|
|
2
2
|
|
|
3
|
-
export type
|
|
3
|
+
export type FlashMode = 'auto' | 'on' | 'off';
|
|
4
4
|
|
|
5
5
|
export type DataRetainedMode = 'clear' | 'retain';
|
|
6
6
|
|
|
@@ -9,9 +9,16 @@ export type CameraModeName = 'single' | 'continuous' | 'video';
|
|
|
9
9
|
export type Point = { x: number; y: number };
|
|
10
10
|
|
|
11
11
|
export type CameraMode = {
|
|
12
|
+
/** 初始前/后摄,缺省 back。H5 传入,接线为初始 device position。 */
|
|
13
|
+
type?: CameraType;
|
|
14
|
+
/** 初始闪光(原版字段,保留作 API 兼容)。闪光由相机内 UI 控制,不从 config 接线。 */
|
|
15
|
+
flashMode?: FlashMode;
|
|
16
|
+
/** 拍摄模式。 */
|
|
12
17
|
mode: CameraModeName;
|
|
13
|
-
|
|
14
|
-
|
|
18
|
+
/** JPEG 压缩 0~1,缺省 0.9。内部速度优先级写死 'speed'(对齐原版 4.x photoQualityBalance)。 */
|
|
19
|
+
quality?: number;
|
|
20
|
+
/** 录制时长上限(秒),video 模式。原版字段,保留;未用到则 no-op。 */
|
|
21
|
+
recTime?: number;
|
|
15
22
|
};
|
|
16
23
|
|
|
17
24
|
export type OpenConfig = {
|
|
@@ -20,11 +27,20 @@ export type OpenConfig = {
|
|
|
20
27
|
};
|
|
21
28
|
|
|
22
29
|
export type CustomPhotoFile = {
|
|
30
|
+
// —— 原版字段 ——
|
|
31
|
+
/** 唯一 id,时间戳 + 序号(避免同毫秒撞 id)。 */
|
|
32
|
+
id: string;
|
|
33
|
+
/** 拍摄时的前/后摄。 */
|
|
34
|
+
cameraType: CameraType;
|
|
35
|
+
/** 模式(原版字段名,与 mode 同值)。 */
|
|
36
|
+
cameraMode: CameraModeName;
|
|
37
|
+
// —— 2.x 字段 ——
|
|
23
38
|
path: string;
|
|
24
39
|
uri: string;
|
|
25
40
|
width: number;
|
|
26
41
|
height: number;
|
|
27
42
|
mime: 'image/jpeg' | 'video/mp4';
|
|
43
|
+
/** 模式(2.x 字段名,与 cameraMode 同值)。 */
|
|
28
44
|
mode: CameraModeName;
|
|
29
45
|
duration?: number;
|
|
30
46
|
};
|
package/src/utils/util.ts
CHANGED
|
@@ -1,16 +1,23 @@
|
|
|
1
|
-
import type { CustomPhotoFile, CameraModeName } from './interface';
|
|
1
|
+
import type { CustomPhotoFile, CameraModeName, CameraType } from './interface';
|
|
2
2
|
|
|
3
3
|
export function toFileUri(path: string): string {
|
|
4
4
|
if (path.startsWith('file://')) return path;
|
|
5
5
|
return `file://${path}`;
|
|
6
6
|
}
|
|
7
7
|
|
|
8
|
+
// 单调递增计数器,保证同毫秒多张照片 id 不撞(原版用纯时间戳有撞 id 风险)。
|
|
9
|
+
let photoIdCounter = 0;
|
|
10
|
+
|
|
8
11
|
export function buildPhotoFile(
|
|
9
12
|
raw: { path: string; width: number; height: number; duration?: number },
|
|
10
13
|
mode: CameraModeName,
|
|
14
|
+
cameraType: CameraType,
|
|
11
15
|
isVideo: boolean = false
|
|
12
16
|
): CustomPhotoFile {
|
|
13
17
|
return {
|
|
18
|
+
id: `${Date.now()}-${photoIdCounter++}`,
|
|
19
|
+
cameraType,
|
|
20
|
+
cameraMode: mode,
|
|
14
21
|
path: raw.path,
|
|
15
22
|
uri: toFileUri(raw.path),
|
|
16
23
|
width: raw.width,
|