@rick427/react-native-liveness 0.2.0 → 0.2.2
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 +118 -33
- package/lib/module/LivenessCamera.js +169 -96
- package/lib/module/LivenessCamera.js.map +1 -1
- package/lib/module/LivenessDetector.js +27 -7
- package/lib/module/LivenessDetector.js.map +1 -1
- package/lib/module/useLivenessCamera.js +67 -12
- package/lib/module/useLivenessCamera.js.map +1 -1
- package/lib/typescript/src/LivenessCamera.d.ts.map +1 -1
- package/package.json +6 -2
- package/src/LivenessCamera.tsx +98 -103
package/README.md
CHANGED
|
@@ -16,10 +16,13 @@ The library scores each camera frame against a set of liveness signals (face siz
|
|
|
16
16
|
|
|
17
17
|
- Real-time passive liveness detection (no gestures required)
|
|
18
18
|
- On-device ML — works fully offline (ML Kit)
|
|
19
|
-
-
|
|
20
|
-
-
|
|
19
|
+
- Circle guide with animated scanner — sweeping scan line, rotating corner brackets, confidence progress arc
|
|
20
|
+
- Score-driven border colour: white → yellow → green
|
|
21
|
+
- Built-in modal via `LivenessCameraModal` — one import, zero wiring
|
|
22
|
+
- Configurable animation type, close button style, and font
|
|
21
23
|
- Auto photo capture via Vision Camera's `takePhoto()`
|
|
22
|
-
-
|
|
24
|
+
- 60 fps preview, ML Kit capped at 20 fps via `runAtTargetFps`
|
|
25
|
+
- Optional shutter sound (respects silent mode)
|
|
23
26
|
- Fully typed TypeScript API
|
|
24
27
|
|
|
25
28
|
---
|
|
@@ -41,29 +44,32 @@ Install these if you don't already have them:
|
|
|
41
44
|
| `react-native-vision-camera` | `>= 4.0.0` |
|
|
42
45
|
| `react-native-svg` | `>= 13.0.0` |
|
|
43
46
|
| `react-native-worklets-core` | `>= 1.0.0` |
|
|
47
|
+
| `react-native-reanimated` | `>= 4.0.0` |
|
|
44
48
|
|
|
45
49
|
```sh
|
|
46
|
-
npm install react-native-vision-camera react-native-svg react-native-worklets-core
|
|
50
|
+
npm install react-native-vision-camera react-native-svg react-native-worklets-core react-native-reanimated
|
|
47
51
|
```
|
|
48
52
|
|
|
49
53
|
### Configure worklets Babel plugin
|
|
50
54
|
|
|
51
|
-
The library uses Vision Camera frame processors which run in a worklet context. Add the appropriate plugin to your `babel.config.js
|
|
55
|
+
The library uses Vision Camera frame processors which run in a worklet context. Add the appropriate plugin to your `babel.config.js`:
|
|
52
56
|
|
|
53
57
|
```js
|
|
54
58
|
// babel.config.js
|
|
55
59
|
module.exports = {
|
|
56
|
-
presets: [
|
|
60
|
+
presets: [
|
|
61
|
+
'module:@react-native/babel-preset', // or 'babel-preset-expo'
|
|
62
|
+
],
|
|
57
63
|
plugins: [
|
|
58
|
-
|
|
59
|
-
|
|
64
|
+
'react-native-worklets-core/plugin', // Vision Camera frame processors
|
|
65
|
+
'react-native-worklets/plugin', // Reanimated v4 SVG animations
|
|
60
66
|
],
|
|
61
67
|
};
|
|
62
68
|
```
|
|
63
69
|
|
|
64
|
-
> **Already have
|
|
70
|
+
> **Already have the plugins?** Just confirm both lines are present in `plugins` (not inside `presets`). `react-native-worklets/plugin` is installed as part of `react-native-worklets` which is a peer dependency of `react-native-reanimated`.
|
|
65
71
|
|
|
66
|
-
After updating
|
|
72
|
+
After updating Babel config, clear the Metro cache:
|
|
67
73
|
|
|
68
74
|
```sh
|
|
69
75
|
npx react-native start --reset-cache
|
|
@@ -86,22 +92,84 @@ Add `NSCameraUsageDescription` to your `Info.plist`:
|
|
|
86
92
|
|
|
87
93
|
### Android
|
|
88
94
|
|
|
89
|
-
|
|
95
|
+
ML Kit and all native dependencies are included automatically via `build.gradle`. No extra steps needed.
|
|
90
96
|
|
|
91
97
|
---
|
|
92
98
|
|
|
93
99
|
## Usage
|
|
94
100
|
|
|
95
|
-
|
|
101
|
+
There are two ways to use the library depending on how much control you need.
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
### Option 1 — `LivenessCameraModal` (recommended)
|
|
106
|
+
|
|
107
|
+
The easiest integration. Pass `visible` / `onClose` and you're done — the modal, close button, and full-screen layout are all handled for you.
|
|
96
108
|
|
|
97
109
|
```tsx
|
|
98
|
-
import {
|
|
110
|
+
import { useState } from 'react';
|
|
111
|
+
import { LivenessCameraModal } from '@rick427/react-native-liveness';
|
|
99
112
|
import type { CaptureResult } from '@rick427/react-native-liveness';
|
|
100
113
|
|
|
101
114
|
export default function VerificationScreen() {
|
|
115
|
+
const [showLiveness, setShowLiveness] = useState(false);
|
|
116
|
+
|
|
102
117
|
const handleCapture = (result: CaptureResult) => {
|
|
103
118
|
console.log('Photo path:', result.photo.path);
|
|
104
119
|
console.log('Liveness score:', result.livenessScore); // 0.0 – 1.0
|
|
120
|
+
setShowLiveness(false);
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
return (
|
|
124
|
+
<>
|
|
125
|
+
{/* Trigger however you like */}
|
|
126
|
+
<Button title="Verify Identity" onPress={() => setShowLiveness(true)} />
|
|
127
|
+
|
|
128
|
+
<LivenessCameraModal
|
|
129
|
+
visible={showLiveness}
|
|
130
|
+
onClose={() => setShowLiveness(false)}
|
|
131
|
+
onCapture={handleCapture}
|
|
132
|
+
onLivenessConfirmed={() => console.log('Live face confirmed!')}
|
|
133
|
+
onError={(err) => console.error(err)}
|
|
134
|
+
/>
|
|
135
|
+
</>
|
|
136
|
+
);
|
|
137
|
+
}
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
#### `LivenessCameraModal` props
|
|
141
|
+
|
|
142
|
+
| Prop | Type | Default | Description |
|
|
143
|
+
|---|---|---|---|
|
|
144
|
+
| `visible` | `boolean` | **required** | Controls modal visibility. |
|
|
145
|
+
| `onClose` | `() => void` | **required** | Called when the × button is pressed or Android back is fired. |
|
|
146
|
+
| `onCapture` | `(result: CaptureResult) => void` | **required** | Fired after photo is captured. |
|
|
147
|
+
| `animationType` | `'slide' \| 'fade' \| 'none'` | `'slide'` | Modal entrance/exit animation. |
|
|
148
|
+
| `closeButtonStyle` | `ViewStyle` | — | Override the close button container style (position, size, colours). |
|
|
149
|
+
| `closeButtonIconColor` | `string` | `'#fff'` | Colour of the × icon. |
|
|
150
|
+
| `closeButtonIconSize` | `number` | `18` | Size of the × icon in dp. |
|
|
151
|
+
| `onLivenessConfirmed` | `() => void` | — | Fired the moment liveness is confirmed, before countdown. |
|
|
152
|
+
| `onError` | `(err: Error) => void` | — | Fired on unrecoverable errors. |
|
|
153
|
+
| `countdownFrom` | `number` | `3` | Countdown start value. |
|
|
154
|
+
| `livenessThreshold` | `number` | `0.75` | Score (0–1) required to confirm liveness. |
|
|
155
|
+
| `confirmFrames` | `number` | `10` | Consecutive high-score frames required (~500 ms at 20 fps). |
|
|
156
|
+
| `soundEnabled` | `boolean` | `true` | Play native shutter sound on capture. |
|
|
157
|
+
| `fontFamily` | `string` | `'Baloo-Medium'` | Font applied to all text inside the component. |
|
|
158
|
+
|
|
159
|
+
---
|
|
160
|
+
|
|
161
|
+
### Option 2 — `LivenessCamera` (embedded)
|
|
162
|
+
|
|
163
|
+
Use this when you want full layout control — embed the camera directly inside your own screen or custom modal.
|
|
164
|
+
|
|
165
|
+
```tsx
|
|
166
|
+
import { LivenessCamera } from '@rick427/react-native-liveness';
|
|
167
|
+
import type { CaptureResult } from '@rick427/react-native-liveness';
|
|
168
|
+
|
|
169
|
+
export default function VerificationScreen() {
|
|
170
|
+
const handleCapture = (result: CaptureResult) => {
|
|
171
|
+
console.log('Photo path:', result.photo.path);
|
|
172
|
+
console.log('Liveness score:', result.livenessScore);
|
|
105
173
|
};
|
|
106
174
|
|
|
107
175
|
return (
|
|
@@ -115,20 +183,23 @@ export default function VerificationScreen() {
|
|
|
115
183
|
}
|
|
116
184
|
```
|
|
117
185
|
|
|
118
|
-
|
|
186
|
+
#### `LivenessCamera` props
|
|
119
187
|
|
|
120
188
|
| Prop | Type | Default | Description |
|
|
121
189
|
|---|---|---|---|
|
|
122
|
-
| `onCapture` | `(result: CaptureResult) => void` | **required** | Fired after photo is
|
|
123
|
-
| `onLivenessConfirmed` | `() => void` | — | Fired the moment liveness is confirmed, before
|
|
190
|
+
| `onCapture` | `(result: CaptureResult) => void` | **required** | Fired after photo is captured. |
|
|
191
|
+
| `onLivenessConfirmed` | `() => void` | — | Fired the moment liveness is confirmed, before countdown. |
|
|
124
192
|
| `onError` | `(err: Error) => void` | — | Fired on unrecoverable errors. |
|
|
125
193
|
| `countdownFrom` | `number` | `3` | Countdown start value. |
|
|
126
|
-
| `livenessThreshold` | `number` | `0.75` | Score (0–1) required
|
|
127
|
-
| `confirmFrames` | `number` | `
|
|
128
|
-
| `soundEnabled` | `boolean` | `true` | Play
|
|
194
|
+
| `livenessThreshold` | `number` | `0.75` | Score (0–1) required to confirm liveness. |
|
|
195
|
+
| `confirmFrames` | `number` | `10` | Consecutive high-score frames required (~500 ms at 20 fps). |
|
|
196
|
+
| `soundEnabled` | `boolean` | `true` | Play native shutter sound on capture. |
|
|
197
|
+
| `fontFamily` | `string` | `'Baloo-Medium'` | Font applied to all text inside the component. |
|
|
129
198
|
| `style` | `ViewStyle` | — | Style for the root container. |
|
|
130
199
|
|
|
131
|
-
|
|
200
|
+
---
|
|
201
|
+
|
|
202
|
+
### `CaptureResult`
|
|
132
203
|
|
|
133
204
|
```ts
|
|
134
205
|
type CaptureResult = {
|
|
@@ -140,34 +211,48 @@ type CaptureResult = {
|
|
|
140
211
|
|
|
141
212
|
---
|
|
142
213
|
|
|
214
|
+
## Scanner animation
|
|
215
|
+
|
|
216
|
+
The circle guide layers three animations built entirely with `Animated` + `react-native-svg` — no extra dependencies.
|
|
217
|
+
|
|
218
|
+
| Layer | Behaviour |
|
|
219
|
+
|---|---|
|
|
220
|
+
| **Dim base ring** | Always visible; gives a positioning target before any progress starts. |
|
|
221
|
+
| **Sweep scan line** | A gradient bar ping-pongs top → bottom inside the circle (1.8 s/leg). Fades out on confirm. |
|
|
222
|
+
| **Rotating brackets** | Four corner arcs rotate slowly (1 rev / 6 s), suggesting the circle boundary during scanning. Freeze in place on confirm. |
|
|
223
|
+
| **Progress arc** | The circle border draws itself in clockwise from 12 o'clock as `livenessScore / livenessThreshold` builds. White → yellow → green. |
|
|
224
|
+
|
|
225
|
+
---
|
|
226
|
+
|
|
143
227
|
## How liveness scoring works
|
|
144
228
|
|
|
145
|
-
Each camera frame is scored across four signals:
|
|
229
|
+
Each camera frame is scored across four signals at up to **20 fps** (ML Kit is throttled via `runAtTargetFps` while the preview renders at 60 fps):
|
|
146
230
|
|
|
147
231
|
| Signal | Weight | Detail |
|
|
148
232
|
|---|---|---|
|
|
149
|
-
| Face detected | 20% | ML Kit found a face in the frame |
|
|
150
|
-
| Face size | 20% | Face width is
|
|
151
|
-
| Head pose | 30% | Yaw < ±
|
|
152
|
-
| Eyes open | 30% | Average of left/right eye open probability from ML Kit |
|
|
233
|
+
| Face detected | 20% | ML Kit found a face in the frame. |
|
|
234
|
+
| Face size | 20% | Face width is 15–80% of the frame. Soft-edge scoring at boundaries. |
|
|
235
|
+
| Head pose | 30% | Yaw < ±25° and pitch < ±25° from frontal. Soft decay outside range. |
|
|
236
|
+
| Eyes open | 30% | Average of left/right eye open probability from ML Kit. |
|
|
153
237
|
|
|
154
|
-
A rolling window of the last 20 frame scores is maintained. Liveness is confirmed once `confirmFrames` consecutive frames all score above `livenessThreshold`.
|
|
238
|
+
A rolling window of the last 20 frame scores is maintained. Liveness is confirmed once `confirmFrames` consecutive frames all score above `livenessThreshold`. Bad frames **decay** the streak by 2 instead of resetting it, making detection resilient to momentary noise.
|
|
155
239
|
|
|
156
240
|
---
|
|
157
241
|
|
|
158
242
|
## Architecture
|
|
159
243
|
|
|
160
244
|
```
|
|
161
|
-
Camera
|
|
245
|
+
Camera (60 fps preview)
|
|
162
246
|
↓ [worklet thread — Vision Camera frame processor]
|
|
163
|
-
Native plugin (Swift / Kotlin)
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
↓ [
|
|
247
|
+
runAtTargetFps(20) → Native plugin (Swift / Kotlin)
|
|
248
|
+
→ ML Kit Face Detection
|
|
249
|
+
→ { bounds, yawAngle, pitchAngle, leftEyeOpenProbability, … }
|
|
250
|
+
↓ [Worklets.createRunOnJS → JS thread, ~20×/sec]
|
|
167
251
|
useLivenessCamera hook
|
|
168
|
-
→ scoreFrame()
|
|
252
|
+
→ scoreFrame() — soft-edge signals, weighted sum
|
|
169
253
|
→ rolling 20-frame window
|
|
170
|
-
→
|
|
254
|
+
→ consecutiveGood++ on pass, decay -2 on fail
|
|
255
|
+
→ 10 consecutive frames > threshold → liveness confirmed
|
|
171
256
|
↓
|
|
172
257
|
Countdown 3 → 2 → 1 (React Native Animated)
|
|
173
258
|
↓
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
3
|
import { useCallback, useEffect, useRef, useState } from 'react';
|
|
4
|
-
import { Animated
|
|
4
|
+
import { Animated as RNAnimated, StyleSheet, Text, View } from 'react-native';
|
|
5
|
+
import Animated, { cancelAnimation, Easing, useAnimatedProps, useSharedValue, withRepeat, withSequence, withTiming } from 'react-native-reanimated';
|
|
5
6
|
import { Camera, useCameraDevice, useCameraFormat, useCameraPermission } from 'react-native-vision-camera';
|
|
6
7
|
import { Circle, ClipPath, Defs, G, LinearGradient, Path, Rect, Stop, Svg } from 'react-native-svg';
|
|
7
8
|
import { useLivenessCamera } from "./useLivenessCamera.js";
|
|
8
9
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
9
|
-
// ─── Animated SVG components
|
|
10
|
-
//
|
|
10
|
+
// ─── Animated SVG components (Reanimated) ────────────────────────────────────
|
|
11
|
+
// createAnimatedComponent from react-native-reanimated properly drives SVG
|
|
12
|
+
// presentation attributes (strokeDashoffset, y, rotation) on the UI thread.
|
|
11
13
|
const AnimatedCircle = Animated.createAnimatedComponent(Circle);
|
|
12
14
|
const AnimatedG = Animated.createAnimatedComponent(G);
|
|
13
15
|
const AnimatedRect = Animated.createAnimatedComponent(Rect);
|
|
@@ -17,7 +19,7 @@ const DEFAULT_FONT = 'Baloo-Medium';
|
|
|
17
19
|
const CIRCLE_DIAMETER_RATIO = 0.82;
|
|
18
20
|
const STROKE_WIDTH = 3;
|
|
19
21
|
const K = 0.5523; // cubic bezier ellipse approximation
|
|
20
|
-
const SCAN_LINE_HEIGHT =
|
|
22
|
+
const SCAN_LINE_HEIGHT = 2; // px — thin line, like a real liveness SDK
|
|
21
23
|
const BRACKET_SPAN_DEG = 44; // degrees each corner bracket spans
|
|
22
24
|
const BRACKET_STROKE = STROKE_WIDTH + 1;
|
|
23
25
|
|
|
@@ -61,6 +63,21 @@ function bracketArcPath(cx, cy, r, centerDeg, spanDeg) {
|
|
|
61
63
|
}
|
|
62
64
|
|
|
63
65
|
// ─── CircleOverlay ────────────────────────────────────────────────────────────
|
|
66
|
+
const _worklet_15111972513221_init_data = {
|
|
67
|
+
code: "function LivenessCameraTsx1(){const{cy,r,scanProgress,SCAN_LINE_HEIGHT,scanOpacity}=this.__closure;return{y:cy-r+2+scanProgress.value*(2*r-SCAN_LINE_HEIGHT-4),opacity:scanOpacity.value};}",
|
|
68
|
+
location: "/home/runner/work/react-native-liveness/react-native-liveness/src/LivenessCamera.tsx",
|
|
69
|
+
sourceMap: "{\"version\":3,\"names\":[\"LivenessCameraTsx1\",\"cy\",\"r\",\"scanProgress\",\"SCAN_LINE_HEIGHT\",\"scanOpacity\",\"__closure\",\"y\",\"value\",\"opacity\"],\"sources\":[\"/home/runner/work/react-native-liveness/react-native-liveness/src/LivenessCamera.tsx\"],\"mappings\":\"AAmII,SAAAA,mBAAA,QAAAC,EAAA,CAAAC,CAAA,CAAAC,YAAA,CAAAC,gBAAA,CAAAC,WAAA,OAAAC,SAAA,OAAO,CAELC,CAAC,CAAEN,EAAE,CAAGC,CAAC,CAAG,CAAC,CAAGC,YAAY,CAACK,KAAK,EAAI,CAAC,CAAGN,CAAC,CAAGE,gBAAgB,CAAG,CAAC,CAAC,CACnEK,OAAO,CAAEJ,WAAW,CAACG,KACvB,CAAC\",\"ignoreList\":[]}"
|
|
70
|
+
};
|
|
71
|
+
const _worklet_14693916078586_init_data = {
|
|
72
|
+
code: "function LivenessCameraTsx2(){const{bracketRot,cx,cy}=this.__closure;return{rotation:bracketRot.value%360,originX:cx,originY:cy};}",
|
|
73
|
+
location: "/home/runner/work/react-native-liveness/react-native-liveness/src/LivenessCamera.tsx",
|
|
74
|
+
sourceMap: "{\"version\":3,\"names\":[\"LivenessCameraTsx2\",\"bracketRot\",\"cx\",\"cy\",\"__closure\",\"rotation\",\"value\",\"originX\",\"originY\"],\"sources\":[\"/home/runner/work/react-native-liveness/react-native-liveness/src/LivenessCamera.tsx\"],\"mappings\":\"AA4II,SAAAA,mBAAA,QAAAC,UAAA,CAAAC,EAAA,CAAAC,EAAA,OAAAC,SAAA,OAAO,CAELC,QAAQ,CAAEJ,UAAU,CAACK,KAAK,CAAG,GAAG,CAChCC,OAAO,CAAEL,EAAE,CACXM,OAAO,CAAEL,EACX,CAAC\",\"ignoreList\":[]}"
|
|
75
|
+
};
|
|
76
|
+
const _worklet_1688522500078_init_data = {
|
|
77
|
+
code: "function LivenessCameraTsx3(){const{circumference,livenessProgress,livenessThreshold}=this.__closure;return{strokeDashoffset:circumference-livenessProgress.value/livenessThreshold*circumference};}",
|
|
78
|
+
location: "/home/runner/work/react-native-liveness/react-native-liveness/src/LivenessCamera.tsx",
|
|
79
|
+
sourceMap: "{\"version\":3,\"names\":[\"LivenessCameraTsx3\",\"circumference\",\"livenessProgress\",\"livenessThreshold\",\"__closure\",\"strokeDashoffset\",\"value\"],\"sources\":[\"/home/runner/work/react-native-liveness/react-native-liveness/src/LivenessCamera.tsx\"],\"mappings\":\"AAsJI,SAAAA,mBAAA,QAAAC,aAAA,CAAAC,gBAAA,CAAAC,iBAAA,OAAAC,SAAA,OAAO,CACLC,gBAAgB,CACdJ,aAAa,CACZC,gBAAgB,CAACI,KAAK,CAAGH,iBAAiB,CAAIF,aACnD,CAAC\",\"ignoreList\":[]}"
|
|
80
|
+
};
|
|
64
81
|
function CircleOverlay({
|
|
65
82
|
width,
|
|
66
83
|
height,
|
|
@@ -68,99 +85,156 @@ function CircleOverlay({
|
|
|
68
85
|
score,
|
|
69
86
|
livenessThreshold
|
|
70
87
|
}) {
|
|
71
|
-
// ──
|
|
72
|
-
|
|
73
|
-
const
|
|
74
|
-
const
|
|
75
|
-
|
|
76
|
-
const
|
|
77
|
-
|
|
88
|
+
// ── Shared values — all hooks before any early return ─────────────────────
|
|
89
|
+
// scanProgress 0=top 1=bottom, ping-pongs continuously
|
|
90
|
+
const scanProgress = useSharedValue(0);
|
|
91
|
+
const scanOpacity = useSharedValue(1);
|
|
92
|
+
// bracketRot drives the slow bracket rotation in degrees
|
|
93
|
+
const bracketRot = useSharedValue(0);
|
|
94
|
+
// livenessProgress tracks smoothed score for the arc
|
|
95
|
+
const livenessProgress = useSharedValue(0);
|
|
96
|
+
|
|
97
|
+
// ── Geometry — computed before useAnimatedProps (safe when 0) ─────────────
|
|
98
|
+
const cx = width / 2;
|
|
99
|
+
const cy = height * 0.42;
|
|
100
|
+
const r = width * CIRCLE_DIAMETER_RATIO / 2;
|
|
101
|
+
const circumference = 2 * Math.PI * r;
|
|
102
|
+
const color = getCircleColor(state, score);
|
|
103
|
+
|
|
104
|
+
// ── Animated props — UI-thread worklets, deps rebuilt when geometry changes
|
|
105
|
+
const scanAnimProps = useAnimatedProps(function LivenessCameraTsx1Factory({
|
|
106
|
+
_worklet_15111972513221_init_data,
|
|
107
|
+
cy,
|
|
108
|
+
r,
|
|
109
|
+
scanProgress,
|
|
110
|
+
SCAN_LINE_HEIGHT,
|
|
111
|
+
scanOpacity
|
|
112
|
+
}) {
|
|
113
|
+
const _e = [new global.Error(), -6, -27];
|
|
114
|
+
const LivenessCameraTsx1 = () => ({
|
|
115
|
+
// Map 0→1 progress onto the pixel range inside the circle
|
|
116
|
+
y: cy - r + 2 + scanProgress.value * (2 * r - SCAN_LINE_HEIGHT - 4),
|
|
117
|
+
opacity: scanOpacity.value
|
|
118
|
+
});
|
|
119
|
+
LivenessCameraTsx1.__closure = {
|
|
120
|
+
cy,
|
|
121
|
+
r,
|
|
122
|
+
scanProgress,
|
|
123
|
+
SCAN_LINE_HEIGHT,
|
|
124
|
+
scanOpacity
|
|
125
|
+
};
|
|
126
|
+
LivenessCameraTsx1.__workletHash = 15111972513221;
|
|
127
|
+
LivenessCameraTsx1.__pluginVersion = "0.8.3";
|
|
128
|
+
LivenessCameraTsx1.__initData = _worklet_15111972513221_init_data;
|
|
129
|
+
LivenessCameraTsx1.__stackDetails = _e;
|
|
130
|
+
return LivenessCameraTsx1;
|
|
131
|
+
}({
|
|
132
|
+
_worklet_15111972513221_init_data,
|
|
133
|
+
cy,
|
|
134
|
+
r,
|
|
135
|
+
scanProgress,
|
|
136
|
+
SCAN_LINE_HEIGHT,
|
|
137
|
+
scanOpacity
|
|
138
|
+
}), [cy, r]);
|
|
139
|
+
const bracketAnimProps = useAnimatedProps(function LivenessCameraTsx2Factory({
|
|
140
|
+
_worklet_14693916078586_init_data,
|
|
141
|
+
bracketRot,
|
|
142
|
+
cx,
|
|
143
|
+
cy
|
|
144
|
+
}) {
|
|
145
|
+
const _e = [new global.Error(), -4, -27];
|
|
146
|
+
const LivenessCameraTsx2 = () => ({
|
|
147
|
+
// react-native-svg accepts numeric rotation + origin instead of a string
|
|
148
|
+
rotation: bracketRot.value % 360,
|
|
149
|
+
originX: cx,
|
|
150
|
+
originY: cy
|
|
151
|
+
});
|
|
152
|
+
LivenessCameraTsx2.__closure = {
|
|
153
|
+
bracketRot,
|
|
154
|
+
cx,
|
|
155
|
+
cy
|
|
156
|
+
};
|
|
157
|
+
LivenessCameraTsx2.__workletHash = 14693916078586;
|
|
158
|
+
LivenessCameraTsx2.__pluginVersion = "0.8.3";
|
|
159
|
+
LivenessCameraTsx2.__initData = _worklet_14693916078586_init_data;
|
|
160
|
+
LivenessCameraTsx2.__stackDetails = _e;
|
|
161
|
+
return LivenessCameraTsx2;
|
|
162
|
+
}({
|
|
163
|
+
_worklet_14693916078586_init_data,
|
|
164
|
+
bracketRot,
|
|
165
|
+
cx,
|
|
166
|
+
cy
|
|
167
|
+
}), [cx, cy]);
|
|
168
|
+
const progressAnimProps = useAnimatedProps(function LivenessCameraTsx3Factory({
|
|
169
|
+
_worklet_1688522500078_init_data,
|
|
170
|
+
circumference,
|
|
171
|
+
livenessProgress,
|
|
172
|
+
livenessThreshold
|
|
173
|
+
}) {
|
|
174
|
+
const _e = [new global.Error(), -4, -27];
|
|
175
|
+
const LivenessCameraTsx3 = () => ({
|
|
176
|
+
strokeDashoffset: circumference - livenessProgress.value / livenessThreshold * circumference
|
|
177
|
+
});
|
|
178
|
+
LivenessCameraTsx3.__closure = {
|
|
179
|
+
circumference,
|
|
180
|
+
livenessProgress,
|
|
181
|
+
livenessThreshold
|
|
182
|
+
};
|
|
183
|
+
LivenessCameraTsx3.__workletHash = 1688522500078;
|
|
184
|
+
LivenessCameraTsx3.__pluginVersion = "0.8.3";
|
|
185
|
+
LivenessCameraTsx3.__initData = _worklet_1688522500078_init_data;
|
|
186
|
+
LivenessCameraTsx3.__stackDetails = _e;
|
|
187
|
+
return LivenessCameraTsx3;
|
|
188
|
+
}({
|
|
189
|
+
_worklet_1688522500078_init_data,
|
|
190
|
+
circumference,
|
|
191
|
+
livenessProgress,
|
|
192
|
+
livenessThreshold
|
|
193
|
+
}), [circumference, livenessThreshold]);
|
|
78
194
|
|
|
79
195
|
// ── Start scan line + bracket rotation on mount ───────────────────────────
|
|
80
196
|
useEffect(() => {
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
}),
|
|
88
|
-
|
|
89
|
-
duration: 1800,
|
|
90
|
-
easing: Easing.linear,
|
|
91
|
-
useNativeDriver: false
|
|
92
|
-
})]));
|
|
93
|
-
scanLoopRef.current.start();
|
|
94
|
-
|
|
95
|
-
// Brackets: one full rotation every 6 s — slow, atmospheric
|
|
96
|
-
bracketLoopRef.current = Animated.loop(Animated.timing(bracketAnim, {
|
|
97
|
-
toValue: 360,
|
|
197
|
+
scanProgress.value = withRepeat(withSequence(withTiming(1, {
|
|
198
|
+
duration: 2400,
|
|
199
|
+
easing: Easing.linear
|
|
200
|
+
}), withTiming(0, {
|
|
201
|
+
duration: 2400,
|
|
202
|
+
easing: Easing.linear
|
|
203
|
+
})), -1, false);
|
|
204
|
+
bracketRot.value = withRepeat(withTiming(360, {
|
|
98
205
|
duration: 6000,
|
|
99
|
-
easing: Easing.linear
|
|
100
|
-
|
|
101
|
-
}));
|
|
102
|
-
bracketLoopRef.current.start();
|
|
206
|
+
easing: Easing.linear
|
|
207
|
+
}), -1, false);
|
|
103
208
|
return () => {
|
|
104
|
-
|
|
105
|
-
|
|
209
|
+
cancelAnimation(scanProgress);
|
|
210
|
+
cancelAnimation(bracketRot);
|
|
106
211
|
};
|
|
107
212
|
}, []); // eslint-disable-line react-hooks/exhaustive-deps
|
|
108
213
|
|
|
109
|
-
// ── On confirmed:
|
|
214
|
+
// ── On liveness confirmed: freeze brackets, fade scan line out ────────────
|
|
110
215
|
useEffect(() => {
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
duration: 350,
|
|
118
|
-
useNativeDriver: false
|
|
119
|
-
}).start();
|
|
216
|
+
if (state !== 'scanning') {
|
|
217
|
+
cancelAnimation(scanProgress);
|
|
218
|
+
cancelAnimation(bracketRot);
|
|
219
|
+
scanOpacity.value = withTiming(0, {
|
|
220
|
+
duration: 350
|
|
221
|
+
});
|
|
120
222
|
}
|
|
121
|
-
}, [state
|
|
223
|
+
}, [state]); // eslint-disable-line react-hooks/exhaustive-deps
|
|
122
224
|
|
|
123
225
|
// ── Drive progress arc from live score ────────────────────────────────────
|
|
124
226
|
useEffect(() => {
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
}).start();
|
|
130
|
-
}, [score, livenessThreshold, progressAnim]);
|
|
227
|
+
livenessProgress.value = withTiming(Math.min(score, livenessThreshold), {
|
|
228
|
+
duration: 180
|
|
229
|
+
});
|
|
230
|
+
}, [score, livenessThreshold]); // eslint-disable-line react-hooks/exhaustive-deps
|
|
131
231
|
|
|
132
232
|
// ── Guard — render nothing until dimensions are known ─────────────────────
|
|
133
233
|
if (width === 0 || height === 0) return null;
|
|
134
234
|
|
|
135
|
-
//
|
|
136
|
-
const cx = width / 2;
|
|
137
|
-
const cy = height * 0.42;
|
|
138
|
-
const r = width * CIRCLE_DIAMETER_RATIO / 2;
|
|
139
|
-
const circumference = 2 * Math.PI * r;
|
|
140
|
-
const color = getCircleColor(state, score);
|
|
141
|
-
|
|
142
|
-
// Scrim: full-screen dark rect with transparent circle hole
|
|
235
|
+
// Scrim: full-screen rect with transparent circle cutout (evenodd rule)
|
|
143
236
|
const scrimD = `M0 0H${width}V${height}H0Z ${circlePath(cx, cy, r)}`;
|
|
144
237
|
|
|
145
|
-
// Scan line Y: sweeps from just inside top to just inside bottom of circle
|
|
146
|
-
const scanLineY = scanAnim.interpolate({
|
|
147
|
-
inputRange: [0, 1],
|
|
148
|
-
outputRange: [cy - r + 2, cy + r - SCAN_LINE_HEIGHT - 2]
|
|
149
|
-
});
|
|
150
|
-
|
|
151
|
-
// Progress arc: strokeDashoffset goes from full (no arc) → 0 (full arc)
|
|
152
|
-
const strokeDashoffset = progressAnim.interpolate({
|
|
153
|
-
inputRange: [0, livenessThreshold],
|
|
154
|
-
outputRange: [circumference, 0],
|
|
155
|
-
extrapolate: 'clamp'
|
|
156
|
-
});
|
|
157
|
-
|
|
158
|
-
// Bracket group rotation — centred on the circle
|
|
159
|
-
const bracketTransform = bracketAnim.interpolate({
|
|
160
|
-
inputRange: [0, 360],
|
|
161
|
-
outputRange: [`rotate(0, ${cx}, ${cy})`, `rotate(360, ${cx}, ${cy})`]
|
|
162
|
-
});
|
|
163
|
-
|
|
164
238
|
// 4 corner brackets at NE / SE / SW / NW diagonal positions
|
|
165
239
|
const bracketD = [45, 135, 225, 315].map(deg => bracketArcPath(cx, cy, r, deg, BRACKET_SPAN_DEG)).join(' ');
|
|
166
240
|
return /*#__PURE__*/_jsxs(Svg, {
|
|
@@ -179,20 +253,20 @@ function CircleOverlay({
|
|
|
179
253
|
id: "scan-gradient",
|
|
180
254
|
x1: "0",
|
|
181
255
|
y1: "0",
|
|
182
|
-
x2: "
|
|
183
|
-
y2: "
|
|
256
|
+
x2: "1",
|
|
257
|
+
y2: "0",
|
|
184
258
|
children: [/*#__PURE__*/_jsx(Stop, {
|
|
185
259
|
offset: "0",
|
|
186
260
|
stopColor: "#fff",
|
|
187
261
|
stopOpacity: "0"
|
|
188
262
|
}), /*#__PURE__*/_jsx(Stop, {
|
|
189
|
-
offset: "0.
|
|
263
|
+
offset: "0.08",
|
|
190
264
|
stopColor: "#fff",
|
|
191
|
-
stopOpacity: "0.
|
|
265
|
+
stopOpacity: "0.55"
|
|
192
266
|
}), /*#__PURE__*/_jsx(Stop, {
|
|
193
|
-
offset: "0.
|
|
267
|
+
offset: "0.92",
|
|
194
268
|
stopColor: "#fff",
|
|
195
|
-
stopOpacity: "0.
|
|
269
|
+
stopOpacity: "0.55"
|
|
196
270
|
}), /*#__PURE__*/_jsx(Stop, {
|
|
197
271
|
offset: "1",
|
|
198
272
|
stopColor: "#fff",
|
|
@@ -214,14 +288,13 @@ function CircleOverlay({
|
|
|
214
288
|
clipPath: "url(#liveness-circle-clip)",
|
|
215
289
|
children: /*#__PURE__*/_jsx(AnimatedRect, {
|
|
216
290
|
x: cx - r,
|
|
217
|
-
y: scanLineY,
|
|
218
291
|
width: r * 2,
|
|
219
292
|
height: SCAN_LINE_HEIGHT,
|
|
220
293
|
fill: "url(#scan-gradient)",
|
|
221
|
-
|
|
294
|
+
animatedProps: scanAnimProps
|
|
222
295
|
})
|
|
223
296
|
}), /*#__PURE__*/_jsx(AnimatedG, {
|
|
224
|
-
|
|
297
|
+
animatedProps: bracketAnimProps,
|
|
225
298
|
children: /*#__PURE__*/_jsx(Path, {
|
|
226
299
|
d: bracketD,
|
|
227
300
|
fill: "none",
|
|
@@ -238,9 +311,9 @@ function CircleOverlay({
|
|
|
238
311
|
stroke: color,
|
|
239
312
|
strokeWidth: STROKE_WIDTH,
|
|
240
313
|
strokeDasharray: circumference,
|
|
241
|
-
strokeDashoffset: strokeDashoffset,
|
|
242
314
|
strokeLinecap: "round",
|
|
243
|
-
transform: `rotate(-90, ${cx}, ${cy})
|
|
315
|
+
transform: `rotate(-90, ${cx}, ${cy})`,
|
|
316
|
+
animatedProps: progressAnimProps
|
|
244
317
|
})]
|
|
245
318
|
});
|
|
246
319
|
}
|
|
@@ -250,26 +323,26 @@ function CountdownBubble({
|
|
|
250
323
|
value,
|
|
251
324
|
fontFamily
|
|
252
325
|
}) {
|
|
253
|
-
const scale = useRef(new
|
|
254
|
-
const opacity = useRef(new
|
|
326
|
+
const scale = useRef(new RNAnimated.Value(0)).current;
|
|
327
|
+
const opacity = useRef(new RNAnimated.Value(0)).current;
|
|
255
328
|
useEffect(() => {
|
|
256
|
-
|
|
329
|
+
RNAnimated.parallel([RNAnimated.sequence([RNAnimated.spring(scale, {
|
|
257
330
|
toValue: 1.2,
|
|
258
331
|
stiffness: 200,
|
|
259
332
|
damping: 6,
|
|
260
333
|
useNativeDriver: true
|
|
261
|
-
}),
|
|
334
|
+
}), RNAnimated.spring(scale, {
|
|
262
335
|
toValue: 1.0,
|
|
263
336
|
stiffness: 150,
|
|
264
337
|
damping: 8,
|
|
265
338
|
useNativeDriver: true
|
|
266
|
-
})]),
|
|
339
|
+
})]), RNAnimated.timing(opacity, {
|
|
267
340
|
toValue: 1,
|
|
268
341
|
duration: 150,
|
|
269
342
|
useNativeDriver: true
|
|
270
343
|
})]).start();
|
|
271
344
|
return () => {
|
|
272
|
-
|
|
345
|
+
RNAnimated.timing(opacity, {
|
|
273
346
|
toValue: 0,
|
|
274
347
|
duration: 200,
|
|
275
348
|
useNativeDriver: true
|
|
@@ -277,7 +350,7 @@ function CountdownBubble({
|
|
|
277
350
|
};
|
|
278
351
|
}, []); // eslint-disable-line react-hooks/exhaustive-deps
|
|
279
352
|
|
|
280
|
-
return /*#__PURE__*/_jsx(
|
|
353
|
+
return /*#__PURE__*/_jsx(RNAnimated.View, {
|
|
281
354
|
style: [styles.countdownBubble, {
|
|
282
355
|
opacity,
|
|
283
356
|
transform: [{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["useCallback","useEffect","useRef","useState","Animated","Easing","StyleSheet","Text","View","Camera","useCameraDevice","useCameraFormat","useCameraPermission","Circle","ClipPath","Defs","G","LinearGradient","Path","Rect","Stop","Svg","useLivenessCamera","jsx","_jsx","jsxs","_jsxs","AnimatedCircle","createAnimatedComponent","AnimatedG","AnimatedRect","DEFAULT_FONT","CIRCLE_DIAMETER_RATIO","STROKE_WIDTH","K","SCAN_LINE_HEIGHT","BRACKET_SPAN_DEG","BRACKET_STROKE","getCircleColor","state","score","circlePath","cx","cy","r","join","bracketArcPath","centerDeg","spanDeg","toRad","d","Math","PI","a1","a2","x1","cos","y1","sin","x2","y2","CircleOverlay","width","height","livenessThreshold","scanAnim","Value","current","scanOpacity","progressAnim","bracketAnim","scanLoopRef","bracketLoopRef","loop","sequence","timing","toValue","duration","easing","linear","useNativeDriver","start","stop","isActive","min","circumference","color","scrimD","scanLineY","interpolate","inputRange","outputRange","strokeDashoffset","extrapolate","bracketTransform","bracketD","map","deg","style","absoluteFill","children","id","offset","stopColor","stopOpacity","fill","fillRule","stroke","strokeWidth","clipPath","x","y","opacity","transform","strokeLinecap","strokeDasharray","CountdownBubble","value","fontFamily","scale","parallel","spring","stiffness","damping","styles","countdownBubble","countdownText","LivenessCamera","onCapture","onLivenessConfirmed","onError","countdownFrom","confirmFrames","soundEnabled","hasPermission","requestPermission","device","format","fps","maxFps","cameraRef","containerSize","setContainerSize","frameProcessor","livenessState","livenessScore","countdown","feedback","handleLayout","e","nativeEvent","layout","catch","Error","root","centered","permissionText","onLayout","ref","photo","pixelFormat","feedbackContainer","feedbackText","countdownContainer","captureFlash","pointerEvents","create","flex","backgroundColor","overflow","justifyContent","alignItems","fontSize","textAlign","paddingHorizontal","position","bottom","left","right","textShadowColor","textShadowOffset","textShadowRadius","absoluteFillObject","borderRadius","borderWidth","borderColor","lineHeight"],"sourceRoot":"../../src","sources":["LivenessCamera.tsx"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":["useCallback","useEffect","useRef","useState","Animated","RNAnimated","StyleSheet","Text","View","cancelAnimation","Easing","useAnimatedProps","useSharedValue","withRepeat","withSequence","withTiming","Camera","useCameraDevice","useCameraFormat","useCameraPermission","Circle","ClipPath","Defs","G","LinearGradient","Path","Rect","Stop","Svg","useLivenessCamera","jsx","_jsx","jsxs","_jsxs","AnimatedCircle","createAnimatedComponent","AnimatedG","AnimatedRect","DEFAULT_FONT","CIRCLE_DIAMETER_RATIO","STROKE_WIDTH","K","SCAN_LINE_HEIGHT","BRACKET_SPAN_DEG","BRACKET_STROKE","getCircleColor","state","score","circlePath","cx","cy","r","join","bracketArcPath","centerDeg","spanDeg","toRad","d","Math","PI","a1","a2","x1","cos","y1","sin","x2","y2","_worklet_15111972513221_init_data","code","location","sourceMap","_worklet_14693916078586_init_data","_worklet_1688522500078_init_data","CircleOverlay","width","height","livenessThreshold","scanProgress","scanOpacity","bracketRot","livenessProgress","circumference","color","scanAnimProps","LivenessCameraTsx1Factory","_e","global","Error","LivenessCameraTsx1","y","value","opacity","__closure","__workletHash","__pluginVersion","__initData","__stackDetails","bracketAnimProps","LivenessCameraTsx2Factory","LivenessCameraTsx2","rotation","originX","originY","progressAnimProps","LivenessCameraTsx3Factory","LivenessCameraTsx3","strokeDashoffset","duration","easing","linear","min","scrimD","bracketD","map","deg","style","absoluteFill","children","id","offset","stopColor","stopOpacity","fill","fillRule","stroke","strokeWidth","clipPath","x","animatedProps","strokeLinecap","strokeDasharray","transform","CountdownBubble","fontFamily","scale","Value","current","parallel","sequence","spring","toValue","stiffness","damping","useNativeDriver","timing","start","styles","countdownBubble","countdownText","LivenessCamera","onCapture","onLivenessConfirmed","onError","countdownFrom","confirmFrames","soundEnabled","hasPermission","requestPermission","device","format","fps","maxFps","cameraRef","containerSize","setContainerSize","frameProcessor","livenessState","livenessScore","countdown","feedback","handleLayout","e","nativeEvent","layout","catch","root","centered","permissionText","onLayout","ref","isActive","photo","pixelFormat","feedbackContainer","feedbackText","countdownContainer","captureFlash","pointerEvents","create","flex","backgroundColor","overflow","justifyContent","alignItems","fontSize","textAlign","paddingHorizontal","position","bottom","left","right","textShadowColor","textShadowOffset","textShadowRadius","absoluteFillObject","borderRadius","borderWidth","borderColor","lineHeight"],"sourceRoot":"../../src","sources":["LivenessCamera.tsx"],"mappings":"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","ignoreList":[]}
|
|
@@ -2,19 +2,39 @@
|
|
|
2
2
|
|
|
3
3
|
import { useMemo } from 'react';
|
|
4
4
|
import { VisionCameraProxy } from 'react-native-vision-camera';
|
|
5
|
+
const _worklet_4012480599600_init_data = {
|
|
6
|
+
code: "function LivenessDetectorTs1(frame){const{plugin}=this.__closure;const result=plugin.call(frame);return result;}",
|
|
7
|
+
location: "/home/runner/work/react-native-liveness/react-native-liveness/src/LivenessDetector.ts",
|
|
8
|
+
sourceMap: "{\"version\":3,\"names\":[\"LivenessDetectorTs1\",\"frame\",\"plugin\",\"__closure\",\"result\",\"call\"],\"sources\":[\"/home/runner/work/react-native-liveness/react-native-liveness/src/LivenessDetector.ts\"],\"mappings\":\"AAsBoB,QAAC,CAAAA,mBAAkCA,CAAAC,KAAA,QAAAC,MAAA,OAAAC,SAAA,CAEjD,KAAM,CAAAC,MAAM,CAAGF,MAAM,CAACG,IAAI,CAACJ,KAAK,CAAC,CAEjC,MAAO,CAAAG,MAAM,CACf\",\"ignoreList\":[]}"
|
|
9
|
+
};
|
|
5
10
|
function createPlugin() {
|
|
6
11
|
const plugin = VisionCameraProxy.initFrameProcessorPlugin('detectLiveness', {});
|
|
7
12
|
if (!plugin) {
|
|
8
13
|
throw new Error('[LivenessCamera] Frame Processor Plugin "detectLiveness" not found. ' + 'Make sure the native module is linked correctly.');
|
|
9
14
|
}
|
|
10
15
|
return {
|
|
11
|
-
detectLiveness:
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
detectLiveness: function LivenessDetectorTs1Factory({
|
|
17
|
+
_worklet_4012480599600_init_data,
|
|
18
|
+
plugin
|
|
19
|
+
}) {
|
|
20
|
+
const _e = [new global.Error(), -2, -27];
|
|
21
|
+
const LivenessDetectorTs1 = function (frame) {
|
|
22
|
+
const result = plugin.call(frame);
|
|
23
|
+
// plugin.call returns a loosely-typed BasicParameterType — cast via unknown
|
|
24
|
+
return result;
|
|
25
|
+
};
|
|
26
|
+
LivenessDetectorTs1.__closure = {
|
|
27
|
+
plugin
|
|
28
|
+
};
|
|
29
|
+
LivenessDetectorTs1.__workletHash = 4012480599600;
|
|
30
|
+
LivenessDetectorTs1.__pluginVersion = "0.8.3";
|
|
31
|
+
LivenessDetectorTs1.__initData = _worklet_4012480599600_init_data;
|
|
32
|
+
LivenessDetectorTs1.__stackDetails = _e;
|
|
33
|
+
return LivenessDetectorTs1;
|
|
34
|
+
}({
|
|
35
|
+
_worklet_4012480599600_init_data,
|
|
36
|
+
plugin
|
|
37
|
+
})
|
|
18
38
|
};
|
|
19
39
|
}
|
|
20
40
|
export function useLivenessPlugin() {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["useMemo","VisionCameraProxy","createPlugin","plugin","initFrameProcessorPlugin","Error","detectLiveness","frame","result","call","useLivenessPlugin"],"sourceRoot":"../../src","sources":["LivenessDetector.ts"],"mappings":";;AAAA,SAASA,OAAO,QAAQ,OAAO;AAC/B,SAASC,iBAAiB,QAAoB,4BAA4B;
|
|
1
|
+
{"version":3,"names":["useMemo","VisionCameraProxy","_worklet_4012480599600_init_data","code","location","sourceMap","createPlugin","plugin","initFrameProcessorPlugin","Error","detectLiveness","LivenessDetectorTs1Factory","_e","global","LivenessDetectorTs1","frame","result","call","__closure","__workletHash","__pluginVersion","__initData","__stackDetails","useLivenessPlugin"],"sourceRoot":"../../src","sources":["LivenessDetector.ts"],"mappings":";;AAAA,SAASA,OAAO,QAAQ,OAAO;AAC/B,SAASC,iBAAiB,QAAoB,4BAA4B;AAAC,MAAAC,gCAAA;EAAAC,IAAA;EAAAC,QAAA;EAAAC,SAAA;AAAA;AAO3E,SAASC,YAAYA,CAAA,EAAmB;EACtC,MAAMC,MAAM,GAAGN,iBAAiB,CAACO,wBAAwB,CACvD,gBAAgB,EAChB,CAAC,CACH,CAAC;EAED,IAAI,CAACD,MAAM,EAAE;IACX,MAAM,IAAIE,KAAK,CACb,sEAAsE,GACpE,kDACJ,CAAC;EACH;EAEA,OAAO;IACLC,cAAc,EAAE,SAAAC,2BAAA;MAAAT,gCAAA;MAECK;IAAM;MAAA,MAAAK,EAAA,QAAAC,MAAA,CAAAJ,KAAA;MAAA,MAAAK,mBAAA,YAAAA,CAFNC,KAAY,EAAsB;QAEjD,MAAMC,MAAM,GAAGT,MAAM,CAACU,IAAI,CAACF,KAAK,CAAC;QACjC;QACA,OAAOC,MAAM;MACf,CAAC;MAAAF,mBAAA,CAAAI,SAAA;QAHgBX;MAAM;MAAAO,mBAAA,CAAAK,aAAA;MAAAL,mBAAA,CAAAM,eAAA;MAAAN,mBAAA,CAAAO,UAAA,GAAAnB,gCAAA;MAAAY,mBAAA,CAAAQ,cAAA,GAAAV,EAAA;MAAA,OAAAE,mBAAA;IAAA,CAFP;MAAAZ,gCAAA;MAECK;IAAM;EAIzB,CAAC;AACH;AAEA,OAAO,SAASgB,iBAAiBA,CAAA,EAAmB;EAClD,OAAOvB,OAAO,CAAC,MAAMM,YAAY,CAAC,CAAC,EAAE,EAAE,CAAC;AAC1C","ignoreList":[]}
|
|
@@ -9,6 +9,16 @@ const WINDOW_SIZE = 20;
|
|
|
9
9
|
// How many frames to decay consecutiveGood by on a bad frame.
|
|
10
10
|
// Decay (not hard reset) means one noisy frame won't erase all progress.
|
|
11
11
|
const CONSECUTIVE_DECAY = 2;
|
|
12
|
+
const _worklet_11184642299290_init_data = {
|
|
13
|
+
code: "function useLivenessCameraTs1(){const{plugin,frame,handleFaceDataJS}=this.__closure;const face=plugin.detectLiveness(frame);handleFaceDataJS(face,frame.width);}",
|
|
14
|
+
location: "/home/runner/work/react-native-liveness/react-native-liveness/src/useLivenessCamera.ts",
|
|
15
|
+
sourceMap: "{\"version\":3,\"names\":[\"useLivenessCameraTs1\",\"plugin\",\"frame\",\"handleFaceDataJS\",\"__closure\",\"face\",\"detectLiveness\",\"width\"],\"sources\":[\"/home/runner/work/react-native-liveness/react-native-liveness/src/useLivenessCamera.ts\"],\"mappings\":\"AAuNyB,SAAAA,oBAAMA,CAAA,QAAAC,MAAA,CAAAC,KAAA,CAAAC,gBAAA,OAAAC,SAAA,CAEvB,KAAM,CAAAC,IAAI,CAAGJ,MAAM,CAACK,cAAc,CAACJ,KAAK,CAAC,CACzCC,gBAAgB,CAACE,IAAI,CAAEH,KAAK,CAACK,KAAK,CAAC,CACrC\",\"ignoreList\":[]}"
|
|
16
|
+
};
|
|
17
|
+
const _worklet_14471027507603_init_data = {
|
|
18
|
+
code: "function useLivenessCameraTs2(frame){const{runAtTargetFps,_worklet_11184642299290_init_data,plugin,handleFaceDataJS}=this.__closure;runAtTargetFps(20,function useLivenessCameraTs1Factory({_worklet_11184642299290_init_data:_worklet_11184642299290_init_data,plugin:plugin,frame:frame,handleFaceDataJS:handleFaceDataJS}){const _e=[new global.Error(),-4,-27];const useLivenessCameraTs1=function(){const face=plugin.detectLiveness(frame);handleFaceDataJS(face,frame.width);};useLivenessCameraTs1.__closure={plugin:plugin,frame:frame,handleFaceDataJS:handleFaceDataJS};useLivenessCameraTs1.__workletHash=11184642299290;useLivenessCameraTs1.__pluginVersion=\"0.8.3\";useLivenessCameraTs1.__initData=_worklet_11184642299290_init_data;useLivenessCameraTs1.__stackDetails=_e;return useLivenessCameraTs1;}({_worklet_11184642299290_init_data:_worklet_11184642299290_init_data,plugin:plugin,frame:frame,handleFaceDataJS:handleFaceDataJS}));}",
|
|
19
|
+
location: "/home/runner/work/react-native-liveness/react-native-liveness/src/useLivenessCamera.ts",
|
|
20
|
+
sourceMap: "{\"version\":3,\"names\":[\"useLivenessCameraTs2\",\"frame\",\"runAtTargetFps\",\"_worklet_11184642299290_init_data\",\"plugin\",\"handleFaceDataJS\",\"__closure\",\"useLivenessCameraTs1Factory\",\"_e\",\"global\",\"Error\",\"useLivenessCameraTs1\",\"face\",\"detectLiveness\",\"width\",\"__workletHash\",\"__pluginVersion\",\"__initData\",\"__stackDetails\"],\"sources\":[\"/home/runner/work/react-native-liveness/react-native-liveness/src/useLivenessCamera.ts\"],\"mappings\":\"AAmNI,QAAC,CAAAA,oBAAiBA,CAAAC,KAAA,QAAAC,cAAA,CAAAC,iCAAA,CAAAC,MAAA,CAAAC,gBAAA,OAAAC,SAAA,CAIhBJ,cAAc,CAAC,EAAE,CAAE,SAAAK,4BAAA,CAAAJ,iCAAA,CAAAA,iCAAA,CAEJC,MAAM,CAANA,MAAM,CAAgBH,KAAK,CAALA,KAAK,CACxCI,gBAAA,CAAAA,gBAAgB,SAAAG,EAAA,MAAAC,MAAA,CAAAC,KAAA,iBAAAC,oBAAA,SAAAA,CAAA,CAHO,CAEvB,KAAM,CAAAC,IAAI,CAAGR,MAAM,CAACS,cAAc,CAACZ,KAAK,CAAC,CACzCI,gBAAgB,CAACO,IAAI,CAAEX,KAAK,CAACa,KAAK,CAAC,CACrC,CAAC,CAAAH,oBAAA,CAAAL,SAAA,EAFcF,MAAM,CAANA,MAAM,CAAgBH,KAAK,CAALA,KAAK,CACxCI,gBAAA,CAAAA,gBAAgB,EAAAM,oBAAA,CAAAI,aAAA,gBAAAJ,oBAAA,CAAAK,eAAA,SAAAL,oBAAA,CAAAM,UAAA,CAAAd,iCAAA,CAAAQ,oBAAA,CAAAO,cAAA,CAAAV,EAAA,QAAAG,oBAAA,EAHC,EAAAR,iCAAA,CAAAA,iCAAA,CAEJC,MAAM,CAANA,MAAM,CAAgBH,KAAK,CAALA,KAAK,CACxCI,gBAAA,CAAAA,gBAAgB,EACjB,CAAC,CACJ\",\"ignoreList\":[]}"
|
|
21
|
+
};
|
|
12
22
|
export function useLivenessCamera(options) {
|
|
13
23
|
const {
|
|
14
24
|
livenessThreshold,
|
|
@@ -168,18 +178,63 @@ export function useLivenessCamera(options) {
|
|
|
168
178
|
// ─── Frame processor ──────────────────────────────────────────────────────
|
|
169
179
|
|
|
170
180
|
const handleFaceDataJS = useMemo(() => Worklets.createRunOnJS(handleFaceData), [handleFaceData]);
|
|
171
|
-
const frameProcessor = useFrameProcessor(
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
181
|
+
const frameProcessor = useFrameProcessor(function useLivenessCameraTs2Factory({
|
|
182
|
+
_worklet_14471027507603_init_data,
|
|
183
|
+
runAtTargetFps,
|
|
184
|
+
_worklet_11184642299290_init_data,
|
|
185
|
+
plugin,
|
|
186
|
+
handleFaceDataJS
|
|
187
|
+
}) {
|
|
188
|
+
const _e = [new global.Error(), -5, -27];
|
|
189
|
+
const useLivenessCameraTs2 = function (frame) {
|
|
190
|
+
// Camera preview renders at full fps (60). ML Kit only needs ~20fps —
|
|
191
|
+
// running it on every frame would block the render thread unnecessarily.
|
|
192
|
+
runAtTargetFps(20, function useLivenessCameraTs1Factory({
|
|
193
|
+
_worklet_11184642299290_init_data,
|
|
194
|
+
plugin,
|
|
195
|
+
frame,
|
|
196
|
+
handleFaceDataJS
|
|
197
|
+
}) {
|
|
198
|
+
const _e = [new global.Error(), -4, -27];
|
|
199
|
+
const useLivenessCameraTs1 = function () {
|
|
200
|
+
const face = plugin.detectLiveness(frame);
|
|
201
|
+
handleFaceDataJS(face, frame.width);
|
|
202
|
+
};
|
|
203
|
+
useLivenessCameraTs1.__closure = {
|
|
204
|
+
plugin,
|
|
205
|
+
frame,
|
|
206
|
+
handleFaceDataJS
|
|
207
|
+
};
|
|
208
|
+
useLivenessCameraTs1.__workletHash = 11184642299290;
|
|
209
|
+
useLivenessCameraTs1.__pluginVersion = "0.8.3";
|
|
210
|
+
useLivenessCameraTs1.__initData = _worklet_11184642299290_init_data;
|
|
211
|
+
useLivenessCameraTs1.__stackDetails = _e;
|
|
212
|
+
return useLivenessCameraTs1;
|
|
213
|
+
}({
|
|
214
|
+
_worklet_11184642299290_init_data,
|
|
215
|
+
plugin,
|
|
216
|
+
frame,
|
|
217
|
+
handleFaceDataJS
|
|
218
|
+
}));
|
|
219
|
+
};
|
|
220
|
+
useLivenessCameraTs2.__closure = {
|
|
221
|
+
runAtTargetFps,
|
|
222
|
+
_worklet_11184642299290_init_data,
|
|
223
|
+
plugin,
|
|
224
|
+
handleFaceDataJS
|
|
225
|
+
};
|
|
226
|
+
useLivenessCameraTs2.__workletHash = 14471027507603;
|
|
227
|
+
useLivenessCameraTs2.__pluginVersion = "0.8.3";
|
|
228
|
+
useLivenessCameraTs2.__initData = _worklet_14471027507603_init_data;
|
|
229
|
+
useLivenessCameraTs2.__stackDetails = _e;
|
|
230
|
+
return useLivenessCameraTs2;
|
|
231
|
+
}({
|
|
232
|
+
_worklet_14471027507603_init_data,
|
|
233
|
+
runAtTargetFps,
|
|
234
|
+
_worklet_11184642299290_init_data,
|
|
235
|
+
plugin,
|
|
236
|
+
handleFaceDataJS
|
|
237
|
+
}), [plugin, handleFaceDataJS]);
|
|
183
238
|
useEffect(() => {
|
|
184
239
|
return () => {
|
|
185
240
|
frameScores.current = [];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["useCallback","useEffect","useMemo","useRef","useState","runAtTargetFps","useFrameProcessor","Worklets","useLivenessPlugin","getFeedback","rollingAverage","scoreFrame","WINDOW_SIZE","CONSECUTIVE_DECAY","useLivenessCamera","options","livenessThreshold","confirmFrames","countdownFrom","soundEnabled","cameraRef","onCapture","onLivenessConfirmed","onError","plugin","frameScores","consecutiveGood","frameWidth","stateRef","isCaptured","FEEDBACK_DEBOUNCE_MS","feedbackTimer","pendingFeedback","state","setState","livenessState","livenessScore","countdown","feedback","setLivenessState","next","current","prev","capture","photo","takePhoto","flash","enableShutterSound","score","timestamp","Date","now","err","Error","String","startCountdown","tick","interval","setInterval","clearInterval","handleFaceData","face","width","safeFace","detected","bounds","x","y","height","yawAngle","pitchAngle","rollAngle","leftEyeOpenProbability","rightEyeOpenProbability","smilingProbability","total","push","length","shift","avgScore","Math","max","isLive","newFeedback","clearTimeout","setTimeout","handleFaceDataJS","createRunOnJS","frameProcessor","frame","detectLiveness"],"sourceRoot":"../../src","sources":["useLivenessCamera.ts"],"mappings":";;AAAA,SAASA,WAAW,EAAEC,SAAS,EAAEC,OAAO,EAAEC,MAAM,EAAEC,QAAQ,QAAQ,OAAO;AAEzE,SAASC,cAAc,EAAEC,iBAAiB,QAAQ,4BAA4B;AAC9E,SAASC,QAAQ,QAAQ,4BAA4B;AACrD,SAASC,iBAAiB,QAAQ,uBAAoB;AACtD,SAASC,WAAW,EAAEC,cAAc,EAAEC,UAAU,QAAQ,sBAAmB;AAQ3E,MAAMC,WAAW,GAAG,EAAE;AACtB;AACA;AACA,MAAMC,iBAAiB,GAAG,CAAC;
|
|
1
|
+
{"version":3,"names":["useCallback","useEffect","useMemo","useRef","useState","runAtTargetFps","useFrameProcessor","Worklets","useLivenessPlugin","getFeedback","rollingAverage","scoreFrame","WINDOW_SIZE","CONSECUTIVE_DECAY","_worklet_11184642299290_init_data","code","location","sourceMap","_worklet_14471027507603_init_data","useLivenessCamera","options","livenessThreshold","confirmFrames","countdownFrom","soundEnabled","cameraRef","onCapture","onLivenessConfirmed","onError","plugin","frameScores","consecutiveGood","frameWidth","stateRef","isCaptured","FEEDBACK_DEBOUNCE_MS","feedbackTimer","pendingFeedback","state","setState","livenessState","livenessScore","countdown","feedback","setLivenessState","next","current","prev","capture","photo","takePhoto","flash","enableShutterSound","score","timestamp","Date","now","err","Error","String","startCountdown","tick","interval","setInterval","clearInterval","handleFaceData","face","width","safeFace","detected","bounds","x","y","height","yawAngle","pitchAngle","rollAngle","leftEyeOpenProbability","rightEyeOpenProbability","smilingProbability","total","push","length","shift","avgScore","Math","max","isLive","newFeedback","clearTimeout","setTimeout","handleFaceDataJS","createRunOnJS","frameProcessor","useLivenessCameraTs2Factory","_e","global","useLivenessCameraTs2","frame","useLivenessCameraTs1Factory","useLivenessCameraTs1","detectLiveness","__closure","__workletHash","__pluginVersion","__initData","__stackDetails"],"sourceRoot":"../../src","sources":["useLivenessCamera.ts"],"mappings":"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","ignoreList":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LivenessCamera.d.ts","sourceRoot":"","sources":["../../../src/LivenessCamera.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"LivenessCamera.d.ts","sourceRoot":"","sources":["../../../src/LivenessCamera.tsx"],"names":[],"mappings":"AA6BA,OAAO,KAAK,EAAE,mBAAmB,EAAiB,MAAM,SAAS,CAAC;AA8SlE,wBAAgB,cAAc,CAAC,EAC7B,SAAS,EACT,mBAAmB,EACnB,OAAO,EACP,aAAiB,EACjB,iBAAwB,EACxB,aAAkB,EAClB,YAAmB,EACnB,UAAyB,EACzB,KAAK,GACN,EAAE,mBAAmB,2CA+FrB"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rick427/react-native-liveness",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.2",
|
|
4
4
|
"description": "Liveness detection library for React Native using Vision Camera v4 and ML Kit",
|
|
5
5
|
"main": "./lib/module/index.js",
|
|
6
6
|
"types": "./lib/typescript/src/index.d.ts",
|
|
@@ -75,8 +75,10 @@
|
|
|
75
75
|
"react": "19.2.0",
|
|
76
76
|
"react-native": "0.83.6",
|
|
77
77
|
"react-native-builder-bob": "^0.41.0",
|
|
78
|
+
"react-native-reanimated": "^4.3.0",
|
|
78
79
|
"react-native-svg": "^15.0.0",
|
|
79
80
|
"react-native-vision-camera": "^4.0.0",
|
|
81
|
+
"react-native-worklets": "0.8.x",
|
|
80
82
|
"react-native-worklets-core": "^1.3.3",
|
|
81
83
|
"turbo": "^2.8.21",
|
|
82
84
|
"typescript": "^6.0.2"
|
|
@@ -84,6 +86,7 @@
|
|
|
84
86
|
"peerDependencies": {
|
|
85
87
|
"react": "*",
|
|
86
88
|
"react-native": "*",
|
|
89
|
+
"react-native-reanimated": ">=4.0.0",
|
|
87
90
|
"react-native-svg": ">=13.0.0",
|
|
88
91
|
"react-native-vision-camera": ">=4.0.0",
|
|
89
92
|
"react-native-worklets-core": ">=1.0.0"
|
|
@@ -99,7 +102,8 @@
|
|
|
99
102
|
[
|
|
100
103
|
"module",
|
|
101
104
|
{
|
|
102
|
-
"esm": true
|
|
105
|
+
"esm": true,
|
|
106
|
+
"configFile": true
|
|
103
107
|
}
|
|
104
108
|
],
|
|
105
109
|
[
|
package/src/LivenessCamera.tsx
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
import { useCallback, useEffect, useRef, useState } from 'react';
|
|
2
|
-
import { Animated
|
|
2
|
+
import { Animated as RNAnimated, StyleSheet, Text, View } from 'react-native';
|
|
3
|
+
import Animated, {
|
|
4
|
+
cancelAnimation,
|
|
5
|
+
Easing,
|
|
6
|
+
useAnimatedProps,
|
|
7
|
+
useSharedValue,
|
|
8
|
+
withRepeat,
|
|
9
|
+
withSequence,
|
|
10
|
+
withTiming,
|
|
11
|
+
} from 'react-native-reanimated';
|
|
3
12
|
import {
|
|
4
13
|
Camera,
|
|
5
14
|
useCameraDevice,
|
|
@@ -20,8 +29,9 @@ import {
|
|
|
20
29
|
import { useLivenessCamera } from './useLivenessCamera';
|
|
21
30
|
import type { LivenessCameraProps, LivenessState } from './types';
|
|
22
31
|
|
|
23
|
-
// ─── Animated SVG components
|
|
24
|
-
//
|
|
32
|
+
// ─── Animated SVG components (Reanimated) ────────────────────────────────────
|
|
33
|
+
// createAnimatedComponent from react-native-reanimated properly drives SVG
|
|
34
|
+
// presentation attributes (strokeDashoffset, y, rotation) on the UI thread.
|
|
25
35
|
const AnimatedCircle = Animated.createAnimatedComponent(Circle);
|
|
26
36
|
const AnimatedG = Animated.createAnimatedComponent(G);
|
|
27
37
|
const AnimatedRect = Animated.createAnimatedComponent(Rect);
|
|
@@ -31,7 +41,7 @@ const DEFAULT_FONT = 'Baloo-Medium';
|
|
|
31
41
|
const CIRCLE_DIAMETER_RATIO = 0.82;
|
|
32
42
|
const STROKE_WIDTH = 3;
|
|
33
43
|
const K = 0.5523; // cubic bezier ellipse approximation
|
|
34
|
-
const SCAN_LINE_HEIGHT =
|
|
44
|
+
const SCAN_LINE_HEIGHT = 2; // px — thin line, like a real liveness SDK
|
|
35
45
|
const BRACKET_SPAN_DEG = 44; // degrees each corner bracket spans
|
|
36
46
|
const BRACKET_STROKE = STROKE_WIDTH + 1;
|
|
37
47
|
|
|
@@ -101,108 +111,94 @@ function CircleOverlay({
|
|
|
101
111
|
score: number;
|
|
102
112
|
livenessThreshold: number;
|
|
103
113
|
}) {
|
|
104
|
-
// ──
|
|
105
|
-
|
|
106
|
-
const
|
|
107
|
-
const
|
|
108
|
-
|
|
114
|
+
// ── Shared values — all hooks before any early return ─────────────────────
|
|
115
|
+
// scanProgress 0=top 1=bottom, ping-pongs continuously
|
|
116
|
+
const scanProgress = useSharedValue(0);
|
|
117
|
+
const scanOpacity = useSharedValue(1);
|
|
118
|
+
// bracketRot drives the slow bracket rotation in degrees
|
|
119
|
+
const bracketRot = useSharedValue(0);
|
|
120
|
+
// livenessProgress tracks smoothed score for the arc
|
|
121
|
+
const livenessProgress = useSharedValue(0);
|
|
122
|
+
|
|
123
|
+
// ── Geometry — computed before useAnimatedProps (safe when 0) ─────────────
|
|
124
|
+
const cx = width / 2;
|
|
125
|
+
const cy = height * 0.42;
|
|
126
|
+
const r = (width * CIRCLE_DIAMETER_RATIO) / 2;
|
|
127
|
+
const circumference = 2 * Math.PI * r;
|
|
128
|
+
const color = getCircleColor(state, score);
|
|
129
|
+
|
|
130
|
+
// ── Animated props — UI-thread worklets, deps rebuilt when geometry changes
|
|
131
|
+
const scanAnimProps = useAnimatedProps(
|
|
132
|
+
() => ({
|
|
133
|
+
// Map 0→1 progress onto the pixel range inside the circle
|
|
134
|
+
y: cy - r + 2 + scanProgress.value * (2 * r - SCAN_LINE_HEIGHT - 4),
|
|
135
|
+
opacity: scanOpacity.value,
|
|
136
|
+
}),
|
|
137
|
+
[cy, r]
|
|
138
|
+
);
|
|
139
|
+
|
|
140
|
+
const bracketAnimProps = useAnimatedProps(
|
|
141
|
+
() => ({
|
|
142
|
+
// react-native-svg accepts numeric rotation + origin instead of a string
|
|
143
|
+
rotation: bracketRot.value % 360,
|
|
144
|
+
originX: cx,
|
|
145
|
+
originY: cy,
|
|
146
|
+
}),
|
|
147
|
+
[cx, cy]
|
|
148
|
+
);
|
|
109
149
|
|
|
110
|
-
const
|
|
111
|
-
|
|
150
|
+
const progressAnimProps = useAnimatedProps(
|
|
151
|
+
() => ({
|
|
152
|
+
strokeDashoffset:
|
|
153
|
+
circumference -
|
|
154
|
+
(livenessProgress.value / livenessThreshold) * circumference,
|
|
155
|
+
}),
|
|
156
|
+
[circumference, livenessThreshold]
|
|
157
|
+
);
|
|
112
158
|
|
|
113
159
|
// ── Start scan line + bracket rotation on mount ───────────────────────────
|
|
114
160
|
useEffect(() => {
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
useNativeDriver: false,
|
|
123
|
-
}),
|
|
124
|
-
Animated.timing(scanAnim, {
|
|
125
|
-
toValue: 0,
|
|
126
|
-
duration: 1800,
|
|
127
|
-
easing: Easing.linear,
|
|
128
|
-
useNativeDriver: false,
|
|
129
|
-
}),
|
|
130
|
-
])
|
|
161
|
+
scanProgress.value = withRepeat(
|
|
162
|
+
withSequence(
|
|
163
|
+
withTiming(1, { duration: 2400, easing: Easing.linear }),
|
|
164
|
+
withTiming(0, { duration: 2400, easing: Easing.linear })
|
|
165
|
+
),
|
|
166
|
+
-1,
|
|
167
|
+
false
|
|
131
168
|
);
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
Animated.timing(bracketAnim, {
|
|
137
|
-
toValue: 360,
|
|
138
|
-
duration: 6000,
|
|
139
|
-
easing: Easing.linear,
|
|
140
|
-
useNativeDriver: false,
|
|
141
|
-
})
|
|
169
|
+
bracketRot.value = withRepeat(
|
|
170
|
+
withTiming(360, { duration: 6000, easing: Easing.linear }),
|
|
171
|
+
-1,
|
|
172
|
+
false
|
|
142
173
|
);
|
|
143
|
-
bracketLoopRef.current.start();
|
|
144
|
-
|
|
145
174
|
return () => {
|
|
146
|
-
|
|
147
|
-
|
|
175
|
+
cancelAnimation(scanProgress);
|
|
176
|
+
cancelAnimation(bracketRot);
|
|
148
177
|
};
|
|
149
178
|
}, []); // eslint-disable-line react-hooks/exhaustive-deps
|
|
150
179
|
|
|
151
|
-
// ── On confirmed:
|
|
180
|
+
// ── On liveness confirmed: freeze brackets, fade scan line out ────────────
|
|
152
181
|
useEffect(() => {
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
Animated.timing(scanOpacity, {
|
|
158
|
-
toValue: 0,
|
|
159
|
-
duration: 350,
|
|
160
|
-
useNativeDriver: false,
|
|
161
|
-
}).start();
|
|
182
|
+
if (state !== 'scanning') {
|
|
183
|
+
cancelAnimation(scanProgress);
|
|
184
|
+
cancelAnimation(bracketRot);
|
|
185
|
+
scanOpacity.value = withTiming(0, { duration: 350 });
|
|
162
186
|
}
|
|
163
|
-
}, [state
|
|
187
|
+
}, [state]); // eslint-disable-line react-hooks/exhaustive-deps
|
|
164
188
|
|
|
165
189
|
// ── Drive progress arc from live score ────────────────────────────────────
|
|
166
190
|
useEffect(() => {
|
|
167
|
-
|
|
168
|
-
toValue: Math.min(score, livenessThreshold),
|
|
191
|
+
livenessProgress.value = withTiming(Math.min(score, livenessThreshold), {
|
|
169
192
|
duration: 180,
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
}, [score, livenessThreshold, progressAnim]);
|
|
193
|
+
});
|
|
194
|
+
}, [score, livenessThreshold]); // eslint-disable-line react-hooks/exhaustive-deps
|
|
173
195
|
|
|
174
196
|
// ── Guard — render nothing until dimensions are known ─────────────────────
|
|
175
197
|
if (width === 0 || height === 0) return null;
|
|
176
198
|
|
|
177
|
-
//
|
|
178
|
-
const cx = width / 2;
|
|
179
|
-
const cy = height * 0.42;
|
|
180
|
-
const r = (width * CIRCLE_DIAMETER_RATIO) / 2;
|
|
181
|
-
const circumference = 2 * Math.PI * r;
|
|
182
|
-
const color = getCircleColor(state, score);
|
|
183
|
-
|
|
184
|
-
// Scrim: full-screen dark rect with transparent circle hole
|
|
199
|
+
// Scrim: full-screen rect with transparent circle cutout (evenodd rule)
|
|
185
200
|
const scrimD = `M0 0H${width}V${height}H0Z ${circlePath(cx, cy, r)}`;
|
|
186
201
|
|
|
187
|
-
// Scan line Y: sweeps from just inside top to just inside bottom of circle
|
|
188
|
-
const scanLineY = scanAnim.interpolate({
|
|
189
|
-
inputRange: [0, 1],
|
|
190
|
-
outputRange: [cy - r + 2, cy + r - SCAN_LINE_HEIGHT - 2],
|
|
191
|
-
});
|
|
192
|
-
|
|
193
|
-
// Progress arc: strokeDashoffset goes from full (no arc) → 0 (full arc)
|
|
194
|
-
const strokeDashoffset = progressAnim.interpolate({
|
|
195
|
-
inputRange: [0, livenessThreshold],
|
|
196
|
-
outputRange: [circumference, 0],
|
|
197
|
-
extrapolate: 'clamp',
|
|
198
|
-
});
|
|
199
|
-
|
|
200
|
-
// Bracket group rotation — centred on the circle
|
|
201
|
-
const bracketTransform = bracketAnim.interpolate({
|
|
202
|
-
inputRange: [0, 360],
|
|
203
|
-
outputRange: [`rotate(0, ${cx}, ${cy})`, `rotate(360, ${cx}, ${cy})`],
|
|
204
|
-
});
|
|
205
|
-
|
|
206
202
|
// 4 corner brackets at NE / SE / SW / NW diagonal positions
|
|
207
203
|
const bracketD = [45, 135, 225, 315]
|
|
208
204
|
.map((deg) => bracketArcPath(cx, cy, r, deg, BRACKET_SPAN_DEG))
|
|
@@ -217,11 +213,11 @@ function CircleOverlay({
|
|
|
217
213
|
<Circle cx={cx} cy={cy} r={r} />
|
|
218
214
|
</ClipPath>
|
|
219
215
|
|
|
220
|
-
{/*
|
|
221
|
-
<LinearGradient id="scan-gradient" x1="0" y1="0" x2="
|
|
216
|
+
{/* Horizontal gradient — line fades in from left, out to right */}
|
|
217
|
+
<LinearGradient id="scan-gradient" x1="0" y1="0" x2="1" y2="0">
|
|
222
218
|
<Stop offset="0" stopColor="#fff" stopOpacity="0" />
|
|
223
|
-
<Stop offset="0.
|
|
224
|
-
<Stop offset="0.
|
|
219
|
+
<Stop offset="0.08" stopColor="#fff" stopOpacity="0.55" />
|
|
220
|
+
<Stop offset="0.92" stopColor="#fff" stopOpacity="0.55" />
|
|
225
221
|
<Stop offset="1" stopColor="#fff" stopOpacity="0" />
|
|
226
222
|
</LinearGradient>
|
|
227
223
|
</Defs>
|
|
@@ -243,16 +239,15 @@ function CircleOverlay({
|
|
|
243
239
|
<G clipPath="url(#liveness-circle-clip)">
|
|
244
240
|
<AnimatedRect
|
|
245
241
|
x={cx - r}
|
|
246
|
-
y={scanLineY}
|
|
247
242
|
width={r * 2}
|
|
248
243
|
height={SCAN_LINE_HEIGHT}
|
|
249
244
|
fill="url(#scan-gradient)"
|
|
250
|
-
|
|
245
|
+
animatedProps={scanAnimProps}
|
|
251
246
|
/>
|
|
252
247
|
</G>
|
|
253
248
|
|
|
254
249
|
{/* ── Rotating corner brackets ─────────────────────────────────────── */}
|
|
255
|
-
<AnimatedG
|
|
250
|
+
<AnimatedG animatedProps={bracketAnimProps}>
|
|
256
251
|
<Path
|
|
257
252
|
d={bracketD}
|
|
258
253
|
fill="none"
|
|
@@ -264,7 +259,7 @@ function CircleOverlay({
|
|
|
264
259
|
</AnimatedG>
|
|
265
260
|
|
|
266
261
|
{/* ── Progress arc — draws in as liveness confidence builds ────────── */}
|
|
267
|
-
{/*
|
|
262
|
+
{/* transform rotates -90° so arc starts at 12 o'clock, goes clockwise */}
|
|
268
263
|
<AnimatedCircle
|
|
269
264
|
cx={cx}
|
|
270
265
|
cy={cy}
|
|
@@ -273,9 +268,9 @@ function CircleOverlay({
|
|
|
273
268
|
stroke={color}
|
|
274
269
|
strokeWidth={STROKE_WIDTH}
|
|
275
270
|
strokeDasharray={circumference}
|
|
276
|
-
strokeDashoffset={strokeDashoffset}
|
|
277
271
|
strokeLinecap="round"
|
|
278
272
|
transform={`rotate(-90, ${cx}, ${cy})`}
|
|
273
|
+
animatedProps={progressAnimProps}
|
|
279
274
|
/>
|
|
280
275
|
</Svg>
|
|
281
276
|
);
|
|
@@ -289,26 +284,26 @@ function CountdownBubble({
|
|
|
289
284
|
value: number;
|
|
290
285
|
fontFamily: string;
|
|
291
286
|
}) {
|
|
292
|
-
const scale = useRef(new
|
|
293
|
-
const opacity = useRef(new
|
|
287
|
+
const scale = useRef(new RNAnimated.Value(0)).current;
|
|
288
|
+
const opacity = useRef(new RNAnimated.Value(0)).current;
|
|
294
289
|
|
|
295
290
|
useEffect(() => {
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
291
|
+
RNAnimated.parallel([
|
|
292
|
+
RNAnimated.sequence([
|
|
293
|
+
RNAnimated.spring(scale, {
|
|
299
294
|
toValue: 1.2,
|
|
300
295
|
stiffness: 200,
|
|
301
296
|
damping: 6,
|
|
302
297
|
useNativeDriver: true,
|
|
303
298
|
}),
|
|
304
|
-
|
|
299
|
+
RNAnimated.spring(scale, {
|
|
305
300
|
toValue: 1.0,
|
|
306
301
|
stiffness: 150,
|
|
307
302
|
damping: 8,
|
|
308
303
|
useNativeDriver: true,
|
|
309
304
|
}),
|
|
310
305
|
]),
|
|
311
|
-
|
|
306
|
+
RNAnimated.timing(opacity, {
|
|
312
307
|
toValue: 1,
|
|
313
308
|
duration: 150,
|
|
314
309
|
useNativeDriver: true,
|
|
@@ -316,7 +311,7 @@ function CountdownBubble({
|
|
|
316
311
|
]).start();
|
|
317
312
|
|
|
318
313
|
return () => {
|
|
319
|
-
|
|
314
|
+
RNAnimated.timing(opacity, {
|
|
320
315
|
toValue: 0,
|
|
321
316
|
duration: 200,
|
|
322
317
|
useNativeDriver: true,
|
|
@@ -325,11 +320,11 @@ function CountdownBubble({
|
|
|
325
320
|
}, []); // eslint-disable-line react-hooks/exhaustive-deps
|
|
326
321
|
|
|
327
322
|
return (
|
|
328
|
-
<
|
|
323
|
+
<RNAnimated.View
|
|
329
324
|
style={[styles.countdownBubble, { opacity, transform: [{ scale }] }]}
|
|
330
325
|
>
|
|
331
326
|
<Text style={[styles.countdownText, { fontFamily }]}>{value}</Text>
|
|
332
|
-
</
|
|
327
|
+
</RNAnimated.View>
|
|
333
328
|
);
|
|
334
329
|
}
|
|
335
330
|
|