Camera Component
Introduction
The Camera Component in CXTMS captures still images using the device camera in picture mode. It is designed for workflows requiring visual documentation — proof of delivery, shipment verification, damage inspection, etc. The component streams the camera feed to a <video> element, captures frames to a hidden <canvas>, and fires onCapture with the result (base64 or Blob) for upload or storage.
YAML Structure
component: camera
name: cameraPrimary
props:
width: <number>
height: <number>
facing: <"front" | "back">
mode: <string> # currently only "picture" is supported
enableTorch: <boolean>
zoom: <number>
autofocus: <"on" | "off" | undefined>
mirror: <boolean>
picture:
quality: <number> # 0–1, default varies
format: <"jpeg" | "png" | "webp">
base64: <boolean> # if true, result is base64 string; else Blob
onCapture:
- <action_sequence>
onScan:
- <action_sequence>
onError:
- <action_sequence>
onPermissionDenied:
- <action_sequence>
onClose:
- <action_sequence>
onReady:
- <action_sequence>
onPermissionDenied:
- <action_sequence>
onError:
- <action_sequence>
Structure Breakdown
| Element | Type | Description |
|---|---|---|
component | string | Always camera |
props | object | Camera options and event handlers |
width / height | number | Viewport dimensions in pixels |
facing | string | Camera to use: front or back (default: back) |
picture | object | Capture format and quality settings |
enableTorch | boolean | Enable flashlight/torch while streaming |
zoom | number | Initial zoom level |
autofocus | string | on / off; defaults to browser auto |
mirror | boolean | Mirror the preview (default: true for front camera) |
onCapture | array | Actions fired after a successful capture |
onClose | array | Actions fired when the camera stream stops |
onReady | array | Actions fired when the camera is initialized |
onPermissionDenied | array | Actions fired when camera permission is denied |
onError | array | Actions fired on camera initialization or runtime errors |
Attribute Description
Root level
- Type:
string - Description: Always set to
camera.
props.facing
- Type:
string - Values:
front,back - Default:
back - Description: Selects which physical camera to use.
props.mode
- Type:
string - Default:
picture - Description: Currently only
picturemode is supported. Other values fall back to picture mode with a console warning.
props.picture
| Sub-prop | Type | Default | Description |
|---|---|---|---|
quality | number | provider default | JPEG quality from 0 to 1 |
format | string | jpeg | Output format: jpeg, png, or webp |
base64 | boolean | — | If true, onCapture receives a base64 string; otherwise a Blob |
props.enableTorch
- Type:
boolean - Description: Activates the device flash / torch during streaming.
props.zoom
- Type:
number - Description: Initial zoom factor (device capabilities determine actual range).
props.autofocus
- Type:
string - Values:
on,off - Description: Controls the autofocus feature. Omit to let the browser decide.
props.mirror
- Type:
boolean - Default:
truefor front camera,falsefor back - Description: Horizontally flips the video preview (does not affect the captured image).
Event Handlers
onCapture
Fired after a frame is captured from the canvas. Receives { data: string|Blob, width: number, height: number }.
onClose
Fired when the camera stream is stopped (component unmounts or parent closes it).
onReady
Fired once the camera is initialized and streaming. Receives { facing, mode: 'picture' }.
onPermissionDenied
Fired when the browser denies camera permission. Receives { permission: 'camera' }.
onError
Fired on camera initialization failure or runtime errors. Receives { message: string, code: string }.
Examples
1. Picture mode — proof-of-delivery photo
A driver captures a single photo, uploads it, and stores the resulting URL on the delivery record.
component: camera
name: podCamera
props:
width: 1024
height: 768
facing: back
onCapture:
- fileUpload:
file: "{{ result.data }}"
name: "capture"
onSuccess:
- setStore:
imageUrl: "{{ result.url }}"
onClose:
- navigateBackOrClose:
result: "cancelled"
Front Camera with Mirror and Torch
component: camera
props:
facing: front
mirror: true
enableTorch: false
picture:
format: jpeg
quality: 0.85
base64: true
onCapture:
- setStore:
selfieData: "{{ result.data }}"
onPermissionDenied:
- notification:
message: "Camera access is required to take photos."
variant: warning
onError:
- notification:
message: "Camera error: {{ error.message }}"
variant: error
With Autofocus Disabled and Zoom
component: camera
name: receivingScanner
props:
width: 1280
height: 720
facing: back
zoom: 1.5
autofocus: off
picture:
format: png
base64: true
onCapture:
- setStore:
scannedImage: "{{ result.data }}"
Best Practices
- Pick the tightest
barcodeTypeswhitelist that fits your workflow. Decoding every symbology is slower and admits more false reads. Retail flows usually needean13,ean8,upc_a,upc_e. Logistics flows usually needcode128,itf14,qr,datamatrix. - Set a realistic
minBarcodeLength. Too low admits noise from wedge scanners and partial reads; too high rejects legitimate short codes (e.g.ean8is only 8 characters). - Use
enableTorchfor dim environments. Warehouses, trailer interiors, and night deliveries decode dramatically faster with the torch on. Consider exposing it as a user-toggleable UI control rather than hard-codingtrue. - Leave
deduplicate: truefor multi-scan workflows. Operators routinely sweep the same carton twice; deduplication prevents double-counting without forcing the operator to be careful. - Always handle
onPermissionDeniedon mobile devices. A camera component that silently shows nothing when permission is denied is the most common in-field complaint. Show a dialog explaining how to re-enable the permission. - In
hybridmode, give visual confirmation of scans. Because scans and captures are independent in hybrid mode, operators benefit from an on-screen confirmation (notification or store-bound badge) before they tap the shutter — otherwise they don't know whether the scan landed. - Prefer
result.urloverresult.datafor uploads. The Base64 payload doubles memory pressure; only setpicture.base64: trueif a downstream consumer specifically needs it. - Avoid logging sensitive barcode contents. Shipping labels often encode customer addresses, PII, and order values. Restrict any action that persists raw barcode data to authorized roles.
When to use Camera vs Barcode Scanner Component vs openBarcodeScanner action
CXTMS exposes three different barcode-capable surfaces. Use this table to pick the right one:
| Use case | Best surface |
|---|---|
| Inline live camera viewport that only scans (no photo) | Barcode Scanner Component |
| One-off "Scan something" triggered from a button or workflow | openBarcodeScanner action |
| Camera viewport that captures still photos | camera with mode: picture |
| Camera viewport that captures still photos and scans codes | camera with mode: hybrid |
| Full-screen continuous scanning workflow with live preview | camera with mode: scanner |
Rule of thumb: choose camera when the operator needs to see the preview as part of the task. Choose the standalone scanner component or action when the camera is purely an input device and a live viewport is incidental.