@snap/react-camera-kit 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +327 -61
- package/dist/cjs/CameraKitProvider.d.ts.map +1 -1
- package/dist/cjs/CameraKitProvider.js +3 -0
- package/dist/cjs/CameraKitProvider.js.map +1 -1
- package/dist/cjs/index.d.ts +1 -0
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +3 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/useLensFrameMetrics.d.ts +31 -0
- package/dist/cjs/useLensFrameMetrics.d.ts.map +1 -0
- package/dist/cjs/useLensFrameMetrics.js +68 -0
- package/dist/cjs/useLensFrameMetrics.js.map +1 -0
- package/dist/cjs/version.d.ts +1 -1
- package/dist/cjs/version.js +1 -1
- package/dist/cjs/version.js.map +1 -1
- package/dist/esm/CameraKitProvider.d.ts.map +1 -1
- package/dist/esm/CameraKitProvider.js +3 -0
- package/dist/esm/CameraKitProvider.js.map +1 -1
- package/dist/esm/index.d.ts +1 -0
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +1 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/useLensFrameMetrics.d.ts +31 -0
- package/dist/esm/useLensFrameMetrics.d.ts.map +1 -0
- package/dist/esm/useLensFrameMetrics.js +65 -0
- package/dist/esm/useLensFrameMetrics.js.map +1 -0
- package/dist/esm/version.d.ts +1 -1
- package/dist/esm/version.js +1 -1
- package/dist/esm/version.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# @snap/react-camera-kit
|
|
2
2
|
|
|
3
|
-
React Camera Kit
|
|
3
|
+
The official React wrapper for the [Camera Kit Web SDK](https://developers.snap.com/camera-kit/integrate-sdk/web/web-configuration). It provides declarative components and hooks that handle SDK bootstrapping, session lifecycle, media sources, and Lens management — so you can integrate Snap AR into React apps with minimal boilerplate.
|
|
4
4
|
|
|
5
|
-
**[Live Demo](https://snapchat.github.io/react-camera-kit/)**
|
|
5
|
+
**[Live Demo](https://snapchat.github.io/react-camera-kit/)** · **[Camera Kit Docs](https://developers.snap.com/camera-kit/integrate-sdk/web/guides/react-camera-kit)**
|
|
6
6
|
|
|
7
7
|
## Installation
|
|
8
8
|
|
|
@@ -10,107 +10,373 @@ React Camera Kit for web applications.
|
|
|
10
10
|
npm install @snap/react-camera-kit @snap/camera-kit
|
|
11
11
|
```
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
### Requirements
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
- `@snap/camera-kit` `^1.13.0` (peer dependency)
|
|
16
|
+
- `react` `>=16.8.0` and `react-dom` `>=16.8.0`
|
|
17
|
+
- `rxjs` `>=7`
|
|
18
|
+
- `https://` for deployed apps (`http://localhost` works for local development)
|
|
16
19
|
|
|
17
|
-
-
|
|
18
|
-
- `lensId`
|
|
19
|
-
- `lensGroupId`
|
|
20
|
-
- `https://` for deployed apps (`http://localhost` should works for local dev)
|
|
20
|
+
You'll need a Camera Kit API token, Lens ID, and Lens Group ID from the [Snap Developer Portal](https://kit.snapchat.com/manage). See [Setting Up Accounts](https://developers.snap.com/camera-kit/getting-started/setting-up-accounts) if you're new to Camera Kit.
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
## Quick start
|
|
23
23
|
|
|
24
|
-
|
|
25
|
-
|
|
24
|
+
```tsx
|
|
25
|
+
import { CameraKitProvider, LensPlayer } from "@snap/react-camera-kit";
|
|
26
26
|
|
|
27
|
-
|
|
27
|
+
function App() {
|
|
28
|
+
return (
|
|
29
|
+
<CameraKitProvider apiToken="YOUR_API_TOKEN">
|
|
30
|
+
<LensPlayer lensId="YOUR_LENS_ID" lensGroupId="YOUR_LENS_GROUP_ID" />
|
|
31
|
+
</CameraKitProvider>
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
```
|
|
28
35
|
|
|
29
|
-
|
|
36
|
+
That's it — `CameraKitProvider` initializes the SDK, and `LensPlayer` sets up the camera, applies the Lens, and renders the output canvas.
|
|
30
37
|
|
|
31
|
-
##
|
|
38
|
+
## Components
|
|
32
39
|
|
|
33
|
-
|
|
40
|
+
### CameraKitProvider
|
|
34
41
|
|
|
35
|
-
The
|
|
42
|
+
The root provider that initializes the Camera Kit SDK. All other components and hooks must be descendants of this provider.
|
|
36
43
|
|
|
37
44
|
```tsx
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
45
|
+
import { CameraKitProvider, createConsoleLogger } from "@snap/react-camera-kit";
|
|
46
|
+
|
|
47
|
+
<CameraKitProvider apiToken="YOUR_API_TOKEN" logger={createConsoleLogger()} logLevel="info">
|
|
48
|
+
{children}
|
|
49
|
+
</CameraKitProvider>;
|
|
41
50
|
```
|
|
42
51
|
|
|
43
|
-
|
|
52
|
+
| Prop | Type | Default | Description |
|
|
53
|
+
| ----------------------------- | ---------------------------------------- | ------------ | ------------------------------------------------------------- |
|
|
54
|
+
| `apiToken` | `string` | **required** | Camera Kit API token |
|
|
55
|
+
| `logger` | `CameraKitLogger` | `noopLogger` | Logger instance — use `createConsoleLogger()` for development |
|
|
56
|
+
| `logLevel` | `"debug" \| "info" \| "warn" \| "error"` | `"info"` | Log verbosity |
|
|
57
|
+
| `renderWhileTabHidden` | `boolean` | `false` | Continue rendering when the browser tab is hidden |
|
|
58
|
+
| `stabilityKey` | `string \| number` | auto | Manual control over when the SDK re-initializes |
|
|
59
|
+
| `extendContainer` | `(container) => container` | — | Customize the SDK's DI container |
|
|
60
|
+
| `createBootstrapEventHandler` | `MetricEventHandlerFactory` | — | Factory for tracking bootstrap success/failure |
|
|
61
|
+
|
|
62
|
+
### LensPlayer
|
|
63
|
+
|
|
64
|
+
All-in-one component that handles source setup, Lens application, and playback. Defaults to the user's camera if no `source` is provided.
|
|
44
65
|
|
|
45
66
|
```tsx
|
|
46
|
-
<
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
67
|
+
<LensPlayer lensId="YOUR_LENS_ID" lensGroupId="YOUR_LENS_GROUP_ID" className="camera-canvas" />
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
| Prop | Type | Default | Description |
|
|
71
|
+
| ---------------- | ----------------------- | -------------------- | ------------------------------------------------------------------------------------------------ |
|
|
72
|
+
| `lensId` | `string` | — | Lens to apply |
|
|
73
|
+
| `lensGroupId` | `string` | — | Lens Group containing the Lens |
|
|
74
|
+
| `source` | `SourceInput` | `{ kind: "camera" }` | Media source (camera, video, or image) |
|
|
75
|
+
| `outputSize` | `OutputSize` | — | Rendering canvas size |
|
|
76
|
+
| `lensLaunchData` | `LensLaunchData` | — | Launch parameters passed to the Lens |
|
|
77
|
+
| `lensReadyGuard` | `() => Promise<void>` | — | Async guard called while Lens is loading (2s timeout) |
|
|
78
|
+
| `refreshTrigger` | `unknown` | — | When this value changes, the Lens is removed and reapplied |
|
|
79
|
+
| `canvasType` | `"live" \| "capture"` | `"live"` | Which canvas to render. For custom layouts, use `LiveCanvas`/`CaptureCanvas` as children instead |
|
|
80
|
+
| `fpsLimit` | `number` | — | Maximum rendering framerate |
|
|
81
|
+
| `muted` | `boolean` | `false` | Mute audio output |
|
|
82
|
+
| `screenRegions` | `ScreenRegions` | — | Screen regions for Lens-aware UI layout |
|
|
83
|
+
| `onError` | `(error, lens) => void` | — | Callback for playback errors |
|
|
84
|
+
| `className` | `string` | — | CSS class name |
|
|
85
|
+
| `style` | `CSSProperties` | — | Inline styles |
|
|
86
|
+
| `children` | `ReactNode` | — | Custom children (use with `LiveCanvas`/`CaptureCanvas`) |
|
|
87
|
+
|
|
88
|
+
### LiveCanvas / CaptureCanvas
|
|
89
|
+
|
|
90
|
+
Render the live preview or capture canvas as children of `LensPlayer`:
|
|
91
|
+
|
|
92
|
+
```tsx
|
|
93
|
+
<LensPlayer lensId="YOUR_LENS_ID" lensGroupId="YOUR_LENS_GROUP_ID">
|
|
94
|
+
<div>
|
|
95
|
+
<LiveCanvas style={{ width: "100%" }} />
|
|
96
|
+
</div>
|
|
97
|
+
<div>
|
|
98
|
+
<CaptureCanvas style={{ width: "100%" }} />
|
|
99
|
+
</div>
|
|
100
|
+
</LensPlayer>
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
Both accept `className` and `style` props.
|
|
104
|
+
|
|
105
|
+
## Hooks
|
|
106
|
+
|
|
107
|
+
### useCameraKit
|
|
108
|
+
|
|
109
|
+
Access the full Camera Kit context — SDK status, source/Lens state, and imperative methods. Must be called within a `CameraKitProvider`.
|
|
110
|
+
|
|
111
|
+
```tsx
|
|
112
|
+
import { useCameraKit } from "@snap/react-camera-kit";
|
|
113
|
+
|
|
114
|
+
function Controls() {
|
|
115
|
+
const { sdkStatus, lens, lenses, isMuted, toggleMuted, applyLens, removeLens, fetchLenses } = useCameraKit();
|
|
116
|
+
|
|
117
|
+
if (sdkStatus !== "ready") return <p>Loading SDK...</p>;
|
|
118
|
+
|
|
119
|
+
return (
|
|
51
120
|
<div>
|
|
52
|
-
<
|
|
121
|
+
<p>Lens: {lens.lensId ?? "None"}</p>
|
|
122
|
+
<button onClick={toggleMuted}>{isMuted ? "Unmute" : "Mute"}</button>
|
|
123
|
+
<button onClick={removeLens}>Remove Lens</button>
|
|
53
124
|
</div>
|
|
54
|
-
|
|
55
|
-
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
**State properties:**
|
|
130
|
+
|
|
131
|
+
| Property | Type | Description |
|
|
132
|
+
| --------------- | --------------------------------------------------------- | --------------------------------------- |
|
|
133
|
+
| `sdkStatus` | `"uninitialized" \| "initializing" \| "ready" \| "error"` | SDK initialization status |
|
|
134
|
+
| `sdkError` | `Error \| undefined` | Error from SDK initialization |
|
|
135
|
+
| `source` | `CurrentSource` | Current source status, input, and error |
|
|
136
|
+
| `lens` | `CurrentLens` | Current Lens status, IDs, and error |
|
|
137
|
+
| `lenses` | `Lens[]` | Array of loaded Lens objects |
|
|
138
|
+
| `liveCanvas` | `HTMLCanvasElement \| undefined` | Live preview canvas element |
|
|
139
|
+
| `captureCanvas` | `HTMLCanvasElement \| undefined` | Capture canvas element |
|
|
140
|
+
| `keyboard` | `Keyboard \| undefined` | Keyboard API for Lens keyboard requests |
|
|
141
|
+
| `isMuted` | `boolean` | Whether audio is muted |
|
|
142
|
+
| `fpsLimit` | `number \| undefined` | Current FPS limit |
|
|
143
|
+
| `screenRegions` | `ScreenRegions \| undefined` | Current screen regions |
|
|
144
|
+
|
|
145
|
+
**Methods:**
|
|
146
|
+
|
|
147
|
+
| Method | Description |
|
|
148
|
+
| ------------------------------------------------------ | ------------------------------------------------------- |
|
|
149
|
+
| `applySource(input, size?)` | Apply a media source (camera, video, or image) |
|
|
150
|
+
| `removeSource()` | Remove the current source |
|
|
151
|
+
| `fetchLens(lensId, groupId)` | Load a single Lens (returns cached if already loaded) |
|
|
152
|
+
| `fetchLenses(groupId)` | Load all Lenses in a group (accepts string or string[]) |
|
|
153
|
+
| `applyLens(lensId, groupId, launchData?, readyGuard?)` | Apply a Lens by ID |
|
|
154
|
+
| `removeLens()` | Remove the current Lens |
|
|
155
|
+
| `refreshLens()` | Remove and reapply the current Lens |
|
|
156
|
+
| `reinitialize()` | Re-bootstrap the SDK (useful after errors) |
|
|
157
|
+
| `setMuted(muted)` | Set the muted state |
|
|
158
|
+
| `toggleMuted()` | Toggle audio mute |
|
|
159
|
+
| `setFPSLimit(fps)` | Set maximum rendering FPS |
|
|
160
|
+
| `setScreenRegions(regions)` | Set screen regions for Lens-aware layout |
|
|
161
|
+
|
|
162
|
+
### useApplyLens
|
|
163
|
+
|
|
164
|
+
Declaratively apply a Lens — it updates automatically when parameters change.
|
|
165
|
+
|
|
166
|
+
```tsx
|
|
167
|
+
import { useApplyLens } from "@snap/react-camera-kit";
|
|
168
|
+
|
|
169
|
+
useApplyLens("YOUR_LENS_ID", "YOUR_LENS_GROUP_ID");
|
|
56
170
|
```
|
|
57
171
|
|
|
58
|
-
|
|
172
|
+
| Parameter | Type | Description |
|
|
173
|
+
| ---------------- | --------------------- | ------------------------------------ |
|
|
174
|
+
| `lensId` | `string \| undefined` | Lens ID — pass `undefined` to remove |
|
|
175
|
+
| `lensGroupId` | `string \| undefined` | Lens Group ID |
|
|
176
|
+
| `lensLaunchData` | `LensLaunchData` | Optional launch parameters |
|
|
177
|
+
| `lensReadyGuard` | `() => Promise<void>` | Optional async ready guard |
|
|
178
|
+
|
|
179
|
+
### useApplySource
|
|
180
|
+
|
|
181
|
+
Declaratively apply a media source. Defaults to camera if no source is provided.
|
|
182
|
+
|
|
183
|
+
```tsx
|
|
184
|
+
import { useApplySource } from "@snap/react-camera-kit";
|
|
185
|
+
|
|
186
|
+
// Video source with fixed output size
|
|
187
|
+
useApplySource({ kind: "video", url: "/demo.mp4", autoplay: true }, { mode: "fixed", width: 720, height: 1280 });
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
| Parameter | Type | Default | Description |
|
|
191
|
+
| ------------ | ------------- | -------------------- | -------------- |
|
|
192
|
+
| `source` | `SourceInput` | `{ kind: "camera" }` | Media source |
|
|
193
|
+
| `outputSize` | `OutputSize` | — | Rendering size |
|
|
194
|
+
|
|
195
|
+
### usePlaybackOptions
|
|
196
|
+
|
|
197
|
+
Declaratively set playback options.
|
|
198
|
+
|
|
199
|
+
```tsx
|
|
200
|
+
import { usePlaybackOptions } from "@snap/react-camera-kit";
|
|
201
|
+
|
|
202
|
+
usePlaybackOptions({
|
|
203
|
+
fpsLimit: 30,
|
|
204
|
+
muted: false,
|
|
205
|
+
onError: (error) => console.error("Playback error:", error),
|
|
206
|
+
});
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
| Option | Type | Description |
|
|
210
|
+
| --------------- | ----------------------- | ------------------------------ |
|
|
211
|
+
| `fpsLimit` | `number` | Maximum rendering FPS |
|
|
212
|
+
| `muted` | `boolean` | Mute audio |
|
|
213
|
+
| `screenRegions` | `ScreenRegions` | Screen regions for Lens layout |
|
|
214
|
+
| `onError` | `(error, lens) => void` | Playback error callback |
|
|
215
|
+
|
|
216
|
+
## Media sources
|
|
217
|
+
|
|
218
|
+
Pass a `SourceInput` to `LensPlayer`'s `source` prop or to `useApplySource`:
|
|
219
|
+
|
|
220
|
+
```tsx
|
|
221
|
+
// Camera (default)
|
|
222
|
+
{ kind: "camera" }
|
|
223
|
+
{ kind: "camera", deviceId: "abc123", options: { cameraFacing: "environment" } }
|
|
224
|
+
|
|
225
|
+
// Video
|
|
226
|
+
{ kind: "video", url: "/demo.mp4", autoplay: true }
|
|
227
|
+
|
|
228
|
+
// Image
|
|
229
|
+
{ kind: "image", url: "/photo.jpg" }
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
### Camera source options
|
|
233
|
+
|
|
234
|
+
| Option | Type | Default | Description |
|
|
235
|
+
| ------------------- | ------------------------- | ------------------------------ | ----------------------------- |
|
|
236
|
+
| `cameraFacing` | `"user" \| "environment"` | `"user"` | Front or back camera |
|
|
237
|
+
| `cameraConstraints` | `MediaTrackConstraints` | `{ width: 1280, height: 720 }` | Camera resolution constraints |
|
|
238
|
+
| `cameraRotation` | `0 \| -90 \| 90 \| 180` | `0` | Camera rotation |
|
|
239
|
+
| `fpsLimit` | `number` | — | Max FPS for the source |
|
|
240
|
+
| `outputSize` | `OutputSize` | — | Rendering canvas size |
|
|
241
|
+
|
|
242
|
+
### Output size
|
|
243
|
+
|
|
244
|
+
```tsx
|
|
245
|
+
// Fixed resolution
|
|
246
|
+
{ mode: "fixed", width: 720, height: 1280 }
|
|
247
|
+
|
|
248
|
+
// Match input source resolution
|
|
249
|
+
{ mode: "match-input" }
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
## Handling loading and error states
|
|
253
|
+
|
|
254
|
+
Use `useCameraKit()` to track the status of the SDK, source, and Lens. Each progresses through `"none" → "loading" → "ready"` (or `"error"`):
|
|
59
255
|
|
|
60
256
|
```tsx
|
|
61
257
|
function Preview() {
|
|
62
|
-
const { lens } = useCameraKit();
|
|
258
|
+
const { sdkStatus, sdkError, source, lens } = useCameraKit();
|
|
259
|
+
|
|
260
|
+
if (sdkStatus === "error") return <p>SDK failed: {sdkError?.message}</p>;
|
|
261
|
+
if (sdkStatus !== "ready") return <p>Initializing...</p>;
|
|
262
|
+
if (source.status === "loading") return <p>Setting up camera...</p>;
|
|
263
|
+
if (lens.status === "error") return <p>Lens error: {lens.error?.message}</p>;
|
|
264
|
+
|
|
63
265
|
return (
|
|
64
|
-
<LensPlayer lensId="YOUR_LENS_ID" lensGroupId="
|
|
65
|
-
{lens.status !== "ready" &&
|
|
66
|
-
|
|
67
|
-
{lens.status === "ready" && <LiveCanvas />}
|
|
266
|
+
<LensPlayer lensId="YOUR_LENS_ID" lensGroupId="YOUR_LENS_GROUP_ID">
|
|
267
|
+
{lens.status !== "ready" && <div className="spinner" />}
|
|
268
|
+
<LiveCanvas />
|
|
68
269
|
</LensPlayer>
|
|
69
270
|
);
|
|
70
271
|
}
|
|
71
272
|
```
|
|
72
273
|
|
|
73
|
-
|
|
274
|
+
### Frame Metrics
|
|
275
|
+
|
|
276
|
+
Use `useLensFrameMetrics` to monitor lens rendering performance:
|
|
74
277
|
|
|
75
278
|
```tsx
|
|
76
|
-
|
|
77
|
-
const { sdkStatus, source, lens } = useCameraKit();
|
|
78
|
-
useApplySource({ kind: "video", url: "/demo.mp4" }, { mode: "fixed", width: 720, height: 1280 });
|
|
79
|
-
useApplyLens("123", "abc", launchData);
|
|
80
|
-
usePlaybackOptions({ onError: (error) => console.error(error) });
|
|
279
|
+
import { useLensFrameMetrics } from "@snap/react-camera-kit";
|
|
81
280
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
281
|
+
function PerformanceOverlay() {
|
|
282
|
+
const metrics = useLensFrameMetrics({ interval: 500 });
|
|
283
|
+
|
|
284
|
+
if (!metrics) return null;
|
|
285
|
+
|
|
286
|
+
return (
|
|
287
|
+
<div>
|
|
288
|
+
<p>FPS: {metrics.avgFps.toFixed(1)}</p>
|
|
289
|
+
<p>Frame time: {metrics.lensFrameProcessingTimeMsAvg.toFixed(1)}ms</p>
|
|
290
|
+
</div>
|
|
291
|
+
);
|
|
86
292
|
}
|
|
87
293
|
```
|
|
88
294
|
|
|
89
|
-
|
|
295
|
+
The hook accepts:
|
|
90
296
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
npm install
|
|
297
|
+
- `interval` (required) — polling interval in milliseconds
|
|
298
|
+
- `enabled` (optional, defaults to `true`) — set to `false` to disable measurement without unmounting
|
|
94
299
|
|
|
95
|
-
|
|
96
|
-
npm run build
|
|
300
|
+
## Full example: Lens switcher
|
|
97
301
|
|
|
98
|
-
|
|
99
|
-
|
|
302
|
+
```tsx
|
|
303
|
+
import { CameraKitProvider, LensPlayer, LiveCanvas, useCameraKit } from "@snap/react-camera-kit";
|
|
304
|
+
import { useEffect } from "react";
|
|
305
|
+
|
|
306
|
+
const LENS_GROUP_ID = "YOUR_LENS_GROUP_ID";
|
|
307
|
+
|
|
308
|
+
function LensSwitcher() {
|
|
309
|
+
const { sdkStatus, lenses, lens, fetchLenses, applyLens, isMuted, toggleMuted, reinitialize, sdkError } =
|
|
310
|
+
useCameraKit();
|
|
311
|
+
|
|
312
|
+
useEffect(() => {
|
|
313
|
+
if (sdkStatus === "ready") fetchLenses(LENS_GROUP_ID);
|
|
314
|
+
}, [sdkStatus]);
|
|
315
|
+
|
|
316
|
+
if (sdkStatus === "error") {
|
|
317
|
+
return (
|
|
318
|
+
<div>
|
|
319
|
+
<p>SDK error: {sdkError?.message}</p>
|
|
320
|
+
<button onClick={reinitialize}>Retry</button>
|
|
321
|
+
</div>
|
|
322
|
+
);
|
|
323
|
+
}
|
|
100
324
|
|
|
101
|
-
|
|
102
|
-
|
|
325
|
+
return (
|
|
326
|
+
<div>
|
|
327
|
+
<select value={lens.lensId ?? ""} onChange={(e) => applyLens(e.target.value, LENS_GROUP_ID)}>
|
|
328
|
+
<option value="" disabled>
|
|
329
|
+
Select a Lens
|
|
330
|
+
</option>
|
|
331
|
+
{lenses.map((l) => (
|
|
332
|
+
<option key={l.id} value={l.id}>
|
|
333
|
+
{l.name}
|
|
334
|
+
</option>
|
|
335
|
+
))}
|
|
336
|
+
</select>
|
|
337
|
+
<button onClick={toggleMuted}>{isMuted ? "Unmute" : "Mute"}</button>
|
|
338
|
+
|
|
339
|
+
<LensPlayer lensId={lens.lensId} lensGroupId={LENS_GROUP_ID}>
|
|
340
|
+
<LiveCanvas style={{ width: "100%", maxWidth: 640 }} />
|
|
341
|
+
</LensPlayer>
|
|
342
|
+
</div>
|
|
343
|
+
);
|
|
344
|
+
}
|
|
103
345
|
|
|
104
|
-
|
|
105
|
-
|
|
346
|
+
export default function App() {
|
|
347
|
+
return (
|
|
348
|
+
<CameraKitProvider apiToken="YOUR_API_TOKEN">
|
|
349
|
+
<LensSwitcher />
|
|
350
|
+
</CameraKitProvider>
|
|
351
|
+
);
|
|
352
|
+
}
|
|
353
|
+
```
|
|
106
354
|
|
|
107
|
-
|
|
108
|
-
|
|
355
|
+
## Utilities
|
|
356
|
+
|
|
357
|
+
| Export | Description |
|
|
358
|
+
| ------------------------ | --------------------------------------------------- |
|
|
359
|
+
| `createConsoleLogger()` | Returns a logger that prints to the browser console |
|
|
360
|
+
| `createNoopLogger()` | Returns a silent logger (default) |
|
|
361
|
+
| `isCameraSource(source)` | Type guard for `CameraSourceInput` |
|
|
362
|
+
| `isVideoSource(source)` | Type guard for `VideoSourceInput` |
|
|
363
|
+
| `isImageSource(source)` | Type guard for `ImageSourceInput` |
|
|
364
|
+
| `CameraRotationOptions` | Valid rotation values: `[0, -90, 90, 180]` |
|
|
365
|
+
|
|
366
|
+
## Development
|
|
367
|
+
|
|
368
|
+
```bash
|
|
369
|
+
npm install # Install dependencies
|
|
370
|
+
npm run build # Build ESM + CJS
|
|
371
|
+
npm run watch # Build in watch mode
|
|
372
|
+
npm run typecheck # Type checking
|
|
373
|
+
npm test # Run tests
|
|
374
|
+
npm run clean # Clean dist folder
|
|
109
375
|
```
|
|
110
376
|
|
|
111
|
-
|
|
377
|
+
### Demo app
|
|
112
378
|
|
|
113
|
-
A Vite demo app is available
|
|
379
|
+
A Vite demo app is available in `demo/`:
|
|
114
380
|
|
|
115
381
|
```bash
|
|
116
382
|
npm run demo:install
|
|
@@ -120,7 +386,7 @@ npm run demo:dev
|
|
|
120
386
|
|
|
121
387
|
## Contributing
|
|
122
388
|
|
|
123
|
-
We welcome contributions! Please see our [Contributing Guidelines](CONTRIBUTING.md) for details
|
|
389
|
+
We welcome contributions! Please see our [Contributing Guidelines](CONTRIBUTING.md) for details.
|
|
124
390
|
|
|
125
391
|
- [Code of Conduct](CODE_OF_CONDUCT.md)
|
|
126
392
|
- [Security Policy](SECURITY.md)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CameraKitProvider.d.ts","sourceRoot":"","sources":["../../src/CameraKitProvider.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAkD,SAAS,EAAgC,MAAM,OAAO,CAAC;AACvH,OAAO,EACL,SAAS,EACT,+BAA+B,EAC/B,gBAAgB,EAChB,eAAe,EACf,IAAI,EACJ,cAAc,EAGd,aAAa,EACb,QAAQ,EACT,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAAE,WAAW,EAAE,aAAa,EAAmB,WAAW,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAC/F,OAAO,EAAE,eAAe,EAAkB,QAAQ,EAAgC,MAAM,oBAAoB,CAAC;AAU7G,MAAM,MAAM,yBAAyB,GAAG,MAAM,CAC5C,KAAK,EACD;IAAE,IAAI,EAAE,mBAAmB,GAAG,mBAAmB,CAAA;CAAE,GACnD;IAAE,IAAI,EAAE,mBAAmB,GAAG,cAAc,CAAC;IAAC,KAAK,EAAE,KAAK,CAAA;CAAE,KAC7D,IAAI,CAAC;AAEV;;;GAGG;AACH,UAAU,qBAAqB;IAC7B,yCAAyC;IACzC,SAAS,EAAE,eAAe,GAAG,cAAc,GAAG,OAAO,GAAG,OAAO,CAAC;IAEhE,6DAA6D;IAC7D,QAAQ,EAAE,KAAK,GAAG,SAAS,CAAC;IAE5B,2DAA2D;IAC3D,UAAU,EAAE,iBAAiB,GAAG,SAAS,CAAC;IAE1C,qDAAqD;IACrD,aAAa,EAAE,iBAAiB,GAAG,SAAS,CAAC;IAE7C,uEAAuE;IACvE,MAAM,EAAE,aAAa,CAAC;IAEtB,gEAAgE;IAChE,IAAI,EAAE,WAAW,CAAC;IAElB;;;;;OAKG;IACH,QAAQ,EAAE,QAAQ,GAAG,SAAS,CAAC;IAE/B,mGAAmG;IACnG,YAAY,EAAE,MAAM,IAAI,CAAC;IAEzB,uEAAuE;IACvE,WAAW,EAAE,CAAC,KAAK,EAAE,WAAW,EAAE,IAAI,CAAC,EAAE,UAAU,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAEtE,mDAAmD;IACnD,YAAY,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAElC,0EAA0E;IAC1E,MAAM,EAAE,IAAI,EAAE,CAAC;IAEf,qFAAqF;IACrF,SAAS,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAE9D,qDAAqD;IACrD,WAAW,EAAE,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,KAAK,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;IAE7D;;;;;;;OAOG;IACH,SAAS,EAAE,CACT,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EACf,UAAU,CAAC,EAAE,cAAc,EAC3B,cAAc,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,KACjC,OAAO,CAAC,OAAO,CAAC,CAAC;IAEtB,2DAA2D;IAC3D,UAAU,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;IAEnC,gEAAgE;IAChE,WAAW,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAEjC,+CAA+C;IAC/C,QAAQ,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IAEnC,uCAAuC;IACvC,WAAW,EAAE,MAAM,IAAI,CAAC;IAExB,wCAAwC;IACxC,OAAO,EAAE,OAAO,CAAC;IAEjB,iCAAiC;IACjC,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IAE7B,8EAA8E;IAC9E,WAAW,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAEjD,oDAAoD;IACpD,aAAa,EAAE,aAAa,GAAG,SAAS,CAAC;IAEzC,oDAAoD;IACpD,gBAAgB,EAAE,CAAC,aAAa,EAAE,aAAa,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACnE;AAGD,UAAU,6BAA8B,SAAQ,qBAAqB;IACnE,SAAS,EAAE,SAAS,GAAG,SAAS,CAAC;IACjC,cAAc,EAAE,gBAAgB,GAAG,SAAS,CAAC;IAC7C,SAAS,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,eAAe,CAAC;CAC5C;AAwCD;;;GAGG;AACH,UAAU,sBAAuB,SAAQ,IAAI,CAAC,+BAA+B,EAAE,QAAQ,CAAC;IACtF;;;;OAIG;IACH,eAAe,CAAC,EAAE,CAAC,SAAS,EAAE,eAAe,KAAK,eAAe,CAAC;IAElE;;;OAGG;IACH,2BAA2B,CAAC,EAAE,yBAAyB,CAAC;IAExD;;;;;;;;;;;;OAYG;IACH,MAAM,CAAC,EAAE,eAAe,CAAC;IAEzB;;;OAGG;IACH,QAAQ,CAAC,EAAE,QAAQ,CAAC;IAEpB;;;;;;;OAOG;IACH,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAE/B;;;;;OAKG;IACH,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAE/B;;OAEG;IACH,QAAQ,EAAE,SAAS,CAAC;CACrB;AAID;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,eAAO,MAAM,iBAAiB,EAAE,KAAK,CAAC,EAAE,CAAC,sBAAsB,
|
|
1
|
+
{"version":3,"file":"CameraKitProvider.d.ts","sourceRoot":"","sources":["../../src/CameraKitProvider.tsx"],"names":[],"mappings":"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"}
|
|
@@ -142,6 +142,9 @@ const CameraKitProvider = ({ extendContainer, stabilityKey, children, createBoot
|
|
|
142
142
|
(0, react_1.useEffect)(() => {
|
|
143
143
|
const abortController = new AbortController();
|
|
144
144
|
const emit = eventFactoryRef.current?.();
|
|
145
|
+
// Clear stale lens cache — the old kit's lensRepository is no longer valid.
|
|
146
|
+
lensCache.current.clear();
|
|
147
|
+
setLenses([]);
|
|
145
148
|
setCameraKitState({ status: "initializing" });
|
|
146
149
|
emit?.({ kind: "bootstrap-attempt" });
|
|
147
150
|
log.info("bootstrap_attempt");
|