auto-camera
v0.1.1
Published
A lightweight, pure TypeScript camera component with canvas rendering and photo capture capabilities.
Maintainers
Readme
auto-camera
A lightweight, pure TypeScript camera component with canvas rendering and photo capture capabilities.
Features
- Canvas-based video rendering with responsive sizing
- Photo capture with JPEG quality control
- Front/back camera switching
- Event-driven architecture
- Optional UI controls
- No external dependencies
Installation
npm install auto-cameraQuick Start
import { createCamera } from "auto-camera";
// Create camera with controls
const { camera, controls, destroy } = createCamera("#camera-container", {
camera: {
facingMode: "user",
mirrored: true,
},
controls: true,
});
// Capture a photo
const result = await camera.capture();
console.log(result.dataUrl);
// Clean up when done
destroy();Manual Setup
For more control, use the AutoCamera class directly:
import { AutoCamera, CameraControls } from "auto-camera";
const camera = new AutoCamera({
target: "#camera-container",
facingMode: "environment",
width: 1920,
height: 1080,
aspectRatio: 16 / 9,
jpegQuality: 0.92,
mirrored: false,
autoStart: true,
});
// Optionally add UI controls
const controls = new CameraControls(camera, {
position: "bottom",
showCaptureButton: true,
showSwitchButton: true,
});
controls.mount(camera.getCanvas().parentElement);Configuration Options
CameraConfig
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| target | HTMLElement \| string | required | Target element or selector |
| facingMode | "user" \| "environment" | "environment" | Camera facing mode |
| width | number | 1280 | Preferred video width |
| height | number | 720 | Preferred video height |
| aspectRatio | number | 16/9 | Aspect ratio for canvas |
| jpegQuality | number | 0.92 | JPEG quality (0-1) |
| mirrored | boolean | false | Mirror the video horizontally |
| autoStart | boolean | true | Auto-start camera on mount |
CameraControlsConfig
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| showCaptureButton | boolean | true | Show capture button |
| showSwitchButton | boolean | true | Show camera switch button |
| captureButtonContent | string | "📷" | Capture button content |
| switchButtonContent | string | "🔄" | Switch button content |
| position | "bottom" \| "top" \| "left" \| "right" | "bottom" | Controls position |
| className | string | "" | Custom CSS class |
Methods
AutoCamera
| Method | Returns | Description |
|--------|---------|-------------|
| start() | Promise<void> | Start the camera stream |
| stop() | void | Stop the camera stream |
| pause() | void | Pause the stream |
| resume() | void | Resume from pause |
| capture() | Promise<CaptureResult> | Capture current frame |
| captureAndDownload(filename?) | Promise<CaptureResult> | Capture and download as JPG |
| switchCamera() | Promise<void> | Toggle front/back camera |
| getState() | CameraState | Get current state |
| getCanvas() | HTMLCanvasElement | Get canvas element |
| getStream() | MediaStream | Get media stream |
| destroy() | void | Clean up resources |
Events
Subscribe to events using on() or once():
// Subscribe to an event
camera.on("capture", (result) => {
console.log("Photo captured:", result.width, "x", result.height);
});
camera.on("error", (error) => {
console.error(error.code, error.message);
});
// Subscribe once (auto-unsubscribes after first emit)
camera.once("ready", () => {
console.log("Camera is ready!");
});
// Unsubscribe using the returned function
const unsubscribe = camera.on("start", () => console.log("Started"));
unsubscribe(); // removes the listener
// Or use off() with a named function
function onStateChange(state) {
console.log("State:", state);
}
camera.on("stateChange", onStateChange);
camera.off("stateChange", onStateChange); // removes the listenerAvailable Events
| Event | Payload | Description |
|-------|---------|-------------|
| ready | - | Camera initialized |
| start | - | Stream started |
| stop | - | Stream stopped |
| pause | - | Stream paused |
| resume | - | Stream resumed |
| capture | CaptureResult | Photo captured |
| error | CameraError | Error occurred |
| stateChange | CameraState | State changed |
| destroy | - | Camera destroyed |
CaptureResult
interface CaptureResult {
dataUrl: string; // Base64 data URL
blob: Blob; // Image blob
width: number; // Image width
height: number; // Image height
timestamp: number; // Capture timestamp
}CameraError
interface CameraError {
code: "NOT_ALLOWED" | "NOT_FOUND" | "NOT_READABLE" | "OVERCONSTRAINED" | "UNKNOWN";
message: string;
originalError?: Error;
}Error Codes
| Code | Cause | Typical Resolution |
|------|-------|-------------------|
| NOT_ALLOWED | User denied camera permission, or page is not served over HTTPS | Prompt user to grant permission in browser settings, or serve page over HTTPS |
| NOT_FOUND | No camera device available on the system | Inform user that a camera is required |
| NOT_READABLE | Camera is already in use by another application or browser tab | Ask user to close other apps using the camera |
| OVERCONSTRAINED | Requested resolution or facing mode not supported by the camera | Use lower resolution or remove facingMode constraint |
| UNKNOWN | Unexpected error not matching known categories | Check originalError for details, display generic error message |
Camera States
The camera transitions through these states:
idle- Initial state, not streaminginitializing- Requesting camera accessstreaming- Actively streaming videopaused- Stream pausederror- An error occurreddestroyed- Component destroyed
Browser Support
Requires browsers with MediaDevices.getUserMedia() support (all modern browsers).
License
MIT
