@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 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
- - Face guide oval with live feedback hints
20
- - Animated countdown (React Native built-in `Animated`)
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
- - Optional shutter sound
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` depending on which package you have installed:
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: ['module:@react-native/babel-preset'], // or 'babel-preset-expo'
60
+ presets: [
61
+ 'module:@react-native/babel-preset', // or 'babel-preset-expo'
62
+ ],
57
63
  plugins: [
58
- ['react-native-worklets-core/plugin'], // if using react-native-worklets-core
59
- // ['react-native-worklets/plugin'], // if using react-native-worklets
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 worklets configured?** Just confirm the relevant plugin line is present no further changes needed.
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 the Babel config, clear the Metro cache:
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
- The ML Kit dependency is included in `build.gradle` automatically. No extra steps needed.
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
- ### Drop-in component
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 { LivenessCamera } from '@rick427/react-native-liveness';
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
- ### Props
186
+ #### `LivenessCamera` props
119
187
 
120
188
  | Prop | Type | Default | Description |
121
189
  |---|---|---|---|
122
- | `onCapture` | `(result: CaptureResult) => void` | **required** | Fired after photo is taken. |
123
- | `onLivenessConfirmed` | `() => void` | — | Fired the moment liveness is confirmed, before the countdown. |
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 per frame to be considered live. |
127
- | `confirmFrames` | `number` | `15` | Consecutive high-score frames required (~500 ms at 30 fps). |
128
- | `soundEnabled` | `boolean` | `true` | Play the native system shutter sound on capture. Respects silent mode. |
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
- ### CaptureResult
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 20%–65% of the frame (not too far, not too close) |
151
- | Head pose | 30% | Yaw < ±20° and pitch < ±20° from frontal |
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 frame (30fps)
245
+ Camera (60 fps preview)
162
246
  ↓ [worklet thread — Vision Camera frame processor]
163
- Native plugin (Swift / Kotlin)
164
- → ML Kit Face Detection
165
- → { bounds, yawAngle, pitchAngle, leftEyeOpenProbability, … }
166
- ↓ [runOnJS → JS thread]
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() per frame
252
+ → scoreFrame() soft-edge signals, weighted sum
169
253
  → rolling 20-frame window
170
- 15 consecutive frames > threshold liveness confirmed
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, Easing, StyleSheet, Text, View } from 'react-native';
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
- // Created once at module level so React never recreates the component class.
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 = 44; // px — height of the sweep bar
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
- // ── Animation values (must be declared before any early return) ────────────
72
- const scanAnim = useRef(new Animated.Value(0)).current;
73
- const scanOpacity = useRef(new Animated.Value(1)).current;
74
- const progressAnim = useRef(new Animated.Value(0)).current;
75
- const bracketAnim = useRef(new Animated.Value(0)).current;
76
- const scanLoopRef = useRef(null);
77
- const bracketLoopRef = useRef(null);
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
- // Scan line: ping-pong top → bottom → top, 1.8 s each leg
82
- scanLoopRef.current = Animated.loop(Animated.sequence([Animated.timing(scanAnim, {
83
- toValue: 1,
84
- duration: 1800,
85
- easing: Easing.linear,
86
- useNativeDriver: false
87
- }), Animated.timing(scanAnim, {
88
- toValue: 0,
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
- useNativeDriver: false
101
- }));
102
- bracketLoopRef.current.start();
206
+ easing: Easing.linear
207
+ }), -1, false);
103
208
  return () => {
104
- scanLoopRef.current?.stop();
105
- bracketLoopRef.current?.stop();
209
+ cancelAnimation(scanProgress);
210
+ cancelAnimation(bracketRot);
106
211
  };
107
212
  }, []); // eslint-disable-line react-hooks/exhaustive-deps
108
213
 
109
- // ── On confirmed: stop scan + brackets, fade out scan line ────────────────
214
+ // ── On liveness confirmed: freeze brackets, fade scan line out ────────────
110
215
  useEffect(() => {
111
- const isActive = state === 'scanning';
112
- if (!isActive) {
113
- scanLoopRef.current?.stop();
114
- bracketLoopRef.current?.stop();
115
- Animated.timing(scanOpacity, {
116
- toValue: 0,
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, scanOpacity]);
223
+ }, [state]); // eslint-disable-line react-hooks/exhaustive-deps
122
224
 
123
225
  // ── Drive progress arc from live score ────────────────────────────────────
124
226
  useEffect(() => {
125
- Animated.timing(progressAnim, {
126
- toValue: Math.min(score, livenessThreshold),
127
- duration: 180,
128
- useNativeDriver: false
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
- // ── Geometry ──────────────────────────────────────────────────────────────
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: "0",
183
- y2: "1",
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.25",
263
+ offset: "0.08",
190
264
  stopColor: "#fff",
191
- stopOpacity: "0.65"
265
+ stopOpacity: "0.55"
192
266
  }), /*#__PURE__*/_jsx(Stop, {
193
- offset: "0.75",
267
+ offset: "0.92",
194
268
  stopColor: "#fff",
195
- stopOpacity: "0.65"
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
- opacity: scanOpacity
294
+ animatedProps: scanAnimProps
222
295
  })
223
296
  }), /*#__PURE__*/_jsx(AnimatedG, {
224
- transform: bracketTransform,
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 Animated.Value(0)).current;
254
- const opacity = useRef(new Animated.Value(0)).current;
326
+ const scale = useRef(new RNAnimated.Value(0)).current;
327
+ const opacity = useRef(new RNAnimated.Value(0)).current;
255
328
  useEffect(() => {
256
- Animated.parallel([Animated.sequence([Animated.spring(scale, {
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
- }), Animated.spring(scale, {
334
+ }), RNAnimated.spring(scale, {
262
335
  toValue: 1.0,
263
336
  stiffness: 150,
264
337
  damping: 8,
265
338
  useNativeDriver: true
266
- })]), Animated.timing(opacity, {
339
+ })]), RNAnimated.timing(opacity, {
267
340
  toValue: 1,
268
341
  duration: 150,
269
342
  useNativeDriver: true
270
343
  })]).start();
271
344
  return () => {
272
- Animated.timing(opacity, {
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(Animated.View, {
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: frame => {
12
- 'worklet';
13
-
14
- const result = plugin.call(frame);
15
- // plugin.call returns a loosely-typed BasicParameterType — cast via unknown
16
- return result;
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;AAO1E,SAASC,YAAYA,CAAA,EAAmB;EACtC,MAAMC,MAAM,GAAGF,iBAAiB,CAACG,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,EAAGC,KAAY,IAAsB;MACjD,SAAS;;MACT,MAAMC,MAAM,GAAGL,MAAM,CAACM,IAAI,CAACF,KAAK,CAAC;MACjC;MACA,OAAOC,MAAM;IACf;EACF,CAAC;AACH;AAEA,OAAO,SAASE,iBAAiBA,CAAA,EAAmB;EAClD,OAAOV,OAAO,CAAC,MAAME,YAAY,CAAC,CAAC,EAAE,EAAE,CAAC;AAC1C","ignoreList":[]}
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(frame => {
172
- 'worklet';
173
-
174
- // Camera preview renders at full fps (60). ML Kit only needs ~20fps —
175
- // running it on every frame would block the render thread unnecessarily.
176
- runAtTargetFps(20, () => {
177
- 'worklet';
178
-
179
- const face = plugin.detectLiveness(frame);
180
- handleFaceDataJS(face, frame.width);
181
- });
182
- }, [plugin, handleFaceDataJS]);
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":"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","ignoreList":[]}
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":"AAoBA,OAAO,KAAK,EAAE,mBAAmB,EAAiB,MAAM,SAAS,CAAC;AA4TlE,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"}
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.0",
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
  [
@@ -1,5 +1,14 @@
1
1
  import { useCallback, useEffect, useRef, useState } from 'react';
2
- import { Animated, Easing, StyleSheet, Text, View } from 'react-native';
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
- // Created once at module level so React never recreates the component class.
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; // px — height of the sweep bar
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
- // ── Animation values (must be declared before any early return) ────────────
105
- const scanAnim = useRef(new Animated.Value(0)).current;
106
- const scanOpacity = useRef(new Animated.Value(1)).current;
107
- const progressAnim = useRef(new Animated.Value(0)).current;
108
- const bracketAnim = useRef(new Animated.Value(0)).current;
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 scanLoopRef = useRef<Animated.CompositeAnimation | null>(null);
111
- const bracketLoopRef = useRef<Animated.CompositeAnimation | null>(null);
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
- // Scan line: ping-pong top → bottom → top, 1.8 s each leg
116
- scanLoopRef.current = Animated.loop(
117
- Animated.sequence([
118
- Animated.timing(scanAnim, {
119
- toValue: 1,
120
- duration: 1800,
121
- easing: Easing.linear,
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
- scanLoopRef.current.start();
133
-
134
- // Brackets: one full rotation every 6 s — slow, atmospheric
135
- bracketLoopRef.current = Animated.loop(
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
- scanLoopRef.current?.stop();
147
- bracketLoopRef.current?.stop();
175
+ cancelAnimation(scanProgress);
176
+ cancelAnimation(bracketRot);
148
177
  };
149
178
  }, []); // eslint-disable-line react-hooks/exhaustive-deps
150
179
 
151
- // ── On confirmed: stop scan + brackets, fade out scan line ────────────────
180
+ // ── On liveness confirmed: freeze brackets, fade scan line out ────────────
152
181
  useEffect(() => {
153
- const isActive = state === 'scanning';
154
- if (!isActive) {
155
- scanLoopRef.current?.stop();
156
- bracketLoopRef.current?.stop();
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, scanOpacity]);
187
+ }, [state]); // eslint-disable-line react-hooks/exhaustive-deps
164
188
 
165
189
  // ── Drive progress arc from live score ────────────────────────────────────
166
190
  useEffect(() => {
167
- Animated.timing(progressAnim, {
168
- toValue: Math.min(score, livenessThreshold),
191
+ livenessProgress.value = withTiming(Math.min(score, livenessThreshold), {
169
192
  duration: 180,
170
- useNativeDriver: false,
171
- }).start();
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
- // ── Geometry ──────────────────────────────────────────────────────────────
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
- {/* Vertical gradient for the scan bar fades at top and bottom */}
221
- <LinearGradient id="scan-gradient" x1="0" y1="0" x2="0" y2="1">
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.25" stopColor="#fff" stopOpacity="0.65" />
224
- <Stop offset="0.75" stopColor="#fff" stopOpacity="0.65" />
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
- opacity={scanOpacity}
245
+ animatedProps={scanAnimProps}
251
246
  />
252
247
  </G>
253
248
 
254
249
  {/* ── Rotating corner brackets ─────────────────────────────────────── */}
255
- <AnimatedG transform={bracketTransform}>
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
- {/* Rotated -90° so it starts at 12 o'clock and goes clockwise */}
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 Animated.Value(0)).current;
293
- const opacity = useRef(new Animated.Value(0)).current;
287
+ const scale = useRef(new RNAnimated.Value(0)).current;
288
+ const opacity = useRef(new RNAnimated.Value(0)).current;
294
289
 
295
290
  useEffect(() => {
296
- Animated.parallel([
297
- Animated.sequence([
298
- Animated.spring(scale, {
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
- Animated.spring(scale, {
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
- Animated.timing(opacity, {
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
- Animated.timing(opacity, {
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
- <Animated.View
323
+ <RNAnimated.View
329
324
  style={[styles.countdownBubble, { opacity, transform: [{ scale }] }]}
330
325
  >
331
326
  <Text style={[styles.countdownText, { fontFamily }]}>{value}</Text>
332
- </Animated.View>
327
+ </RNAnimated.View>
333
328
  );
334
329
  }
335
330