<Camera> — full prop reference
Every prop is optional. <Camera> works with no props — it captures, and
you wire onCapture to receive the result. The props fall into the groups
below, followed by deep-dives on panorama guidance, the JSON settings
objects, the guidanceCopy keys, and the allowed enum values.
The defaults in these tables are the values the component actually
resolves at mount — cross-checked against the component destructure and
DEFAULT_PANORAMA_SETTINGS / DEFAULT_FLOW_GATE_SETTINGS — not the prop
JSDoc, which is stale in a few places. Where a JSDoc claim disagrees, the
table here is authoritative.
Capture source & lens
Uncontrolled — read once at mount.
| Prop | Type | Default | Description |
|---|---|---|---|
defaultCaptureSource | CaptureSource ('ar' | 'non-ar') | 'non-ar' | Initial capture source, read once at mount (uncontrolled). Consider 'ar': AR feeds the engine natively, so it is immune to the frame-processor build failure described in Host integration (caveats: on Android a device without Google Play Services for AR shows a blank AR preview with no automatic downgrade today; AR tap-photos use the AR video stream, no flash, no iOS depth sidecar). Clamped by captureSources. |
defaultLens | CameraLens ('1x' | '0.5x') | '1x' | Initial physical lens. When captureSources='ar' the lens is forced to '1x' — the ultra-wide isn't usable in AR. |
captureSources | CaptureSourcesMode ('ar' | 'non-ar' | 'both') | 'both' | Which capture sources the host allows. 'both' shows the AR toggle; 'ar' is AR-only (toggle and 0.5× chooser hidden); 'non-ar' hides the toggle. A single source overrides a conflicting defaultCaptureSource. Use 'ar' to lock captures to AR and hide the AR pill so users can't flip modes. |
engine | 'batch-keyframe' | 'batch-keyframe' | Which stitcher engine to drive. Only 'batch-keyframe' is supported and is the default. |
See Flash & lenses for how lens selection, device capability, and flash interact.
Stitcher tunables
Uncontrolled internal-tester knobs; most apps never set these. Each flat
default* prop seeds the matching field in the settings tree at mount.
v0.16 adds the stitcher and
frameSelection JSON-object props, which take
precedence over the flat props below.
| Prop | Type | Default | Description |
|---|---|---|---|
defaultStitchMode | StitchMode ('auto' | 'panorama' | 'scans') | 'auto' | Initial cv::Stitcher pipeline mode seed. Resolves through DEFAULT_PANORAMA_SETTINGS.stitcher.stitchMode. |
defaultBlender | Blender ('multiband' | 'feather') | 'multiband' | Initial pixel blender seed (DEFAULT_PANORAMA_SETTINGS.stitcher.blenderType). |
defaultWarper | Warper ('plane' | 'cylindrical' | 'spherical') | 'plane' | Initial output projection seed (PANORAMA mode only; SCANS hard-wires plane). Resolves to DEFAULT_PANORAMA_SETTINGS.stitcher.warperType — v0.16 reverted this from 'spherical' back to 'plane'. |
maxInscribedRectCrop | boolean | false | Crop-strategy seed. false keeps the non-black bounding rect; true crops to the max inscribed rectangle (no black corners, more CPU). Forced off internally when rectCrop is on. Maps to stitcher.enableMaxInscribedRectCrop. See Inscribed-rect crop. |
defaultFlowNoveltyPercentile | number | 0.85 | Flow-gate novelty percentile seed (flow-based mode). DEFAULT_FLOW_GATE_SETTINGS.noveltyPercentile. Clamped natively to [0.50, 0.99]. |
defaultFlowEvalEveryNFrames | number | 5 | Flow-gate eval throttle seed. DEFAULT_FLOW_GATE_SETTINGS.evalEveryNFrames. Clamped natively to [1, 10]. |
defaultFlowMaxTranslationCm | number | 50 | Flow-gate translation budget (cm) seed. DEFAULT_FLOW_GATE_SETTINGS.maxTranslationCm. 0 disables; clamped natively to [0, 100]. |
defaultKeyframeMaxCount | number | 6 | Hard cap on accepted keyframes seed. Resolves to DEFAULT_PANORAMA_SETTINGS.frameSelection.maxKeyframes. Clamped natively to [3, 10]. Maps to frameSelection.maxKeyframes. |
defaultKeyframeOverlapThreshold | number | 0.20 | Required new-content fraction seed. Resolves to DEFAULT_PANORAMA_SETTINGS.frameSelection.overlapThreshold = 0.20 (the FrameSelectionSettings docstring's 0.15 is stale). Clamped natively to [0.10, 0.80]. |
defaultMaxKeyframeIntervalMs | number | 1500 | Time-budget force-accept (ms) for the keyframe gate seed. Resolves to DEFAULT_PANORAMA_SETTINGS.frameSelection.maxKeyframeIntervalMs = 1500 (the prop JSDoc's 2000 is stale). 0 disables. Applies to AR + non-AR. |
defaultCompositingResolMP | number | — | Forward-looking; accepted for API stability but currently a no-op. Will wire to cv::Stitcher compositing resolution later. |
defaultRegistrationResolMP | number | — | Forward-looking; accepted but currently a no-op. |
defaultSeamEstimationResolMP | number | — | Forward-looking; accepted but currently a no-op. |
stitcher | Partial<Omit<BatchStitcherSettings, perf keys>> | — | The stitch recipe object: stitchMode / warperType / blenderType / enableMaxInscribedRectCrop / debugPack. Wins over the flat default* props. v0.24 — the speed levers moved to perf. |
frameSelection | Partial<...gate fields> | — | The keyframe gate object: mode / maxKeyframes / overlapThreshold / maxKeyframeIntervalMs / flow (deep-merged). v0.24 — the anti-blur controls moved to blur. |
blur | BlurPropOverrides | — | v0.24 anti-blur group. See below. |
perf | PerfPropOverrides | — | v0.24 perf-lever group. See below. |
The in-app settings modal (gear, shown via showSettingsButton) can edit
the stitcher and frame-gate fields at runtime; those edits override these
seed props at capture time.
Anti-blur & perf groups (v0.24)
v0.24 groups the anti-blur and stitch-speed knobs into two dedicated prop objects. Both are partial + deep-merged over the SDK defaults, so set only what you want. Upgrading from v0.23? See the migration guide.
blur — motion-blur defenses
<Camera blur={{ sharpnessWindow: 4, maxExposureMs: 8, preferHighFpsFormat: true }} />
| Field | Type | Default | How to flip / what it does |
|---|---|---|---|
sharpnessWindow | number | 4 | Pick the sharpest of K gate-evaluated frames. 1 disables (immediate save). |
maxExposureMs | number | 8 | Exposure-cap target (ms) shared with the host capture session. 0 = don't cap. |
maxCommitPanRateRadPerSec | number | 1.0 | Hold keyframe commit while slewing faster than this (rad/s). 0 = no motion gate. |
minScoreFractionOfMedian | number | 0.6 | Hold commit while the best candidate is below this fraction of the session sharpness median. 0 = off. |
maxConsecutiveHolds | number | 12 | Forward-progress guard: never hold the same pending keyframe more than this many evaluated frames. |
preferHighFpsFormat | boolean | true | Prefer the highest-fps capture format (bounds exposure + doubles candidates). false = smallest format. The only exposure lever on the iOS AR path. |
perf — stitch-speed levers
<Camera perf={{ seamFinderType: 'voronoi', numThreads: 0 }} />
| Field | Type | Default (v0.24) | How to flip / what it does |
|---|---|---|---|
seamFinderType | 'voronoi' | 'graphcut' | 'skip' | 'voronoi' | The dominant speed lever. voronoi is ~1.6–1.9× faster than graphcut with no visible quality loss on-device. Use 'graphcut' for high near-field-parallax corpora; 'skip' for the lowest-memory config (pair with blenderType:'feather'). |
rangeMatcherWidth | number | 3 | PANORAMA feature-matcher window (2/2/3 ladder). 0 = legacy full-pairwise. Android/high-level only. |
numThreads | number | 0 | OpenCV intra-stitch threads. 0 = auto multi-core (fastest on-device at 8–10 keyframes). 1 = single-thread kill-switch (lower peak RAM). Android only (iOS is always multi-core). |
adaptiveStitchMode | 'measured' | 'off' | 'always' | 'measured' | Compose-resolution adaptation. 'measured' shrinks the output to adaptiveMinOutputMP only on devices proven slow. 'off' = never shrink. Android only. |
adaptiveMinOutputMP | number | 0.6 | Compose-resolution floor (MP) when adapting. Native clamps [0.6, 1.0]. |
adaptiveSlowStitchMsPerFrame | number | 1000 | Per-keyframe wall-time (ms) above which 'measured' fires. |
Inscribed-rect crop
When cv::Stitcher warps the keyframes onto the output canvas, the filled
region is rarely a perfect rectangle — the edges curve and the corners are
often empty (black), especially on a wide pan or a plane / cylindrical
warp. maxInscribedRectCrop chooses how that canvas is cropped at finalize:
false(default) — crop to the bounding rectangle of the non-black pixels: keeps every stitched pixel, but can leave black corners where the projection didn't fill.true— crop to the largest axis-aligned rectangle that fits entirely inside the stitched region: clean, straight edges, no black corners, at the cost of more CPU at finalize and a potentially much smaller output on lopsided or ultra-wide pans — which is why it's opt-in.
// Default (false) — bounding-box crop, keeps every stitched pixel:
<Camera onCapture={handleCapture} />
// Opt in — clean inscribed rectangle, no black corners (may shrink the output):
<Camera onCapture={handleCapture} maxInscribedRectCrop={true} />
rectCrop forces this offWhen the rectCrop draggable-quad editor
is enabled, the native auto-crop (maxInscribedRectCrop) is forced off — the
manual crop is the source of truth.
Panorama capture & guidance (v0.16)
These props govern the non-AR panorama capture flow: which device hold is accepted, the live guidance surfaces during the pan, the auto-stop budgets, and what UI (if any) the user sees after the stitch finalizes.
panMode
PanMode ('vertical' | 'horizontal' | 'both'), default 'vertical'.
Which device hold the non-AR pano accepts:
'vertical'— landscape-only, top → bottom. Breaking new default.'horizontal'— portrait-only, left → right.'both'— no rotate gate; any hold is accepted.
Starting in the wrong hold is blocked behind the rotate prompt (see
rotateToLandscape / rotateToPortrait in guidanceCopy keys).
panGuidance
boolean, default true.
panGuidance is a current propEarlier drafts of this page claimed panGuidance was removed. That was
wrong — it is a live prop and defaults to true.
Master switch for the in-capture pan-guidance surfaces: the rotate prompt,
the pan how-to animation/hint, the "too fast" pill, and the blinking
countdown. Set false to suppress all of them. Note that the lateral-drift
stop (lateralBudgetCm /
lateralStopFinalizeMinFrames) and the
post-stitch review surface (rectCrop /
showPreview) have their own props and are not governed
by panGuidance. They are not independent of each other, though: a review
surface suppresses the popup a finalized lateral stop would otherwise
show — see what shows after a lateral-drift stop.
maxPanDurationMs
number, default 0 (disabled).
A hard recording-time ceiling (ms) that acts as a safety cap alongside
the primary keyframe-count auto-stop. v0.16 changed the default from 9000
to 0 — the keyframe-count auto-stop is now the default UX, and the time cap
is opt-in. When > 0, a blinking countdown is shown and capture
auto-finalizes when it reaches 0.
panTooFastThreshold
number, default 0.6 rad/s (resolved fallback).
Gyro rate (rad/s) above which the pan is flagged "too fast" (the amber pill).
There is no component-level default; the prop is passed through as
usePanMotion's warnMaxRadPerSec, so when omitted it resolves to
DEFAULT_WARN_RAD_PER_SEC = 0.6.
The prop JSDoc claims a default of 1.0 rad/s. The real fallback literal is
0.6.
lateralBudgetCm
number, default 8 (v0.25.3 — was 4).
Cross-pan (lateral / sideways) drift budget in cm. Once integrated sideways
translation exceeds this for the grace window, the capture is stopped. Set
0 to disable the lateral-drift stop entirely.
This is the sensitivity knob — how much drift is tolerated before a stop
happens at all. What happens at that stop (finalize the partial sweep, or
discard it) is a separate decision, controlled by
lateralStopFinalizeMinFrames. If operators
report the stop firing too eagerly, raise this; if they report stopped captures
being thrown away, lower that one.
v0.25.3 raised the default after field reports of the stop firing on minor
drift. v0.26.0 fixed the underlying detector — see
lateralMotionModel. The budget stays at 8 so the
detector change and the threshold do not move in the same release.
lateralBudgetCm is not the only lateral triggerThe capture is also stopped by an independent cross-pan rotation trigger,
lateralTurnRateRadPerSec — historically the
primary one. lateralBudgetCm does not affect it. If operators report eager
stops, read latch=gyro|accel in the [panMotion] telemetry
(panMotionDebug) to find out which trigger is firing
before tuning either. Setting lateralBudgetCm={0} disables both.
Whether that stop KEEPS what was captured (finalize + stitch, carrying the
LATERAL_DRIFT_FINALIZE warning) or throws it away is a separate decision —
see lateralStopFinalizeMinFrames below. At
its default the capture is kept only when at least 5 keyframes were accepted
— a change from the 2 this budget used to imply.
lateralTurnRateRadPerSec
number, default 0.15 (rad/s ≈ 8.6 °/s) — unchanged from earlier
versions; exposed as a prop in v0.26.0.
The second, independent lateral trigger: an EMA (τ ≈ 0.4 s) of the
cross-pan gyroscope rate. Historically this has been the primary trigger in
practice — it fires on sustained cross-axis rotation regardless of
lateralBudgetCm.
It was tuned against a single field trace (a straight pan smoothed to ~0.04 rad/s; two deliberate cross-turns to ~0.3 and ~0.7). Raise it if operators are stopped while panning normally; lower it to catch gentler veering.
Because both triggers set the same flag, a stop you attribute to "drifting
sideways" may in fact be this one. Check latch= in the telemetry first.
0 disables this trigger only. lateralBudgetCm={0} disables both.
lateralMotionModel
'fused' | 'legacy', default 'fused' (v0.26.0).
Which physics the displacement (accelerometer) trigger runs.
'fused'— subtract the device's fused gravity vector per sample, then high-pass the residual; derivedtfrom each sample's own sensor timestamp; time-normalise every filter coefficient so the detector behaves the same at any sensor cadence.'legacy'— the ≤0.25.3 behaviour bit-for-bit: a per-sample IIR gravity estimate and a hardcoded 20 msdt.
'legacy' cannot tell a wrist tilt from a sideways slide — a re-projection
of gravity onto the cross-pan axis is arithmetically identical to real
acceleration. Measured on an 8 s sweep with zero real translation, 6° of
wrist roll read 5.18 cm, while a real 100 cm slide read 2.00 cm. It is an
escape hatch for reproducing an old capture, not a rollout gate.
Falls back to 'legacy' automatically and per sample whenever the gravity
sensor is absent, errored, warming up, stale, or reporting an implausible
magnitude — so a device without a usable gravity sensor is never worse off.
panMotionDebug
boolean, default __DEV__.
Emit the throttled [panMotion] diagnostics (~2.5 Hz). Pass true to keep
them in a release build while diagnosing a field report without shipping a
new version; pass false to silence them in development.
The lines carry latch=gyro|accel, gSrc=, lat=…cm, budget=, crossEma=,
thresh=, per-sample dt statistics, and both the fused and IIR estimates of
the same quantity — enough to attribute a stop to a trigger and a cause from a
Metro log.
lateralStopFinalizeMinFrames
number, default 5.
The accepted-keyframe count at or above which a lateral-drift stop
finalizes the capture: the partial sweep is stitched and delivered to
onCapture with a LATERAL_DRIFT_FINALIZE warning. Below the threshold the
capture is discarded instead — the engine is cancelled, nothing is
stitched, and onCaptureAbandoned('lateral-drift')
fires.
| Value | Behaviour |
|---|---|
0 | ALWAYS DISCARD — a laterally-drifted sweep is never kept, whatever was captured. |
N >= 1 | Finalize iff acceptedKeyframeCount >= N, otherwise discard. |
2 | Reproduces the previously hardcoded behaviour exactly (keep anything stitchable). |
5 (default) | Keep only a real sweep; 2-4 keyframes discard. |
The default of 5 is not the 2 the SDK used to hardcode. A capture that
accepted 2, 3 or 4 keyframes before drifting used to finalize and reach
onCapture; it now abandons and fires
onCaptureAbandoned('lateral-drift')
instead. For shelf capture that remnant is not a usable panorama — it is waste
that still costs a stitch, a file, and an operator's attention on output that
has to be rejected downstream.
Pass lateralStopFinalizeMinFrames={2} to restore the previous behaviour.
0 is a special case, not arithmetic0 means always discard. It has to be guarded explicitly, because the
natural acceptedKeyframeCount >= minFrames comparison is unconditionally
true at 0 — which would silently mean the exact opposite, "always
finalize".
Negative, NaN and infinite values normalise back to the default, so a broken
host config degrades to the standard behaviour rather than to "throw every
capture away". Fractional values round up (2.5 needs 3 frames) — the prop
counts whole frames.
Why it exists: a hardcoded threshold is a product judgement the SDK is not entitled to make. A shelf-audit host wants the 3-frame partial panorama; a host feeding a downstream vision pipeline treats any laterally-drifted sweep as garbage, and keeping it only costs a stitch, a file, and an operator's attention on output they will bin.
The discard path shows its own popup state, whose copy does not promise a
stitch — lateralStopDiscardedTitle / lateralStopDiscardedBody.
Below 2 accepted keyframes nothing stitchable existed in the first place, so
the popup keeps the pre-existing "follow the arrow" wrong-direction copy
regardless of this threshold.
A discarded capture always shows its popup: nothing was kept, no review surface follows, and the popup is the only feedback there is. A finalized stop is the asymmetric case — it shows no popup at all when a review surface follows. See what shows after a lateral-drift stop.
// Never keep a drifted sweep — the pipeline downstream would reject it anyway.
<Camera lateralStopFinalizeMinFrames={0} onCaptureAbandoned={handleAbandon} />
rectCrop
boolean, default false.
Show the draggable-quad crop editor after a pano finalizes, before
onCapture fires. With true, the user drags four corners and confirming
perspective-rectifies the stitch to a rectangle.
showPreview
boolean, default false.
Show a plain review screen (Retake / Confirm, no crop box) after a pano
finalizes. Ignored when rectCrop is on.
How rectCrop and showPreview interact
Both props control the post-finalize UI, and rectCrop takes precedence:
rectCrop | showPreview | What the user sees after finalize |
|---|---|---|
false | false | Nothing — onCapture fires immediately, no review UI. |
false | true | Plain review screen (Retake / Confirm), no crop box. |
true | false | Draggable-quad crop editor (drag 4 corners, confirm rectifies). |
true | true | Crop editor wins — showPreview is ignored. |
These two props are also what decides whether a finalized lateral-drift stop shows its popup: the first row is the only configuration in which it does, because it is the only one where no review surface follows. See what shows after a lateral-drift stop.
When rectCrop is on, the native auto-crop (maxInscribedRectCrop) is forced
off so the manual crop is the single source of truth. The crop editor's button
labels and the preview's confirm label are all overridable via
guidanceCopy (cropConfirm, cropReset,
cropUseOriginal, cropRetake, previewConfirm).
What shows after a lateral-drift stop
Only one of <Camera>'s capture-flow modals is ever on screen at a time.
On iOS each one is a real UIViewController presentation, and a controller can
present only one child: a second present is refused and leaves an invisible
window in the hierarchy that swallows every touch. That was the 0.25.1
dead-shutter bug, and the rule below is what prevents it.
So a host can predict exactly what the operator sees:
| Stop outcome | rectCrop / showPreview | What appears |
|---|---|---|
| Finalized | either is on | Review surface only. No popup — the surface's own banner already carries the same LATERAL_DRIFT_FINALIZE warning. |
| Finalized | both off | Popup only — lateralStopTitle / lateralStopBody. No review surface follows, so the popup is the only feedback. |
Discarded by lateralStopFinalizeMinFrames | any | Popup only — lateralStopDiscardedTitle / lateralStopDiscardedBody. Nothing was kept, so there is nothing to review. |
| Too few frames to stitch anything | any | Popup only — lateralWrongDirectionTitle / lateralWrongDirectionBody. |
The review surface additionally waits while any guidance popup is up (including the orientation-drift popup) and mounts when that popup is dismissed. The pending result is held in state meanwhile, so nothing is lost — it costs a beat, not a capture.
Before 0.25.1 a finalized stop showed the popup and then tried to open the review surface over it, which is the clash described above. If your host relied on the popup appearing after a finalized lateral stop, it is now suppressed whenever a review surface follows — the warning is in that surface's banner instead. Discard outcomes are unaffected and still show their popup.
guidanceCopy
Partial<GuidanceCopy>, default falls back to DEFAULT_GUIDANCE_COPY.
Copy overrides for every guidance string — the rotate prompt, the pan hint,
the "too fast" warning, the lateral-stop popup, the crop/preview buttons, the
status banner, and the warning banners. It's a Partial: any key you omit
falls back to DEFAULT_GUIDANCE_COPY. See guidanceCopy keys
for the full key list and defaults.
<Camera
panMode="vertical"
panGuidance
lateralBudgetCm={8}
rectCrop
guidanceCopy={{
rotateToLandscape: 'Turn your phone sideways',
panHint: 'Sweep slowly, top to bottom',
cropConfirm: 'Looks good',
}}
onCapture={handleCapture}
/>
UI toggles
| Prop | Type | Default | Description |
|---|---|---|---|
enablePhotoMode | boolean | true | Enable tap-shutter single-photo capture. |
enablePanoramaMode | boolean | true | Enable hold-pan-release panorama capture. |
showSettingsButton | boolean | false | Show the gear button that opens the internal settings modal. Off by default so public consumers don't see it (absorbed into the header's right side when headerTitle is set). |
style | StyleProp<ViewStyle> | — | Style applied to the Camera root container. |
Photo depth sidecar (iOS)
| Prop | Type | Default | Description |
|---|---|---|---|
captureDepthData | boolean | false | iOS, non-AR photo path. Save each tap photo's AVDepthData as a <photo>.depth.bin sidecar (float32 metres + JSON header) and return its path as depthPath on the photo result. Stereo depth on dual-camera iPhones, LiDAR-backed absolute depth on Pro models. Silently yields no sidecar on Android, in AR capture, and on single-lens hardware. Adds per-shot latency while depth delivery runs. |
See Photo depth sidecar for the sidecar file format, device requirements, and consumption notes.
Flash
Controlled or uncontrolled. See Flash & lenses.
| Prop | Type | Default | Description |
|---|---|---|---|
flash | 'on' | 'off' | — (uncontrolled; internal 'off') | Controlled-or-uncontrolled torch state. Omit to let <Camera> own it internally; supply it to take ownership in the parent. Forced to 'off' in AR mode (ARKit/ARCore own the torch). |
onFlashChange | (next: 'on' | 'off') => void | — | Fires when the user taps the built-in flash button. In uncontrolled mode the internal state has already flipped; in controlled mode the parent must update flash or the toggle is a no-op. |
showFlashButton | boolean | true | Show the built-in flash button in the bottom-left slot. Set false to render your own flash chrome and drive the torch via the controlled flash prop. |
Header chrome (opt-in)
Setting headerTitle renders a built-in top header; the settings gear is
absorbed into it.
| Prop | Type | Default | Description |
|---|---|---|---|
headerTitle | string | — (header not rendered) | Built-in CaptureHeader title (centred). When undefined the header is not rendered. |
onHeaderBack | () => void | — (no back button) | Header back-button callback. When supplied (and headerTitle set) the header renders a back affordance on the left. |
headerBackLabel | string | '‹ Back' | Header back-button label. No effect unless headerTitle and onHeaderBack are both set. |
headerGuidance | string | — (renders nothing) | Optional second-line subtitle below the header title. No effect unless headerTitle is set. |
headerColors | CaptureHeaderProps['colors'] | — (white-on-black) | Colour overrides for the built-in header. No effect unless headerTitle is set. |
Capture history (thumbnails)
| Prop | Type | Default | Description |
|---|---|---|---|
thumbnails | CaptureThumbnailItem[] ({ id, uri, width?, height? }) | — (strip skipped) | When provided (even as []), Camera renders a built-in CaptureThumbnailStrip above the bottom controls. onCapture results are not auto-added; the host owns the canonical list. |
thumbnailsMin | number | — | Minimum-photos hint for the count line ('n / min'); success colour when reached, warning otherwise. |
thumbnailsMax | number | — | Maximum-photos hint for the count line ('· max' suffix). No enforcement. |
onThumbnailPress | (item: CaptureThumbnailItem) => void | — (built-in preview) | Tap handler for thumbnails. When set, replaces the strip's built-in tap-to-preview modal with the host's own UI. |
Post-stitch preview modal
| Prop | Type | Default | Description |
|---|---|---|---|
capturePreview | { imageUri: string; imageWidth?: number; imageHeight?: number; title?: string } | — (modal hidden) | When set, Camera renders a built-in CapturePreview modal as visible (post-stitch confirmation). undefined hides it. |
capturePreviewActions | CapturePreviewAction[] | — / [] (only close affordance) | Action buttons along the bottom of the CapturePreview modal. Empty/undefined renders no buttons, only the close affordance. |
onCapturePreviewClose | () => void | — | Fires when the user dismisses the capturePreview modal (close tap, backdrop tap, Android hardware back). Host clears the capturePreview prop in response. |
Frame processor (advanced)
| Prop | Type | Default | Description |
|---|---|---|---|
frameProcessor | ReadonlyFrameProcessor | DrawableFrameProcessor |