capacitor-camera-view 1.0.4 → 1.1.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/Package.swift +1 -1
- package/README.md +25 -15
- package/android/src/main/java/com/michaelwolz/capacitorcameraview/CameraView.kt +112 -43
- package/android/src/main/java/com/michaelwolz/capacitorcameraview/CameraViewPlugin.kt +8 -6
- package/dist/docs.json +56 -26
- package/dist/esm/definitions.d.ts +34 -15
- package/dist/esm/definitions.js.map +1 -1
- package/dist/esm/web.d.ts +3 -7
- package/dist/esm/web.js +18 -2
- package/dist/esm/web.js.map +1 -1
- package/dist/plugin.cjs.js +18 -2
- package/dist/plugin.cjs.js.map +1 -1
- package/dist/plugin.js +18 -2
- package/dist/plugin.js.map +1 -1
- package/ios/Sources/CameraViewPlugin/CameraSessionConfiguration.swift +1 -1
- package/ios/Sources/CameraViewPlugin/CameraViewManager+BarcodeScan.swift +5 -5
- package/ios/Sources/CameraViewPlugin/CameraViewManager+PhotoCapture.swift +0 -1
- package/ios/Sources/CameraViewPlugin/CameraViewManager.swift +11 -12
- package/ios/Sources/CameraViewPlugin/CameraViewPlugin.swift +53 -15
- package/ios/Sources/CameraViewPlugin/Utils.swift +8 -0
- package/package.json +11 -10
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"definitions.js","sourceRoot":"","sources":["../../src/definitions.ts"],"names":[],"mappings":"","sourcesContent":["import type { PermissionState, PluginListenerHandle } from '@capacitor/core';\n\n/**\n * Main plugin interface for Capacitor Camera View functionality.\n *\n * @since 1.0.0\n */\nexport interface CameraViewPlugin {\n /**\n * Start the camera view with optional configuration.\n *\n * @param options - Configuration options for the camera session\n * @returns A promise that resolves when the camera has started\n *\n * @since 1.0.0\n */\n start(options?: CameraSessionConfiguration): Promise<void>;\n\n /**\n * Stop the camera view and release resources.\n *\n * @returns A promise that resolves when the camera has stopped\n *\n * @since 1.0.0\n */\n stop(): Promise<void>;\n\n /**\n * Check if the camera view is currently running.\n *\n * @returns A promise that resolves with an object containing the running state of the camera\n *\n * @since 1.0.0\n */\n isRunning(): Promise<IsRunningResponse>;\n\n /**\n * Capture a photo using the current camera configuration.\n *\n * @param options - Capture configuration options\n * @param options.quality - The JPEG quality of the captured photo on a scale of 0-100\n * @returns A promise that resolves with an object containing a base64 encoded string of the captured photo\n *\n * @since 1.0.0\n */\n capture(options: { quality: number }): Promise<CaptureResponse>;\n\n /**\n * Captures a frame from the current camera preview without using the full camera capture pipeline.\n *\n * Unlike `capture()` which may trigger hardware-level photo capture on native platforms,\n * this method quickly samples the current video stream. This is suitable computer vision or\n * simple snapshots where high fidelity is not required.\n *\n * On web this method does exactly the same as `capture()` as it only captures a frame from the video stream\n * because unfortunately [ImageCapture API](https://developer.mozilla.org/en-US/docs/Web/API/ImageCapture) is\n * not yet well supported on the web.\n *\n * @param options - Capture configuration options\n * @param options.quality - The JPEG quality of the captured sample on a scale of 0-100\n * @returns A promise that resolves with an object containing a base64 encoded string of the captured sample\n *\n * @since 1.0.0\n */\n captureSample(options: { quality: number }): Promise<CaptureResponse>;\n\n /**\n * Switch between front and back camera.\n *\n * @returns A promise that resolves when the camera has been flipped\n *\n * @since 1.0.0\n */\n flipCamera(): Promise<void>;\n\n /**\n * Get available camera devices for capturing photos.\n *\n * @returns A promise that resolves with an object containing an array of available capture devices\n *\n * @since 1.0.0\n */\n getAvailableDevices(): Promise<GetAvailableDevicesResponse>;\n\n /**\n * Get current zoom level information and available range.\n *\n * @remarks\n * Make sure the camera is properly initialized before calling this method. Otherwise, this might\n * lead to returning default values on android.\n *\n * @returns A promise that resolves with an object containing min, max and current zoom levels\n *\n * @since 1.0.0\n */\n getZoom(): Promise<GetZoomResponse>;\n\n /**\n * Set the camera zoom level.\n *\n * @param options - Zoom configuration options\n * @param options.level - The zoom level to set\n * @param options.ramp - Whether to animate the zoom level change, defaults to false (iOS only)\n * @returns A promise that resolves when the zoom level has been set\n *\n * @remarks\n * On web platforms, zoom functionality may be limited by browser support.\n * When native zoom is not available, a CSS-based zoom simulation is applied.\n *\n * @since 1.0.0\n */\n setZoom(options: { level: number; ramp?: boolean }): Promise<void>;\n\n /**\n * Get current flash mode setting.\n *\n * @returns A promise that resolves with an object containing the current flash mode\n *\n * @since 1.0.0\n */\n getFlashMode(): Promise<GetFlashModeResponse>;\n\n /**\n * Get supported flash modes for the current camera.\n *\n * @returns A promise that resolves with an object containing an array of supported flash modes\n *\n * @since 1.0.0\n */\n getSupportedFlashModes(): Promise<GetSupportedFlashModesResponse>;\n\n /**\n * Set the camera flash mode.\n *\n * @param options - Flash mode configuration options\n * @param options.mode - The flash mode to set\n * @returns A promise that resolves when the flash mode has been set\n *\n * @since 1.0.0\n */\n setFlashMode(options: { mode: FlashMode }): Promise<void>;\n\n /**\n * Check camera permission status without requesting permissions.\n *\n * @returns A promise that resolves with an object containing the camera permission status\n *\n * @since 1.0.0\n */\n checkPermissions(): Promise<PermissionStatus>;\n\n /**\n * Request camera permission from the user.\n *\n * @returns A promise that resolves with an object containing the camera permission status\n *\n * @since 1.0.0\n */\n requestPermissions(): Promise<PermissionStatus>;\n\n /**\n * Listen for barcode detection events.\n * This event is emitted when a barcode is detected in the camera preview.\n *\n * @param eventName - The name of the event to listen for ('barcodeDetected')\n * @param listenerFunc - The callback function to execute when a barcode is detected\n * @returns A promise that resolves with an event subscription\n *\n * @since 1.0.0\n */\n addListener(\n eventName: 'barcodeDetected',\n listenerFunc: (data: BarcodeDetectionData) => void,\n ): Promise<PluginListenerHandle>;\n\n /**\n * Remove all listeners for this plugin.\n *\n * @param eventName - Optional event name to remove listeners for\n * @returns A promise that resolves when the listeners are removed\n *\n * @since 1.0.0\n */\n removeAllListeners(eventName?: string): Promise<void>;\n}\n\n// ------------------------------------------------------------------------------\n// Camera Configuration Types\n// ------------------------------------------------------------------------------\n\n/**\n * Position options for the camera.\n * - 'front': Front-facing camera\n * - 'back': Rear-facing camera\n *\n * @since 1.0.0\n */\nexport type CameraPosition = 'front' | 'back';\n\n/**\n * Flash mode options for the camera.\n * - 'off': Flash disabled\n * - 'on': Flash always on\n * - 'auto': Flash automatically enabled in low-light conditions\n *\n * @since 1.0.0\n */\nexport type FlashMode = 'off' | 'on' | 'auto';\n\n/**\n * Represents a physical camera device on the device.\n *\n * @since 1.0.0\n */\nexport interface CameraDevice {\n /** The unique identifier of the camera device */\n id: string;\n\n /** The human-readable name of the camera device */\n name: string;\n\n /** The position of the camera device (front or back) */\n position: CameraPosition;\n\n /** The type of the camera device (e.g., wide, ultra-wide, telephoto) - iOS only */\n deviceType?: CameraDeviceType;\n}\n\n/**\n * Available camera device types for iOS.\n * Maps to AVCaptureDevice DeviceTypes in iOS.\n *\n * @see https://developer.apple.com/documentation/avfoundation/avcapturedevice/devicetype-swift.struct\n *\n * @since 1.0.0\n */\nexport type CameraDeviceType =\n /** builtInWideAngleCamera - standard camera */\n | 'wideAngle'\n /** builtInUltraWideCamera - 0.5x zoom level */\n | 'ultraWide'\n /** builtInTelephotoCamera - 2x/3x zoom level */\n | 'telephoto'\n /** builtInDualCamera - wide + telephoto combination */\n | 'dual'\n /** builtInDualWideCamera - wide + ultraWide combination */\n | 'dualWide'\n /** builtInTripleCamera - wide + ultraWide + telephoto */\n | 'triple'\n /** builtInTrueDepthCamera - front-facing camera with depth sensing */\n | 'trueDepth';\n\n/**\n * Configuration options for starting a camera session.\n *\n * @since 1.0.0\n */\nexport interface CameraSessionConfiguration {\n /**\n * Enables the barcode detection functionality\n * @default false\n */\n enableBarcodeDetection?: boolean;\n\n /**\n * Position of the camera to use\n * @default 'back'\n */\n position?: CameraPosition;\n\n /**\n * Specific device ID of the camera to use\n * If provided, takes precedence over position\n */\n deviceId?: string;\n\n /**\n * Whether to use the triple camera if available (iPhone Pro models only)\n * @default false\n */\n useTripleCameraIfAvailable?: boolean;\n\n /**\n * Ordered list of preferred camera device types to use (iOS only).\n * The system will attempt to use the first available camera type in the list.\n * If position is also provided, the system will use the first available camera type\n * that matches the position and is in the list.\n *\n * This will fallback to the default camera type if none of the preferred types are available.\n *\n * @example [CameraDeviceType.WideAngle, CameraDeviceType.UltraWide, CameraDeviceType.Telephoto]\n * @default undefined - system will decide based on position/deviceId\n */\n preferredCameraDeviceTypes?: CameraDeviceType[];\n\n /**\n * The initial zoom factor to use\n * @default 1.0\n */\n zoomFactor?: number;\n\n /**\n * Optional HTML ID of the container element where the camera view should be rendered.\n * If not provided, the camera view will be appended to the document body. Web only.\n * @example 'cameraContainer'\n */\n containerElementId?: string;\n}\n\n// ------------------------------------------------------------------------------\n// Response Interfaces\n// ------------------------------------------------------------------------------\n\n/**\n * Response for checking if the camera view is running.\n *\n * @since 1.0.0\n */\nexport interface IsRunningResponse {\n /** Indicates if the camera view is currently active and running */\n isRunning: boolean;\n}\n\n/**\n * Response for capturing a photo.\n *\n * @since 1.0.0\n */\nexport interface CaptureResponse {\n /** The base64 encoded string of the captured photo */\n photo: string;\n}\n\n/**\n * Response for getting available camera devices.\n *\n * @since 1.0.0\n */\nexport interface GetAvailableDevicesResponse {\n /** An array of available camera devices */\n devices: CameraDevice[];\n}\n\n/**\n * Response for getting zoom level information.\n *\n * @since 1.0.0\n */\nexport interface GetZoomResponse {\n /** The minimum zoom level supported */\n min: number;\n\n /** The maximum zoom level supported */\n max: number;\n\n /** The current zoom level */\n current: number;\n}\n\n/**\n * Response for getting the current flash mode.\n *\n * @since 1.0.0\n */\nexport interface GetFlashModeResponse {\n /** The current flash mode setting */\n flashMode: FlashMode;\n}\n\n/**\n * Response for getting supported flash modes.\n *\n * @since 1.0.0\n */\nexport interface GetSupportedFlashModesResponse {\n /** An array of flash modes supported by the current camera */\n flashModes: FlashMode[];\n}\n\n/**\n * Data for a detected barcode.\n *\n * @since 1.0.0\n */\nexport interface BarcodeDetectionData {\n /** The decoded string value of the barcode */\n value: string;\n\n /** The display value of the barcode (may differ from the raw value) */\n displayValue?: string;\n\n /** The type/format of the barcode (e.g., 'qr', 'code128', etc.) */\n type: string;\n\n /** The bounding rectangle of the barcode in the camera frame. */\n boundingRect: BoundingRect;\n}\n\n/**\n * Rectangle defining the boundary of the barcode in the camera frame.\n * Coordinates are normalized between 0 and 1 relative to the camera frame.\n *\n * @since 1.0.0\n */\nexport interface BoundingRect {\n /** X-coordinate of the top-left corner */\n x: number;\n /** Y-coordinate of the top-left corner */\n y: number;\n /** Width of the bounding rectangle (should match the actual width of the barcode) */\n width: number;\n /** Height of the bounding rectangle (should match the actual height of the barcode) */\n height: number;\n}\n\n/**\n * Response for the camera permission status.\n *\n * @since 1.0.0\n */\nexport interface PermissionStatus {\n /** The state of the camera permission */\n camera: PermissionState;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"definitions.js","sourceRoot":"","sources":["../../src/definitions.ts"],"names":[],"mappings":"","sourcesContent":["import type { PermissionState, PluginListenerHandle } from '@capacitor/core';\n\n/**\n * Main plugin interface for Capacitor Camera View functionality.\n *\n * @since 1.0.0\n */\nexport interface CameraViewPlugin {\n /**\n * Start the camera view with optional configuration.\n *\n * @param options - Configuration options for the camera session\n * @returns A promise that resolves when the camera has started\n *\n * @since 1.0.0\n */\n start(options?: CameraSessionConfiguration): Promise<void>;\n\n /**\n * Stop the camera view and release resources.\n *\n * @returns A promise that resolves when the camera has stopped\n *\n * @since 1.0.0\n */\n stop(): Promise<void>;\n\n /**\n * Check if the camera view is currently running.\n *\n * @returns A promise that resolves with an object containing the running state of the camera\n *\n * @since 1.0.0\n */\n isRunning(): Promise<IsRunningResponse>;\n\n /**\n * Capture a photo using the current camera configuration.\n *\n * @param options - Capture configuration options\n * @returns A promise that resolves with an object containing either a base64 encoded string or file path of the captured photo\n *\n * @since 1.0.0\n */\n capture<T extends CaptureOptions>(options: T): Promise<CaptureResponse<T>>;\n\n /**\n * Captures a frame from the current camera preview without using the full camera capture pipeline.\n *\n * Unlike `capture()` which may trigger hardware-level photo capture on native platforms,\n * this method quickly samples the current video stream. This is suitable computer vision or\n * simple snapshots where high fidelity is not required.\n *\n * On web this method does exactly the same as `capture()` as it only captures a frame from the video stream\n * because unfortunately [ImageCapture API](https://developer.mozilla.org/en-US/docs/Web/API/ImageCapture) is\n * not yet well supported on the web.\n *\n * @param options - Capture configuration options\n * @returns A promise that resolves with an object containing either a base64 encoded string or file path of the captured sample\n *\n * @since 1.0.0\n */\n captureSample<T extends CaptureOptions>(options: T): Promise<CaptureResponse<T>>;\n\n /**\n * Switch between front and back camera.\n *\n * @returns A promise that resolves when the camera has been flipped\n *\n * @since 1.0.0\n */\n flipCamera(): Promise<void>;\n\n /**\n * Get available camera devices for capturing photos.\n *\n * @returns A promise that resolves with an object containing an array of available capture devices\n *\n * @since 1.0.0\n */\n getAvailableDevices(): Promise<GetAvailableDevicesResponse>;\n\n /**\n * Get current zoom level information and available range.\n *\n * @remarks\n * Make sure the camera is properly initialized before calling this method. Otherwise, this might\n * lead to returning default values on android.\n *\n * @returns A promise that resolves with an object containing min, max and current zoom levels\n *\n * @since 1.0.0\n */\n getZoom(): Promise<GetZoomResponse>;\n\n /**\n * Set the camera zoom level.\n *\n * @param options - Zoom configuration options\n * @param options.level - The zoom level to set\n * @param options.ramp - Whether to animate the zoom level change, defaults to false (iOS only)\n * @returns A promise that resolves when the zoom level has been set\n *\n * @remarks\n * On web platforms, zoom functionality may be limited by browser support.\n * When native zoom is not available, a CSS-based zoom simulation is applied.\n *\n * @since 1.0.0\n */\n setZoom(options: { level: number; ramp?: boolean }): Promise<void>;\n\n /**\n * Get current flash mode setting.\n *\n * @returns A promise that resolves with an object containing the current flash mode\n *\n * @since 1.0.0\n */\n getFlashMode(): Promise<GetFlashModeResponse>;\n\n /**\n * Get supported flash modes for the current camera.\n *\n * @returns A promise that resolves with an object containing an array of supported flash modes\n *\n * @since 1.0.0\n */\n getSupportedFlashModes(): Promise<GetSupportedFlashModesResponse>;\n\n /**\n * Set the camera flash mode.\n *\n * @param options - Flash mode configuration options\n * @param options.mode - The flash mode to set\n * @returns A promise that resolves when the flash mode has been set\n *\n * @since 1.0.0\n */\n setFlashMode(options: { mode: FlashMode }): Promise<void>;\n\n /**\n * Check camera permission status without requesting permissions.\n *\n * @returns A promise that resolves with an object containing the camera permission status\n *\n * @since 1.0.0\n */\n checkPermissions(): Promise<PermissionStatus>;\n\n /**\n * Request camera permission from the user.\n *\n * @returns A promise that resolves with an object containing the camera permission status\n *\n * @since 1.0.0\n */\n requestPermissions(): Promise<PermissionStatus>;\n\n /**\n * Listen for barcode detection events.\n * This event is emitted when a barcode is detected in the camera preview.\n *\n * @param eventName - The name of the event to listen for ('barcodeDetected')\n * @param listenerFunc - The callback function to execute when a barcode is detected\n * @returns A promise that resolves with an event subscription\n *\n * @since 1.0.0\n */\n addListener(\n eventName: 'barcodeDetected',\n listenerFunc: (data: BarcodeDetectionData) => void,\n ): Promise<PluginListenerHandle>;\n\n /**\n * Remove all listeners for this plugin.\n *\n * @param eventName - Optional event name to remove listeners for\n * @returns A promise that resolves when the listeners are removed\n *\n * @since 1.0.0\n */\n removeAllListeners(eventName?: string): Promise<void>;\n}\n\n// ------------------------------------------------------------------------------\n// Camera Configuration Types\n// ------------------------------------------------------------------------------\n\n/**\n * Position options for the camera.\n * - 'front': Front-facing camera\n * - 'back': Rear-facing camera\n *\n * @since 1.0.0\n */\nexport type CameraPosition = 'front' | 'back';\n\n/**\n * Flash mode options for the camera.\n * - 'off': Flash disabled\n * - 'on': Flash always on\n * - 'auto': Flash automatically enabled in low-light conditions\n *\n * @since 1.0.0\n */\nexport type FlashMode = 'off' | 'on' | 'auto';\n\n/**\n * Represents a physical camera device on the device.\n *\n * @since 1.0.0\n */\nexport interface CameraDevice {\n /** The unique identifier of the camera device */\n id: string;\n\n /** The human-readable name of the camera device */\n name: string;\n\n /** The position of the camera device (front or back) */\n position: CameraPosition;\n\n /** The type of the camera device (e.g., wide, ultra-wide, telephoto) - iOS only */\n deviceType?: CameraDeviceType;\n}\n\n/**\n * Available camera device types for iOS.\n * Maps to AVCaptureDevice DeviceTypes in iOS.\n *\n * @see https://developer.apple.com/documentation/avfoundation/avcapturedevice/devicetype-swift.struct\n *\n * @since 1.0.0\n */\nexport type CameraDeviceType =\n /** builtInWideAngleCamera - standard camera */\n | 'wideAngle'\n /** builtInUltraWideCamera - 0.5x zoom level */\n | 'ultraWide'\n /** builtInTelephotoCamera - 2x/3x zoom level */\n | 'telephoto'\n /** builtInDualCamera - wide + telephoto combination */\n | 'dual'\n /** builtInDualWideCamera - wide + ultraWide combination */\n | 'dualWide'\n /** builtInTripleCamera - wide + ultraWide + telephoto */\n | 'triple'\n /** builtInTrueDepthCamera - front-facing camera with depth sensing */\n | 'trueDepth';\n\n/**\n * Configuration options for starting a camera session.\n *\n * @since 1.0.0\n */\nexport interface CameraSessionConfiguration {\n /**\n * Enables the barcode detection functionality\n * @default false\n */\n enableBarcodeDetection?: boolean;\n\n /**\n * Position of the camera to use\n * @default 'back'\n */\n position?: CameraPosition;\n\n /**\n * Specific device ID of the camera to use\n * If provided, takes precedence over position\n */\n deviceId?: string;\n\n /**\n * Whether to use the triple camera if available (iPhone Pro models only)\n * @default false\n */\n useTripleCameraIfAvailable?: boolean;\n\n /**\n * Ordered list of preferred camera device types to use (iOS only).\n * The system will attempt to use the first available camera type in the list.\n * If position is also provided, the system will use the first available camera type\n * that matches the position and is in the list.\n *\n * This will fallback to the default camera type if none of the preferred types are available.\n *\n * @example [CameraDeviceType.WideAngle, CameraDeviceType.UltraWide, CameraDeviceType.Telephoto]\n * @default undefined - system will decide based on position/deviceId\n */\n preferredCameraDeviceTypes?: CameraDeviceType[];\n\n /**\n * The initial zoom factor to use\n * @default 1.0\n */\n zoomFactor?: number;\n\n /**\n * Optional HTML ID of the container element where the camera view should be rendered.\n * If not provided, the camera view will be appended to the document body. Web only.\n * @example 'cameraContainer'\n */\n containerElementId?: string;\n}\n\n/**\n * Configuration options for capturing photos and samples.\n *\n * @since 1.1.0\n */\nexport interface CaptureOptions {\n /**\n * The JPEG quality of the captured photo/sample on a scale of 0-100\n * @since 1.1.0\n */\n quality: number;\n\n /**\n * If true, saves to a temporary file and returns the web path instead of base64.\n * The web path can be used to set the src attribute of an image for efficient loading and rendering.\n * This reduces the data that needs to be transferred over the bridge, which can improve performance\n * especially for high-resolution images.\n * @default false\n * @since 1.1.0\n */\n saveToFile?: boolean;\n}\n\n// ------------------------------------------------------------------------------\n// Response Interfaces\n// ------------------------------------------------------------------------------\n\n/**\n * Response for checking if the camera view is running.\n *\n * @since 1.0.0\n */\nexport interface IsRunningResponse {\n /** Indicates if the camera view is currently active and running */\n isRunning: boolean;\n}\n\n/**\n * Response for capturing a photo\n * This will contain either a base64 encoded string or a web path to the captured photo,\n * depending on the `saveToFile` option in the CaptureOptions.\n * @since 1.0.0\n */\nexport type CaptureResponse<T extends CaptureOptions = CaptureOptions> = T['saveToFile'] extends true\n ? {\n /** The web path to the captured photo that can be used to set the src attribute of an image for efficient loading and rendering (when saveToFile is true) */\n webPath: string;\n }\n : {\n /** The base64 encoded string of the captured photo (when saveToFile is false or undefined) */\n photo: string;\n };\n\n/**\n * Response for getting available camera devices.\n *\n * @since 1.0.0\n */\nexport interface GetAvailableDevicesResponse {\n /** An array of available camera devices */\n devices: CameraDevice[];\n}\n\n/**\n * Response for getting zoom level information.\n *\n * @since 1.0.0\n */\nexport interface GetZoomResponse {\n /** The minimum zoom level supported */\n min: number;\n\n /** The maximum zoom level supported */\n max: number;\n\n /** The current zoom level */\n current: number;\n}\n\n/**\n * Response for getting the current flash mode.\n *\n * @since 1.0.0\n */\nexport interface GetFlashModeResponse {\n /** The current flash mode setting */\n flashMode: FlashMode;\n}\n\n/**\n * Response for getting supported flash modes.\n *\n * @since 1.0.0\n */\nexport interface GetSupportedFlashModesResponse {\n /** An array of flash modes supported by the current camera */\n flashModes: FlashMode[];\n}\n\n/**\n * Data for a detected barcode.\n *\n * @since 1.0.0\n */\nexport interface BarcodeDetectionData {\n /** The decoded string value of the barcode */\n value: string;\n\n /** The display value of the barcode (may differ from the raw value) */\n displayValue?: string;\n\n /** The type/format of the barcode (e.g., 'qr', 'code128', etc.) */\n type: string;\n\n /** The bounding rectangle of the barcode in the camera frame. */\n boundingRect: BoundingRect;\n}\n\n/**\n * Rectangle defining the boundary of the barcode in the camera frame.\n * Coordinates are normalized between 0 and 1 relative to the camera frame.\n *\n * @since 1.0.0\n */\nexport interface BoundingRect {\n /** X-coordinate of the top-left corner */\n x: number;\n /** Y-coordinate of the top-left corner */\n y: number;\n /** Width of the bounding rectangle (should match the actual width of the barcode) */\n width: number;\n /** Height of the bounding rectangle (should match the actual height of the barcode) */\n height: number;\n}\n\n/**\n * Response for the camera permission status.\n *\n * @since 1.0.0\n */\nexport interface PermissionStatus {\n /** The state of the camera permission */\n camera: PermissionState;\n}\n"]}
|
package/dist/esm/web.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { WebPlugin } from '@capacitor/core';
|
|
2
|
-
import type { CameraSessionConfiguration, CameraViewPlugin, GetAvailableDevicesResponse, GetFlashModeResponse, GetSupportedFlashModesResponse, GetZoomResponse, IsRunningResponse, PermissionStatus, CaptureResponse, FlashMode } from './definitions';
|
|
2
|
+
import type { CameraSessionConfiguration, CameraViewPlugin, GetAvailableDevicesResponse, GetFlashModeResponse, GetSupportedFlashModesResponse, GetZoomResponse, IsRunningResponse, PermissionStatus, CaptureResponse, FlashMode, CaptureOptions } from './definitions';
|
|
3
3
|
/**
|
|
4
4
|
* Web implementation of the CameraViewPlugin.
|
|
5
5
|
* Optimized for performance and battery efficiency.
|
|
@@ -31,15 +31,11 @@ export declare class CameraViewWeb extends WebPlugin implements CameraViewPlugin
|
|
|
31
31
|
* Capture a photo using the camera and return it as a base64-encoded JPEG image.
|
|
32
32
|
* Preserves what the user actually sees in the UI, including cropping from object-fit: cover.
|
|
33
33
|
*/
|
|
34
|
-
capture(options:
|
|
35
|
-
quality: number;
|
|
36
|
-
}): Promise<CaptureResponse>;
|
|
34
|
+
capture<T extends CaptureOptions>(options: T): Promise<CaptureResponse<T>>;
|
|
37
35
|
/**
|
|
38
36
|
* Web implementation already uses images from the video stream, so this is the same as `capture()`
|
|
39
37
|
*/
|
|
40
|
-
captureSample(options:
|
|
41
|
-
quality: number;
|
|
42
|
-
}): Promise<CaptureResponse>;
|
|
38
|
+
captureSample<T extends CaptureOptions>(options: T): Promise<CaptureResponse<T>>;
|
|
43
39
|
/**
|
|
44
40
|
* Flip between front and back camera
|
|
45
41
|
*/
|
package/dist/esm/web.js
CHANGED
|
@@ -128,8 +128,24 @@ export class CameraViewWeb extends WebPlugin {
|
|
|
128
128
|
const visibleArea = calculateVisibleArea(videoElement);
|
|
129
129
|
drawVisibleAreaToCanvas(canvas, videoElement, visibleArea);
|
|
130
130
|
const quality = Math.min(1.0, Math.max(0.1, options.quality / 100));
|
|
131
|
-
|
|
132
|
-
|
|
131
|
+
if (options.saveToFile) {
|
|
132
|
+
// Create a blob from canvas and return a blob URL
|
|
133
|
+
return new Promise((resolve, reject) => {
|
|
134
|
+
canvas.toBlob((blob) => {
|
|
135
|
+
if (!blob) {
|
|
136
|
+
reject(new Error('Failed to create blob from canvas'));
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
const url = URL.createObjectURL(blob);
|
|
140
|
+
resolve({ webPath: url });
|
|
141
|
+
}, 'image/jpeg', quality);
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
else {
|
|
145
|
+
// Return base64 data
|
|
146
|
+
const base64Data = canvasToBase64(canvas, quality);
|
|
147
|
+
return { photo: base64Data };
|
|
148
|
+
}
|
|
133
149
|
}
|
|
134
150
|
catch (err) {
|
|
135
151
|
throw new Error(`Failed to capture photo: ${this.formatError(err)}`);
|
package/dist/esm/web.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"web.js","sourceRoot":"","sources":["../../src/web.ts"],"names":[],"mappings":"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","sourcesContent":["import { WebPlugin } from '@capacitor/core';\n\nimport type {\n CameraSessionConfiguration,\n CameraViewPlugin,\n GetAvailableDevicesResponse,\n GetFlashModeResponse,\n GetSupportedFlashModesResponse,\n GetZoomResponse,\n IsRunningResponse,\n PermissionStatus,\n CaptureResponse,\n FlashMode,\n} from './definitions';\nimport { calculateVisibleArea, canvasToBase64, drawVisibleAreaToCanvas, transformBarcodeBoundingBox } from './utils';\n\n/**\n * Web implementation of the CameraViewPlugin.\n * Optimized for performance and battery efficiency.\n */\nexport class CameraViewWeb extends WebPlugin implements CameraViewPlugin {\n // DOM elements\n private videoElement: HTMLVideoElement | null = null;\n private canvasElement: HTMLCanvasElement | null = null;\n\n // Stream state\n private stream: MediaStream | null = null;\n #isRunning = false;\n\n // Configuration state\n private currentCamera = 'environment'; // Default to back camera\n private currentZoom = 1.0;\n private currentFlashMode: FlashMode = 'off';\n\n // Barcode detection support\n private barcodeDetectionSupported = false;\n private barcodeDetector: BarcodeDetector | null = null;\n\n constructor() {\n super();\n this.checkBarcodeDetectionSupport();\n }\n\n /**\n * Start the camera with the given configuration\n */\n async start(options?: CameraSessionConfiguration): Promise<void> {\n if (this.#isRunning) {\n return;\n }\n\n const permissionStatus = await this.requestPermissions();\n if (permissionStatus.camera !== 'granted') {\n throw new Error('Camera permission was not granted');\n }\n\n try {\n // Set up video element if it doesn't exist\n if (!this.videoElement) {\n await this.setupVideoElement(options?.containerElementId);\n }\n\n // Set up video constraints based on options\n const videoConstraints: MediaTrackConstraints = {};\n\n // Prefer deviceId if specified\n if (options?.deviceId) {\n videoConstraints.deviceId = { exact: options.deviceId };\n // Remember the current camera mode (though we're using a specific device)\n this.currentCamera = options?.position === 'front' ? 'user' : 'environment';\n } else {\n // Fall back to facing mode\n const facingMode = options?.position === 'front' ? 'user' : 'environment';\n this.currentCamera = facingMode;\n videoConstraints.facingMode = facingMode;\n }\n\n const constraints: MediaStreamConstraints = {\n video: videoConstraints,\n audio: false,\n };\n\n this.stream = await navigator.mediaDevices.getUserMedia(constraints);\n\n if (this.videoElement) {\n this.videoElement.srcObject = this.stream;\n this.videoElement.play();\n this.#isRunning = true;\n\n // If barcode detection is enabled and supported, start detection\n if (options?.enableBarcodeDetection && this.barcodeDetectionSupported) {\n this.startBarcodeDetection();\n }\n }\n } catch (err) {\n throw new Error(`Failed to start camera: ${this.formatError(err)}`);\n }\n }\n\n /**\n * Stop the camera and release resources\n */\n async stop(): Promise<void> {\n if (!this.#isRunning) {\n return;\n }\n\n try {\n // Stop all tracks in the stream\n if (this.stream) {\n this.stream.getTracks().forEach((track) => track.stop());\n this.stream = null;\n }\n\n // Clear video source\n if (this.videoElement) {\n this.videoElement = null;\n }\n\n this.#isRunning = false;\n } catch (err) {\n throw new Error(`Failed to stop camera: ${this.formatError(err)}`);\n }\n }\n\n /**\n * Check if the camera is currently running\n */\n async isRunning(): Promise<IsRunningResponse> {\n return { isRunning: this.#isRunning };\n }\n\n /**\n * Capture a photo using the camera and return it as a base64-encoded JPEG image.\n * Preserves what the user actually sees in the UI, including cropping from object-fit: cover.\n */\n async capture(options: { quality: number }): Promise<CaptureResponse> {\n const videoElement = this.videoElement;\n\n if (!this.#isRunning || !videoElement) {\n throw new Error('Camera is not running');\n }\n\n try {\n const canvas = this.getCanvasElement();\n const visibleArea = calculateVisibleArea(videoElement);\n\n drawVisibleAreaToCanvas(canvas, videoElement, visibleArea);\n\n const quality = Math.min(1.0, Math.max(0.1, options.quality / 100));\n const base64Data = canvasToBase64(canvas, quality);\n\n return { photo: base64Data };\n } catch (err) {\n throw new Error(`Failed to capture photo: ${this.formatError(err)}`);\n }\n }\n\n /**\n * Web implementation already uses images from the video stream, so this is the same as `capture()`\n */\n async captureSample(options: { quality: number }): Promise<CaptureResponse> {\n return this.capture(options);\n }\n\n /**\n * Flip between front and back camera\n */\n public async flipCamera(): Promise<void> {\n if (!this.#isRunning) {\n throw new Error('Camera is not running');\n }\n\n try {\n // Switch current camera\n this.currentCamera = this.currentCamera === 'user' ? 'environment' : 'user';\n\n // Stop current stream\n if (this.stream) {\n this.stream.getTracks().forEach((track) => track.stop());\n }\n\n // Restart with new facing mode\n const constraints: MediaStreamConstraints = {\n video: {\n facingMode: this.currentCamera,\n },\n audio: false,\n };\n\n this.stream = await navigator.mediaDevices.getUserMedia(constraints);\n\n if (this.videoElement) {\n this.videoElement.srcObject = this.stream;\n }\n } catch (err) {\n throw new Error(`Failed to flip camera: ${this.formatError(err)}`);\n }\n }\n\n /**\n * Get available camera devices\n */\n public async getAvailableDevices(): Promise<GetAvailableDevicesResponse> {\n try {\n const devices = await navigator.mediaDevices.enumerateDevices();\n const videoDevices = devices.filter((device) => device.kind === 'videoinput');\n\n return {\n devices: videoDevices.map((device) => ({\n id: device.deviceId,\n name: device.label || `Camera ${device.deviceId.substring(0, 5)}`,\n position: device.label.toLowerCase().includes('front') ? 'front' : 'back',\n })),\n };\n } catch (err) {\n console.error('Failed to get available devices', err);\n return { devices: [] };\n }\n }\n\n /**\n * Get current zoom information (web has limited zoom support)\n */\n public async getZoom(): Promise<GetZoomResponse> {\n // Web has limited zoom capabilities in most browsers,\n // we fake zoomin by scaling the video element\n return {\n min: 1.0,\n max: 3.0,\n current: this.currentZoom,\n };\n }\n\n /**\n * Set zoom level (limited support in web)\n */\n public async setZoom(options: { level: number; ramp?: boolean }): Promise<void> {\n // Store the requested zoom level\n this.currentZoom = options.level;\n\n // Apply visual zoom using CSS transform when native zoom isn't supported\n if (this.videoElement) {\n this.videoElement.style.transition = options.ramp ? 'transform 0.2s ease-in-out' : 'none';\n const scale = Math.max(1.0, Math.min(options.level, 3.0)); // Limit scale to reasonable bounds\n this.videoElement.style.transform = `scale(${scale})`;\n this.videoElement.style.transformOrigin = 'center';\n }\n }\n\n /**\n * Get current flash mode\n */\n public async getFlashMode(): Promise<GetFlashModeResponse> {\n return { flashMode: this.currentFlashMode };\n }\n\n /**\n * Get supported flash modes\n */\n public async getSupportedFlashModes(): Promise<GetSupportedFlashModesResponse> {\n // Web has limited flash control\n return { flashModes: ['off'] };\n }\n\n /**\n * Set flash mode (limited support in web)\n */\n public async setFlashMode(options: { mode: FlashMode }): Promise<void> {\n this.currentFlashMode = options.mode;\n console.warn('Flash mode control is not fully supported in the web implementation');\n }\n\n /**\n * Check camera permission without requesting\n */\n public async checkPermissions(): Promise<PermissionStatus> {\n try {\n // Use Permissions API if available\n if (navigator.permissions) {\n const result = await navigator.permissions.query({ name: 'camera' as PermissionName });\n return {\n camera: result.state === 'granted' ? 'granted' : result.state === 'denied' ? 'denied' : 'prompt',\n };\n }\n\n // If Permissions API is not available, check if we have an active stream\n return {\n camera: this.stream ? 'granted' : 'prompt',\n };\n } catch (err) {\n // If permissions API is not supported or fails\n return {\n camera: 'prompt',\n };\n }\n }\n\n /**\n * Request camera permission from the user\n */\n public async requestPermissions(): Promise<PermissionStatus> {\n try {\n // Try to access the camera to trigger the permission prompt\n const stream = await navigator.mediaDevices.getUserMedia({ video: true });\n\n // If we get here, permission was granted\n // Clean up the test stream\n stream.getTracks().forEach((track) => track.stop());\n\n return { camera: 'granted' };\n } catch (err) {\n // Permission denied or other error\n return { camera: 'denied' };\n }\n }\n\n /**\n * Start barcode detection if supported\n */\n private async startBarcodeDetection() {\n const barcodeDetector = this.barcodeDetector;\n const videoElement = this.videoElement;\n\n if (!this.barcodeDetectionSupported || !barcodeDetector || !videoElement) {\n return;\n }\n\n // Make sure video is fully loaded before starting detection\n if (videoElement.readyState < 2) {\n await new Promise<void>((resolve) => {\n const loadHandler = () => {\n videoElement.removeEventListener('loadeddata', loadHandler);\n resolve();\n };\n videoElement.addEventListener('loadeddata', loadHandler);\n });\n }\n\n // Add throttling to reduce CPU usage\n let lastDetectionTime = 0;\n const minTimeBetweenDetections = 100; // ms\n\n // Set up periodic frame analysis for barcode detection\n const detectFrame = async () => {\n if (!this.#isRunning || !videoElement || !barcodeDetector) {\n return;\n }\n\n const now = Date.now();\n if (now - lastDetectionTime >= minTimeBetweenDetections) {\n try {\n const barcodes = await barcodeDetector.detect(videoElement);\n lastDetectionTime = now;\n\n if (barcodes.length > 0) {\n const barcode = barcodes[0];\n\n // Transform barcode coordinates using the utility function\n const boundingRect = transformBarcodeBoundingBox(barcode.boundingBox, videoElement);\n\n this.notifyListeners('barcodeDetected', {\n value: barcode.rawValue,\n type: barcode.format.toLowerCase(),\n boundingRect,\n });\n }\n } catch (err) {\n console.error('Barcode detection error', err);\n }\n }\n\n if (this.#isRunning) {\n requestAnimationFrame(detectFrame);\n }\n };\n\n requestAnimationFrame(detectFrame);\n }\n\n /**\n * Clean up resources when the plugin is disposed\n */\n public async handleOnDestroy(): Promise<void> {\n await this.stop();\n\n // Remove elements from DOM\n if (this.videoElement?.parentNode) {\n this.videoElement.parentNode.removeChild(this.videoElement);\n this.videoElement = null;\n }\n\n if (this.canvasElement) {\n this.canvasElement = null;\n }\n\n this.barcodeDetector = null;\n }\n\n /**\n * Check if barcode detection is supported in this browser\n */\n private async checkBarcodeDetectionSupport() {\n if ('BarcodeDetector' in window) {\n try {\n this.barcodeDetector = new BarcodeDetector();\n this.barcodeDetectionSupported = true;\n } catch (e) {\n console.warn('BarcodeDetector is not supported by this browser.');\n this.barcodeDetectionSupported = false;\n }\n }\n }\n\n /**\n * Set up the video element for the camera view\n */\n private async setupVideoElement(containerElementId?: string) {\n this.videoElement = document.createElement('video');\n this.videoElement.playsInline = true;\n this.videoElement.autoplay = true;\n this.videoElement.muted = true;\n this.videoElement.style.width = '100%';\n this.videoElement.style.height = '100%';\n this.videoElement.style.objectFit = 'cover';\n\n // If a container ID is provided, find that element and append the video to it\n if (containerElementId) {\n const container = document.getElementById(containerElementId);\n if (!container) {\n throw new Error(`Container element with ID ${containerElementId} not found`);\n }\n container.appendChild(this.videoElement);\n } else {\n // Otherwise, append to body as fallback\n document.body.appendChild(this.videoElement);\n }\n }\n\n /**\n * Ensures canvas element exists and returns it\n */\n private getCanvasElement(): HTMLCanvasElement {\n if (!this.canvasElement) {\n this.canvasElement = document.createElement('canvas');\n }\n return this.canvasElement;\n }\n\n /**\n * Format error message\n */\n private formatError(err: unknown): string {\n return err instanceof Error ? err.message : String(err);\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"web.js","sourceRoot":"","sources":["../../src/web.ts"],"names":[],"mappings":"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","sourcesContent":["import { WebPlugin } from '@capacitor/core';\n\nimport type {\n CameraSessionConfiguration,\n CameraViewPlugin,\n GetAvailableDevicesResponse,\n GetFlashModeResponse,\n GetSupportedFlashModesResponse,\n GetZoomResponse,\n IsRunningResponse,\n PermissionStatus,\n CaptureResponse,\n FlashMode,\n CaptureOptions,\n} from './definitions';\nimport { calculateVisibleArea, canvasToBase64, drawVisibleAreaToCanvas, transformBarcodeBoundingBox } from './utils';\n\n/**\n * Web implementation of the CameraViewPlugin.\n * Optimized for performance and battery efficiency.\n */\nexport class CameraViewWeb extends WebPlugin implements CameraViewPlugin {\n // DOM elements\n private videoElement: HTMLVideoElement | null = null;\n private canvasElement: HTMLCanvasElement | null = null;\n\n // Stream state\n private stream: MediaStream | null = null;\n #isRunning = false;\n\n // Configuration state\n private currentCamera = 'environment'; // Default to back camera\n private currentZoom = 1.0;\n private currentFlashMode: FlashMode = 'off';\n\n // Barcode detection support\n private barcodeDetectionSupported = false;\n private barcodeDetector: BarcodeDetector | null = null;\n\n constructor() {\n super();\n this.checkBarcodeDetectionSupport();\n }\n\n /**\n * Start the camera with the given configuration\n */\n async start(options?: CameraSessionConfiguration): Promise<void> {\n if (this.#isRunning) {\n return;\n }\n\n const permissionStatus = await this.requestPermissions();\n if (permissionStatus.camera !== 'granted') {\n throw new Error('Camera permission was not granted');\n }\n\n try {\n // Set up video element if it doesn't exist\n if (!this.videoElement) {\n await this.setupVideoElement(options?.containerElementId);\n }\n\n // Set up video constraints based on options\n const videoConstraints: MediaTrackConstraints = {};\n\n // Prefer deviceId if specified\n if (options?.deviceId) {\n videoConstraints.deviceId = { exact: options.deviceId };\n // Remember the current camera mode (though we're using a specific device)\n this.currentCamera = options?.position === 'front' ? 'user' : 'environment';\n } else {\n // Fall back to facing mode\n const facingMode = options?.position === 'front' ? 'user' : 'environment';\n this.currentCamera = facingMode;\n videoConstraints.facingMode = facingMode;\n }\n\n const constraints: MediaStreamConstraints = {\n video: videoConstraints,\n audio: false,\n };\n\n this.stream = await navigator.mediaDevices.getUserMedia(constraints);\n\n if (this.videoElement) {\n this.videoElement.srcObject = this.stream;\n this.videoElement.play();\n this.#isRunning = true;\n\n // If barcode detection is enabled and supported, start detection\n if (options?.enableBarcodeDetection && this.barcodeDetectionSupported) {\n this.startBarcodeDetection();\n }\n }\n } catch (err) {\n throw new Error(`Failed to start camera: ${this.formatError(err)}`);\n }\n }\n\n /**\n * Stop the camera and release resources\n */\n async stop(): Promise<void> {\n if (!this.#isRunning) {\n return;\n }\n\n try {\n // Stop all tracks in the stream\n if (this.stream) {\n this.stream.getTracks().forEach((track) => track.stop());\n this.stream = null;\n }\n\n // Clear video source\n if (this.videoElement) {\n this.videoElement = null;\n }\n\n this.#isRunning = false;\n } catch (err) {\n throw new Error(`Failed to stop camera: ${this.formatError(err)}`);\n }\n }\n\n /**\n * Check if the camera is currently running\n */\n async isRunning(): Promise<IsRunningResponse> {\n return { isRunning: this.#isRunning };\n }\n\n /**\n * Capture a photo using the camera and return it as a base64-encoded JPEG image.\n * Preserves what the user actually sees in the UI, including cropping from object-fit: cover.\n */\n async capture<T extends CaptureOptions>(options: T): Promise<CaptureResponse<T>> {\n const videoElement = this.videoElement;\n\n if (!this.#isRunning || !videoElement) {\n throw new Error('Camera is not running');\n }\n\n try {\n const canvas = this.getCanvasElement();\n const visibleArea = calculateVisibleArea(videoElement);\n\n drawVisibleAreaToCanvas(canvas, videoElement, visibleArea);\n\n const quality = Math.min(1.0, Math.max(0.1, options.quality / 100));\n\n if (options.saveToFile) {\n // Create a blob from canvas and return a blob URL\n return new Promise((resolve, reject) => {\n canvas.toBlob(\n (blob) => {\n if (!blob) {\n reject(new Error('Failed to create blob from canvas'));\n return;\n }\n\n const url = URL.createObjectURL(blob);\n resolve({ webPath: url } as CaptureResponse<T>);\n },\n 'image/jpeg',\n quality,\n );\n });\n } else {\n // Return base64 data\n const base64Data = canvasToBase64(canvas, quality);\n return { photo: base64Data } as CaptureResponse<T>;\n }\n } catch (err) {\n throw new Error(`Failed to capture photo: ${this.formatError(err)}`);\n }\n }\n\n /**\n * Web implementation already uses images from the video stream, so this is the same as `capture()`\n */\n async captureSample<T extends CaptureOptions>(options: T): Promise<CaptureResponse<T>> {\n return this.capture(options);\n }\n\n /**\n * Flip between front and back camera\n */\n public async flipCamera(): Promise<void> {\n if (!this.#isRunning) {\n throw new Error('Camera is not running');\n }\n\n try {\n // Switch current camera\n this.currentCamera = this.currentCamera === 'user' ? 'environment' : 'user';\n\n // Stop current stream\n if (this.stream) {\n this.stream.getTracks().forEach((track) => track.stop());\n }\n\n // Restart with new facing mode\n const constraints: MediaStreamConstraints = {\n video: {\n facingMode: this.currentCamera,\n },\n audio: false,\n };\n\n this.stream = await navigator.mediaDevices.getUserMedia(constraints);\n\n if (this.videoElement) {\n this.videoElement.srcObject = this.stream;\n }\n } catch (err) {\n throw new Error(`Failed to flip camera: ${this.formatError(err)}`);\n }\n }\n\n /**\n * Get available camera devices\n */\n public async getAvailableDevices(): Promise<GetAvailableDevicesResponse> {\n try {\n const devices = await navigator.mediaDevices.enumerateDevices();\n const videoDevices = devices.filter((device) => device.kind === 'videoinput');\n\n return {\n devices: videoDevices.map((device) => ({\n id: device.deviceId,\n name: device.label || `Camera ${device.deviceId.substring(0, 5)}`,\n position: device.label.toLowerCase().includes('front') ? 'front' : 'back',\n })),\n };\n } catch (err) {\n console.error('Failed to get available devices', err);\n return { devices: [] };\n }\n }\n\n /**\n * Get current zoom information (web has limited zoom support)\n */\n public async getZoom(): Promise<GetZoomResponse> {\n // Web has limited zoom capabilities in most browsers,\n // we fake zoomin by scaling the video element\n return {\n min: 1.0,\n max: 3.0,\n current: this.currentZoom,\n };\n }\n\n /**\n * Set zoom level (limited support in web)\n */\n public async setZoom(options: { level: number; ramp?: boolean }): Promise<void> {\n // Store the requested zoom level\n this.currentZoom = options.level;\n\n // Apply visual zoom using CSS transform when native zoom isn't supported\n if (this.videoElement) {\n this.videoElement.style.transition = options.ramp ? 'transform 0.2s ease-in-out' : 'none';\n const scale = Math.max(1.0, Math.min(options.level, 3.0)); // Limit scale to reasonable bounds\n this.videoElement.style.transform = `scale(${scale})`;\n this.videoElement.style.transformOrigin = 'center';\n }\n }\n\n /**\n * Get current flash mode\n */\n public async getFlashMode(): Promise<GetFlashModeResponse> {\n return { flashMode: this.currentFlashMode };\n }\n\n /**\n * Get supported flash modes\n */\n public async getSupportedFlashModes(): Promise<GetSupportedFlashModesResponse> {\n // Web has limited flash control\n return { flashModes: ['off'] };\n }\n\n /**\n * Set flash mode (limited support in web)\n */\n public async setFlashMode(options: { mode: FlashMode }): Promise<void> {\n this.currentFlashMode = options.mode;\n console.warn('Flash mode control is not fully supported in the web implementation');\n }\n\n /**\n * Check camera permission without requesting\n */\n public async checkPermissions(): Promise<PermissionStatus> {\n try {\n // Use Permissions API if available\n if (navigator.permissions) {\n const result = await navigator.permissions.query({ name: 'camera' as PermissionName });\n return {\n camera: result.state === 'granted' ? 'granted' : result.state === 'denied' ? 'denied' : 'prompt',\n };\n }\n\n // If Permissions API is not available, check if we have an active stream\n return {\n camera: this.stream ? 'granted' : 'prompt',\n };\n } catch (err) {\n // If permissions API is not supported or fails\n return {\n camera: 'prompt',\n };\n }\n }\n\n /**\n * Request camera permission from the user\n */\n public async requestPermissions(): Promise<PermissionStatus> {\n try {\n // Try to access the camera to trigger the permission prompt\n const stream = await navigator.mediaDevices.getUserMedia({ video: true });\n\n // If we get here, permission was granted\n // Clean up the test stream\n stream.getTracks().forEach((track) => track.stop());\n\n return { camera: 'granted' };\n } catch (err) {\n // Permission denied or other error\n return { camera: 'denied' };\n }\n }\n\n /**\n * Start barcode detection if supported\n */\n private async startBarcodeDetection() {\n const barcodeDetector = this.barcodeDetector;\n const videoElement = this.videoElement;\n\n if (!this.barcodeDetectionSupported || !barcodeDetector || !videoElement) {\n return;\n }\n\n // Make sure video is fully loaded before starting detection\n if (videoElement.readyState < 2) {\n await new Promise<void>((resolve) => {\n const loadHandler = () => {\n videoElement.removeEventListener('loadeddata', loadHandler);\n resolve();\n };\n videoElement.addEventListener('loadeddata', loadHandler);\n });\n }\n\n // Add throttling to reduce CPU usage\n let lastDetectionTime = 0;\n const minTimeBetweenDetections = 100; // ms\n\n // Set up periodic frame analysis for barcode detection\n const detectFrame = async () => {\n if (!this.#isRunning || !videoElement || !barcodeDetector) {\n return;\n }\n\n const now = Date.now();\n if (now - lastDetectionTime >= minTimeBetweenDetections) {\n try {\n const barcodes = await barcodeDetector.detect(videoElement);\n lastDetectionTime = now;\n\n if (barcodes.length > 0) {\n const barcode = barcodes[0];\n\n // Transform barcode coordinates using the utility function\n const boundingRect = transformBarcodeBoundingBox(barcode.boundingBox, videoElement);\n\n this.notifyListeners('barcodeDetected', {\n value: barcode.rawValue,\n type: barcode.format.toLowerCase(),\n boundingRect,\n });\n }\n } catch (err) {\n console.error('Barcode detection error', err);\n }\n }\n\n if (this.#isRunning) {\n requestAnimationFrame(detectFrame);\n }\n };\n\n requestAnimationFrame(detectFrame);\n }\n\n /**\n * Clean up resources when the plugin is disposed\n */\n public async handleOnDestroy(): Promise<void> {\n await this.stop();\n\n // Remove elements from DOM\n if (this.videoElement?.parentNode) {\n this.videoElement.parentNode.removeChild(this.videoElement);\n this.videoElement = null;\n }\n\n if (this.canvasElement) {\n this.canvasElement = null;\n }\n\n this.barcodeDetector = null;\n }\n\n /**\n * Check if barcode detection is supported in this browser\n */\n private async checkBarcodeDetectionSupport() {\n if ('BarcodeDetector' in window) {\n try {\n this.barcodeDetector = new BarcodeDetector();\n this.barcodeDetectionSupported = true;\n } catch (e) {\n console.warn('BarcodeDetector is not supported by this browser.');\n this.barcodeDetectionSupported = false;\n }\n }\n }\n\n /**\n * Set up the video element for the camera view\n */\n private async setupVideoElement(containerElementId?: string) {\n this.videoElement = document.createElement('video');\n this.videoElement.playsInline = true;\n this.videoElement.autoplay = true;\n this.videoElement.muted = true;\n this.videoElement.style.width = '100%';\n this.videoElement.style.height = '100%';\n this.videoElement.style.objectFit = 'cover';\n\n // If a container ID is provided, find that element and append the video to it\n if (containerElementId) {\n const container = document.getElementById(containerElementId);\n if (!container) {\n throw new Error(`Container element with ID ${containerElementId} not found`);\n }\n container.appendChild(this.videoElement);\n } else {\n // Otherwise, append to body as fallback\n document.body.appendChild(this.videoElement);\n }\n }\n\n /**\n * Ensures canvas element exists and returns it\n */\n private getCanvasElement(): HTMLCanvasElement {\n if (!this.canvasElement) {\n this.canvasElement = document.createElement('canvas');\n }\n return this.canvasElement;\n }\n\n /**\n * Format error message\n */\n private formatError(err: unknown): string {\n return err instanceof Error ? err.message : String(err);\n }\n}\n"]}
|
package/dist/plugin.cjs.js
CHANGED
|
@@ -245,8 +245,24 @@ class CameraViewWeb extends core.WebPlugin {
|
|
|
245
245
|
const visibleArea = calculateVisibleArea(videoElement);
|
|
246
246
|
drawVisibleAreaToCanvas(canvas, videoElement, visibleArea);
|
|
247
247
|
const quality = Math.min(1.0, Math.max(0.1, options.quality / 100));
|
|
248
|
-
|
|
249
|
-
|
|
248
|
+
if (options.saveToFile) {
|
|
249
|
+
// Create a blob from canvas and return a blob URL
|
|
250
|
+
return new Promise((resolve, reject) => {
|
|
251
|
+
canvas.toBlob((blob) => {
|
|
252
|
+
if (!blob) {
|
|
253
|
+
reject(new Error('Failed to create blob from canvas'));
|
|
254
|
+
return;
|
|
255
|
+
}
|
|
256
|
+
const url = URL.createObjectURL(blob);
|
|
257
|
+
resolve({ webPath: url });
|
|
258
|
+
}, 'image/jpeg', quality);
|
|
259
|
+
});
|
|
260
|
+
}
|
|
261
|
+
else {
|
|
262
|
+
// Return base64 data
|
|
263
|
+
const base64Data = canvasToBase64(canvas, quality);
|
|
264
|
+
return { photo: base64Data };
|
|
265
|
+
}
|
|
250
266
|
}
|
|
251
267
|
catch (err) {
|
|
252
268
|
throw new Error(`Failed to capture photo: ${this.formatError(err)}`);
|
package/dist/plugin.cjs.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.cjs.js","sources":["esm/index.js","esm/utils.js","esm/web.js"],"sourcesContent":["import { registerPlugin } from '@capacitor/core';\n/**\n * The main Capacitor Camera View plugin instance.\n */\nconst CameraView = registerPlugin('CameraView', {\n web: () => import('./web').then((m) => new m.CameraViewWeb()),\n});\nexport * from './definitions';\nexport { CameraView };\n//# sourceMappingURL=index.js.map","/**\n * Converts canvas to base64 string\n */\nexport function canvasToBase64(canvas, quality) {\n const dataUrl = canvas.toDataURL('image/jpeg', quality);\n return dataUrl.split(',')[1];\n}\n/**\n * Calculates the visible area of the video based on object-fit: cover\n */\nexport function calculateVisibleArea(video) {\n // Get the displayed dimensions of the video element\n const videoRect = video.getBoundingClientRect();\n const displayWidth = videoRect.width;\n const displayHeight = videoRect.height;\n // Get the intrinsic dimensions of the video\n const videoWidth = video.videoWidth;\n const videoHeight = video.videoHeight;\n // Calculate which portion of the video is visible (for object-fit: cover)\n const videoAspect = videoWidth / videoHeight;\n const displayAspect = displayWidth / displayHeight;\n let sourceX = 0;\n let sourceY = 0;\n let sourceWidth = videoWidth;\n let sourceHeight = videoHeight;\n // If video aspect ratio is greater than display aspect ratio,\n // the video is cropped on the sides\n if (videoAspect > displayAspect) {\n sourceWidth = videoHeight * displayAspect;\n sourceX = (videoWidth - sourceWidth) / 2;\n }\n // Otherwise the video is cropped on the top and bottom\n else {\n sourceHeight = videoWidth / displayAspect;\n sourceY = (videoHeight - sourceHeight) / 2;\n }\n return {\n sourceX,\n sourceY,\n sourceWidth,\n sourceHeight,\n displayWidth,\n displayHeight,\n };\n}\n/**\n * Draws the visible area of the video to the canvas\n */\nexport function drawVisibleAreaToCanvas(canvas, videoElement, area) {\n const { sourceX, sourceY, sourceWidth, sourceHeight, displayWidth, displayHeight } = area;\n // Set canvas size to match the displayed dimensions\n canvas.width = displayWidth;\n canvas.height = displayHeight;\n const ctx = canvas.getContext('2d', { alpha: false });\n if (!ctx) {\n throw new Error('Could not get canvas context');\n }\n // Draw only the visible portion of the video to match what the user sees\n ctx.drawImage(videoElement, sourceX, sourceY, sourceWidth, sourceHeight, 0, 0, displayWidth, displayHeight);\n}\n/**\n * Transforms barcode coordinates from the video source space to display space\n * accounting for object-fit: cover scaling and cropping.\n *\n * @param barcodeBoundingBox The original barcode bounding box from the detector\n * @param videoElement The video element with the camera stream\n * @returns The transformed bounding box coordinates in display space\n */\nexport function transformBarcodeBoundingBox(barcodeBoundingBox, videoElement) {\n // Get the video element's displayed dimensions\n const videoRect = videoElement.getBoundingClientRect();\n const displayWidth = videoRect.width;\n const displayHeight = videoRect.height;\n // Get original video dimensions\n const videoWidth = videoElement.videoWidth;\n const videoHeight = videoElement.videoHeight;\n // Calculate scaling and positioning for object-fit: cover\n const videoAspect = videoWidth / videoHeight;\n const displayAspect = displayWidth / displayHeight;\n let scaledX, scaledY, scaledWidth, scaledHeight;\n if (videoAspect > displayAspect) {\n // Video is wider than display area - height matches, width is centered and cropped\n const scale = displayHeight / videoHeight;\n const scaledVideoWidth = videoWidth * scale;\n const cropX = (scaledVideoWidth - displayWidth) / 2;\n scaledWidth = barcodeBoundingBox.width * scale;\n scaledHeight = barcodeBoundingBox.height * scale;\n scaledX = barcodeBoundingBox.x * scale - cropX;\n scaledY = barcodeBoundingBox.y * scale;\n }\n else {\n // Video is taller than display area - width matches, height is centered and cropped\n const scale = displayWidth / videoWidth;\n const scaledVideoHeight = videoHeight * scale;\n const cropY = (scaledVideoHeight - displayHeight) / 2;\n scaledWidth = barcodeBoundingBox.width * scale;\n scaledHeight = barcodeBoundingBox.height * scale;\n scaledX = barcodeBoundingBox.x * scale;\n scaledY = barcodeBoundingBox.y * scale - cropY;\n }\n return {\n x: scaledX,\n y: scaledY,\n width: scaledWidth,\n height: scaledHeight,\n };\n}\n//# sourceMappingURL=utils.js.map","var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, privateMap) {\n if (!privateMap.has(receiver)) {\n throw new TypeError(\"attempted to get private field on non-instance\");\n }\n return privateMap.get(receiver);\n};\nvar __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, privateMap, value) {\n if (!privateMap.has(receiver)) {\n throw new TypeError(\"attempted to set private field on non-instance\");\n }\n privateMap.set(receiver, value);\n return value;\n};\nvar _isRunning;\nimport { WebPlugin } from '@capacitor/core';\nimport { calculateVisibleArea, canvasToBase64, drawVisibleAreaToCanvas, transformBarcodeBoundingBox } from './utils';\n/**\n * Web implementation of the CameraViewPlugin.\n * Optimized for performance and battery efficiency.\n */\nexport class CameraViewWeb extends WebPlugin {\n constructor() {\n super();\n // DOM elements\n this.videoElement = null;\n this.canvasElement = null;\n // Stream state\n this.stream = null;\n _isRunning.set(this, false);\n // Configuration state\n this.currentCamera = 'environment'; // Default to back camera\n this.currentZoom = 1.0;\n this.currentFlashMode = 'off';\n // Barcode detection support\n this.barcodeDetectionSupported = false;\n this.barcodeDetector = null;\n this.checkBarcodeDetectionSupport();\n }\n /**\n * Start the camera with the given configuration\n */\n async start(options) {\n if (__classPrivateFieldGet(this, _isRunning)) {\n return;\n }\n const permissionStatus = await this.requestPermissions();\n if (permissionStatus.camera !== 'granted') {\n throw new Error('Camera permission was not granted');\n }\n try {\n // Set up video element if it doesn't exist\n if (!this.videoElement) {\n await this.setupVideoElement(options === null || options === void 0 ? void 0 : options.containerElementId);\n }\n // Set up video constraints based on options\n const videoConstraints = {};\n // Prefer deviceId if specified\n if (options === null || options === void 0 ? void 0 : options.deviceId) {\n videoConstraints.deviceId = { exact: options.deviceId };\n // Remember the current camera mode (though we're using a specific device)\n this.currentCamera = (options === null || options === void 0 ? void 0 : options.position) === 'front' ? 'user' : 'environment';\n }\n else {\n // Fall back to facing mode\n const facingMode = (options === null || options === void 0 ? void 0 : options.position) === 'front' ? 'user' : 'environment';\n this.currentCamera = facingMode;\n videoConstraints.facingMode = facingMode;\n }\n const constraints = {\n video: videoConstraints,\n audio: false,\n };\n this.stream = await navigator.mediaDevices.getUserMedia(constraints);\n if (this.videoElement) {\n this.videoElement.srcObject = this.stream;\n this.videoElement.play();\n __classPrivateFieldSet(this, _isRunning, true);\n // If barcode detection is enabled and supported, start detection\n if ((options === null || options === void 0 ? void 0 : options.enableBarcodeDetection) && this.barcodeDetectionSupported) {\n this.startBarcodeDetection();\n }\n }\n }\n catch (err) {\n throw new Error(`Failed to start camera: ${this.formatError(err)}`);\n }\n }\n /**\n * Stop the camera and release resources\n */\n async stop() {\n if (!__classPrivateFieldGet(this, _isRunning)) {\n return;\n }\n try {\n // Stop all tracks in the stream\n if (this.stream) {\n this.stream.getTracks().forEach((track) => track.stop());\n this.stream = null;\n }\n // Clear video source\n if (this.videoElement) {\n this.videoElement = null;\n }\n __classPrivateFieldSet(this, _isRunning, false);\n }\n catch (err) {\n throw new Error(`Failed to stop camera: ${this.formatError(err)}`);\n }\n }\n /**\n * Check if the camera is currently running\n */\n async isRunning() {\n return { isRunning: __classPrivateFieldGet(this, _isRunning) };\n }\n /**\n * Capture a photo using the camera and return it as a base64-encoded JPEG image.\n * Preserves what the user actually sees in the UI, including cropping from object-fit: cover.\n */\n async capture(options) {\n const videoElement = this.videoElement;\n if (!__classPrivateFieldGet(this, _isRunning) || !videoElement) {\n throw new Error('Camera is not running');\n }\n try {\n const canvas = this.getCanvasElement();\n const visibleArea = calculateVisibleArea(videoElement);\n drawVisibleAreaToCanvas(canvas, videoElement, visibleArea);\n const quality = Math.min(1.0, Math.max(0.1, options.quality / 100));\n const base64Data = canvasToBase64(canvas, quality);\n return { photo: base64Data };\n }\n catch (err) {\n throw new Error(`Failed to capture photo: ${this.formatError(err)}`);\n }\n }\n /**\n * Web implementation already uses images from the video stream, so this is the same as `capture()`\n */\n async captureSample(options) {\n return this.capture(options);\n }\n /**\n * Flip between front and back camera\n */\n async flipCamera() {\n if (!__classPrivateFieldGet(this, _isRunning)) {\n throw new Error('Camera is not running');\n }\n try {\n // Switch current camera\n this.currentCamera = this.currentCamera === 'user' ? 'environment' : 'user';\n // Stop current stream\n if (this.stream) {\n this.stream.getTracks().forEach((track) => track.stop());\n }\n // Restart with new facing mode\n const constraints = {\n video: {\n facingMode: this.currentCamera,\n },\n audio: false,\n };\n this.stream = await navigator.mediaDevices.getUserMedia(constraints);\n if (this.videoElement) {\n this.videoElement.srcObject = this.stream;\n }\n }\n catch (err) {\n throw new Error(`Failed to flip camera: ${this.formatError(err)}`);\n }\n }\n /**\n * Get available camera devices\n */\n async getAvailableDevices() {\n try {\n const devices = await navigator.mediaDevices.enumerateDevices();\n const videoDevices = devices.filter((device) => device.kind === 'videoinput');\n return {\n devices: videoDevices.map((device) => ({\n id: device.deviceId,\n name: device.label || `Camera ${device.deviceId.substring(0, 5)}`,\n position: device.label.toLowerCase().includes('front') ? 'front' : 'back',\n })),\n };\n }\n catch (err) {\n console.error('Failed to get available devices', err);\n return { devices: [] };\n }\n }\n /**\n * Get current zoom information (web has limited zoom support)\n */\n async getZoom() {\n // Web has limited zoom capabilities in most browsers,\n // we fake zoomin by scaling the video element\n return {\n min: 1.0,\n max: 3.0,\n current: this.currentZoom,\n };\n }\n /**\n * Set zoom level (limited support in web)\n */\n async setZoom(options) {\n // Store the requested zoom level\n this.currentZoom = options.level;\n // Apply visual zoom using CSS transform when native zoom isn't supported\n if (this.videoElement) {\n this.videoElement.style.transition = options.ramp ? 'transform 0.2s ease-in-out' : 'none';\n const scale = Math.max(1.0, Math.min(options.level, 3.0)); // Limit scale to reasonable bounds\n this.videoElement.style.transform = `scale(${scale})`;\n this.videoElement.style.transformOrigin = 'center';\n }\n }\n /**\n * Get current flash mode\n */\n async getFlashMode() {\n return { flashMode: this.currentFlashMode };\n }\n /**\n * Get supported flash modes\n */\n async getSupportedFlashModes() {\n // Web has limited flash control\n return { flashModes: ['off'] };\n }\n /**\n * Set flash mode (limited support in web)\n */\n async setFlashMode(options) {\n this.currentFlashMode = options.mode;\n console.warn('Flash mode control is not fully supported in the web implementation');\n }\n /**\n * Check camera permission without requesting\n */\n async checkPermissions() {\n try {\n // Use Permissions API if available\n if (navigator.permissions) {\n const result = await navigator.permissions.query({ name: 'camera' });\n return {\n camera: result.state === 'granted' ? 'granted' : result.state === 'denied' ? 'denied' : 'prompt',\n };\n }\n // If Permissions API is not available, check if we have an active stream\n return {\n camera: this.stream ? 'granted' : 'prompt',\n };\n }\n catch (err) {\n // If permissions API is not supported or fails\n return {\n camera: 'prompt',\n };\n }\n }\n /**\n * Request camera permission from the user\n */\n async requestPermissions() {\n try {\n // Try to access the camera to trigger the permission prompt\n const stream = await navigator.mediaDevices.getUserMedia({ video: true });\n // If we get here, permission was granted\n // Clean up the test stream\n stream.getTracks().forEach((track) => track.stop());\n return { camera: 'granted' };\n }\n catch (err) {\n // Permission denied or other error\n return { camera: 'denied' };\n }\n }\n /**\n * Start barcode detection if supported\n */\n async startBarcodeDetection() {\n const barcodeDetector = this.barcodeDetector;\n const videoElement = this.videoElement;\n if (!this.barcodeDetectionSupported || !barcodeDetector || !videoElement) {\n return;\n }\n // Make sure video is fully loaded before starting detection\n if (videoElement.readyState < 2) {\n await new Promise((resolve) => {\n const loadHandler = () => {\n videoElement.removeEventListener('loadeddata', loadHandler);\n resolve();\n };\n videoElement.addEventListener('loadeddata', loadHandler);\n });\n }\n // Add throttling to reduce CPU usage\n let lastDetectionTime = 0;\n const minTimeBetweenDetections = 100; // ms\n // Set up periodic frame analysis for barcode detection\n const detectFrame = async () => {\n if (!__classPrivateFieldGet(this, _isRunning) || !videoElement || !barcodeDetector) {\n return;\n }\n const now = Date.now();\n if (now - lastDetectionTime >= minTimeBetweenDetections) {\n try {\n const barcodes = await barcodeDetector.detect(videoElement);\n lastDetectionTime = now;\n if (barcodes.length > 0) {\n const barcode = barcodes[0];\n // Transform barcode coordinates using the utility function\n const boundingRect = transformBarcodeBoundingBox(barcode.boundingBox, videoElement);\n this.notifyListeners('barcodeDetected', {\n value: barcode.rawValue,\n type: barcode.format.toLowerCase(),\n boundingRect,\n });\n }\n }\n catch (err) {\n console.error('Barcode detection error', err);\n }\n }\n if (__classPrivateFieldGet(this, _isRunning)) {\n requestAnimationFrame(detectFrame);\n }\n };\n requestAnimationFrame(detectFrame);\n }\n /**\n * Clean up resources when the plugin is disposed\n */\n async handleOnDestroy() {\n var _a;\n await this.stop();\n // Remove elements from DOM\n if ((_a = this.videoElement) === null || _a === void 0 ? void 0 : _a.parentNode) {\n this.videoElement.parentNode.removeChild(this.videoElement);\n this.videoElement = null;\n }\n if (this.canvasElement) {\n this.canvasElement = null;\n }\n this.barcodeDetector = null;\n }\n /**\n * Check if barcode detection is supported in this browser\n */\n async checkBarcodeDetectionSupport() {\n if ('BarcodeDetector' in window) {\n try {\n this.barcodeDetector = new BarcodeDetector();\n this.barcodeDetectionSupported = true;\n }\n catch (e) {\n console.warn('BarcodeDetector is not supported by this browser.');\n this.barcodeDetectionSupported = false;\n }\n }\n }\n /**\n * Set up the video element for the camera view\n */\n async setupVideoElement(containerElementId) {\n this.videoElement = document.createElement('video');\n this.videoElement.playsInline = true;\n this.videoElement.autoplay = true;\n this.videoElement.muted = true;\n this.videoElement.style.width = '100%';\n this.videoElement.style.height = '100%';\n this.videoElement.style.objectFit = 'cover';\n // If a container ID is provided, find that element and append the video to it\n if (containerElementId) {\n const container = document.getElementById(containerElementId);\n if (!container) {\n throw new Error(`Container element with ID ${containerElementId} not found`);\n }\n container.appendChild(this.videoElement);\n }\n else {\n // Otherwise, append to body as fallback\n document.body.appendChild(this.videoElement);\n }\n }\n /**\n * Ensures canvas element exists and returns it\n */\n getCanvasElement() {\n if (!this.canvasElement) {\n this.canvasElement = document.createElement('canvas');\n }\n return this.canvasElement;\n }\n /**\n * Format error message\n */\n formatError(err) {\n return err instanceof Error ? err.message : String(err);\n }\n}\n_isRunning = new WeakMap();\n//# sourceMappingURL=web.js.map"],"names":["registerPlugin","this","WebPlugin"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"plugin.cjs.js","sources":["esm/index.js","esm/utils.js","esm/web.js"],"sourcesContent":["import { registerPlugin } from '@capacitor/core';\n/**\n * The main Capacitor Camera View plugin instance.\n */\nconst CameraView = registerPlugin('CameraView', {\n web: () => import('./web').then((m) => new m.CameraViewWeb()),\n});\nexport * from './definitions';\nexport { CameraView };\n//# sourceMappingURL=index.js.map","/**\n * Converts canvas to base64 string\n */\nexport function canvasToBase64(canvas, quality) {\n const dataUrl = canvas.toDataURL('image/jpeg', quality);\n return dataUrl.split(',')[1];\n}\n/**\n * Calculates the visible area of the video based on object-fit: cover\n */\nexport function calculateVisibleArea(video) {\n // Get the displayed dimensions of the video element\n const videoRect = video.getBoundingClientRect();\n const displayWidth = videoRect.width;\n const displayHeight = videoRect.height;\n // Get the intrinsic dimensions of the video\n const videoWidth = video.videoWidth;\n const videoHeight = video.videoHeight;\n // Calculate which portion of the video is visible (for object-fit: cover)\n const videoAspect = videoWidth / videoHeight;\n const displayAspect = displayWidth / displayHeight;\n let sourceX = 0;\n let sourceY = 0;\n let sourceWidth = videoWidth;\n let sourceHeight = videoHeight;\n // If video aspect ratio is greater than display aspect ratio,\n // the video is cropped on the sides\n if (videoAspect > displayAspect) {\n sourceWidth = videoHeight * displayAspect;\n sourceX = (videoWidth - sourceWidth) / 2;\n }\n // Otherwise the video is cropped on the top and bottom\n else {\n sourceHeight = videoWidth / displayAspect;\n sourceY = (videoHeight - sourceHeight) / 2;\n }\n return {\n sourceX,\n sourceY,\n sourceWidth,\n sourceHeight,\n displayWidth,\n displayHeight,\n };\n}\n/**\n * Draws the visible area of the video to the canvas\n */\nexport function drawVisibleAreaToCanvas(canvas, videoElement, area) {\n const { sourceX, sourceY, sourceWidth, sourceHeight, displayWidth, displayHeight } = area;\n // Set canvas size to match the displayed dimensions\n canvas.width = displayWidth;\n canvas.height = displayHeight;\n const ctx = canvas.getContext('2d', { alpha: false });\n if (!ctx) {\n throw new Error('Could not get canvas context');\n }\n // Draw only the visible portion of the video to match what the user sees\n ctx.drawImage(videoElement, sourceX, sourceY, sourceWidth, sourceHeight, 0, 0, displayWidth, displayHeight);\n}\n/**\n * Transforms barcode coordinates from the video source space to display space\n * accounting for object-fit: cover scaling and cropping.\n *\n * @param barcodeBoundingBox The original barcode bounding box from the detector\n * @param videoElement The video element with the camera stream\n * @returns The transformed bounding box coordinates in display space\n */\nexport function transformBarcodeBoundingBox(barcodeBoundingBox, videoElement) {\n // Get the video element's displayed dimensions\n const videoRect = videoElement.getBoundingClientRect();\n const displayWidth = videoRect.width;\n const displayHeight = videoRect.height;\n // Get original video dimensions\n const videoWidth = videoElement.videoWidth;\n const videoHeight = videoElement.videoHeight;\n // Calculate scaling and positioning for object-fit: cover\n const videoAspect = videoWidth / videoHeight;\n const displayAspect = displayWidth / displayHeight;\n let scaledX, scaledY, scaledWidth, scaledHeight;\n if (videoAspect > displayAspect) {\n // Video is wider than display area - height matches, width is centered and cropped\n const scale = displayHeight / videoHeight;\n const scaledVideoWidth = videoWidth * scale;\n const cropX = (scaledVideoWidth - displayWidth) / 2;\n scaledWidth = barcodeBoundingBox.width * scale;\n scaledHeight = barcodeBoundingBox.height * scale;\n scaledX = barcodeBoundingBox.x * scale - cropX;\n scaledY = barcodeBoundingBox.y * scale;\n }\n else {\n // Video is taller than display area - width matches, height is centered and cropped\n const scale = displayWidth / videoWidth;\n const scaledVideoHeight = videoHeight * scale;\n const cropY = (scaledVideoHeight - displayHeight) / 2;\n scaledWidth = barcodeBoundingBox.width * scale;\n scaledHeight = barcodeBoundingBox.height * scale;\n scaledX = barcodeBoundingBox.x * scale;\n scaledY = barcodeBoundingBox.y * scale - cropY;\n }\n return {\n x: scaledX,\n y: scaledY,\n width: scaledWidth,\n height: scaledHeight,\n };\n}\n//# sourceMappingURL=utils.js.map","var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, privateMap) {\n if (!privateMap.has(receiver)) {\n throw new TypeError(\"attempted to get private field on non-instance\");\n }\n return privateMap.get(receiver);\n};\nvar __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, privateMap, value) {\n if (!privateMap.has(receiver)) {\n throw new TypeError(\"attempted to set private field on non-instance\");\n }\n privateMap.set(receiver, value);\n return value;\n};\nvar _isRunning;\nimport { WebPlugin } from '@capacitor/core';\nimport { calculateVisibleArea, canvasToBase64, drawVisibleAreaToCanvas, transformBarcodeBoundingBox } from './utils';\n/**\n * Web implementation of the CameraViewPlugin.\n * Optimized for performance and battery efficiency.\n */\nexport class CameraViewWeb extends WebPlugin {\n constructor() {\n super();\n // DOM elements\n this.videoElement = null;\n this.canvasElement = null;\n // Stream state\n this.stream = null;\n _isRunning.set(this, false);\n // Configuration state\n this.currentCamera = 'environment'; // Default to back camera\n this.currentZoom = 1.0;\n this.currentFlashMode = 'off';\n // Barcode detection support\n this.barcodeDetectionSupported = false;\n this.barcodeDetector = null;\n this.checkBarcodeDetectionSupport();\n }\n /**\n * Start the camera with the given configuration\n */\n async start(options) {\n if (__classPrivateFieldGet(this, _isRunning)) {\n return;\n }\n const permissionStatus = await this.requestPermissions();\n if (permissionStatus.camera !== 'granted') {\n throw new Error('Camera permission was not granted');\n }\n try {\n // Set up video element if it doesn't exist\n if (!this.videoElement) {\n await this.setupVideoElement(options === null || options === void 0 ? void 0 : options.containerElementId);\n }\n // Set up video constraints based on options\n const videoConstraints = {};\n // Prefer deviceId if specified\n if (options === null || options === void 0 ? void 0 : options.deviceId) {\n videoConstraints.deviceId = { exact: options.deviceId };\n // Remember the current camera mode (though we're using a specific device)\n this.currentCamera = (options === null || options === void 0 ? void 0 : options.position) === 'front' ? 'user' : 'environment';\n }\n else {\n // Fall back to facing mode\n const facingMode = (options === null || options === void 0 ? void 0 : options.position) === 'front' ? 'user' : 'environment';\n this.currentCamera = facingMode;\n videoConstraints.facingMode = facingMode;\n }\n const constraints = {\n video: videoConstraints,\n audio: false,\n };\n this.stream = await navigator.mediaDevices.getUserMedia(constraints);\n if (this.videoElement) {\n this.videoElement.srcObject = this.stream;\n this.videoElement.play();\n __classPrivateFieldSet(this, _isRunning, true);\n // If barcode detection is enabled and supported, start detection\n if ((options === null || options === void 0 ? void 0 : options.enableBarcodeDetection) && this.barcodeDetectionSupported) {\n this.startBarcodeDetection();\n }\n }\n }\n catch (err) {\n throw new Error(`Failed to start camera: ${this.formatError(err)}`);\n }\n }\n /**\n * Stop the camera and release resources\n */\n async stop() {\n if (!__classPrivateFieldGet(this, _isRunning)) {\n return;\n }\n try {\n // Stop all tracks in the stream\n if (this.stream) {\n this.stream.getTracks().forEach((track) => track.stop());\n this.stream = null;\n }\n // Clear video source\n if (this.videoElement) {\n this.videoElement = null;\n }\n __classPrivateFieldSet(this, _isRunning, false);\n }\n catch (err) {\n throw new Error(`Failed to stop camera: ${this.formatError(err)}`);\n }\n }\n /**\n * Check if the camera is currently running\n */\n async isRunning() {\n return { isRunning: __classPrivateFieldGet(this, _isRunning) };\n }\n /**\n * Capture a photo using the camera and return it as a base64-encoded JPEG image.\n * Preserves what the user actually sees in the UI, including cropping from object-fit: cover.\n */\n async capture(options) {\n const videoElement = this.videoElement;\n if (!__classPrivateFieldGet(this, _isRunning) || !videoElement) {\n throw new Error('Camera is not running');\n }\n try {\n const canvas = this.getCanvasElement();\n const visibleArea = calculateVisibleArea(videoElement);\n drawVisibleAreaToCanvas(canvas, videoElement, visibleArea);\n const quality = Math.min(1.0, Math.max(0.1, options.quality / 100));\n if (options.saveToFile) {\n // Create a blob from canvas and return a blob URL\n return new Promise((resolve, reject) => {\n canvas.toBlob((blob) => {\n if (!blob) {\n reject(new Error('Failed to create blob from canvas'));\n return;\n }\n const url = URL.createObjectURL(blob);\n resolve({ webPath: url });\n }, 'image/jpeg', quality);\n });\n }\n else {\n // Return base64 data\n const base64Data = canvasToBase64(canvas, quality);\n return { photo: base64Data };\n }\n }\n catch (err) {\n throw new Error(`Failed to capture photo: ${this.formatError(err)}`);\n }\n }\n /**\n * Web implementation already uses images from the video stream, so this is the same as `capture()`\n */\n async captureSample(options) {\n return this.capture(options);\n }\n /**\n * Flip between front and back camera\n */\n async flipCamera() {\n if (!__classPrivateFieldGet(this, _isRunning)) {\n throw new Error('Camera is not running');\n }\n try {\n // Switch current camera\n this.currentCamera = this.currentCamera === 'user' ? 'environment' : 'user';\n // Stop current stream\n if (this.stream) {\n this.stream.getTracks().forEach((track) => track.stop());\n }\n // Restart with new facing mode\n const constraints = {\n video: {\n facingMode: this.currentCamera,\n },\n audio: false,\n };\n this.stream = await navigator.mediaDevices.getUserMedia(constraints);\n if (this.videoElement) {\n this.videoElement.srcObject = this.stream;\n }\n }\n catch (err) {\n throw new Error(`Failed to flip camera: ${this.formatError(err)}`);\n }\n }\n /**\n * Get available camera devices\n */\n async getAvailableDevices() {\n try {\n const devices = await navigator.mediaDevices.enumerateDevices();\n const videoDevices = devices.filter((device) => device.kind === 'videoinput');\n return {\n devices: videoDevices.map((device) => ({\n id: device.deviceId,\n name: device.label || `Camera ${device.deviceId.substring(0, 5)}`,\n position: device.label.toLowerCase().includes('front') ? 'front' : 'back',\n })),\n };\n }\n catch (err) {\n console.error('Failed to get available devices', err);\n return { devices: [] };\n }\n }\n /**\n * Get current zoom information (web has limited zoom support)\n */\n async getZoom() {\n // Web has limited zoom capabilities in most browsers,\n // we fake zoomin by scaling the video element\n return {\n min: 1.0,\n max: 3.0,\n current: this.currentZoom,\n };\n }\n /**\n * Set zoom level (limited support in web)\n */\n async setZoom(options) {\n // Store the requested zoom level\n this.currentZoom = options.level;\n // Apply visual zoom using CSS transform when native zoom isn't supported\n if (this.videoElement) {\n this.videoElement.style.transition = options.ramp ? 'transform 0.2s ease-in-out' : 'none';\n const scale = Math.max(1.0, Math.min(options.level, 3.0)); // Limit scale to reasonable bounds\n this.videoElement.style.transform = `scale(${scale})`;\n this.videoElement.style.transformOrigin = 'center';\n }\n }\n /**\n * Get current flash mode\n */\n async getFlashMode() {\n return { flashMode: this.currentFlashMode };\n }\n /**\n * Get supported flash modes\n */\n async getSupportedFlashModes() {\n // Web has limited flash control\n return { flashModes: ['off'] };\n }\n /**\n * Set flash mode (limited support in web)\n */\n async setFlashMode(options) {\n this.currentFlashMode = options.mode;\n console.warn('Flash mode control is not fully supported in the web implementation');\n }\n /**\n * Check camera permission without requesting\n */\n async checkPermissions() {\n try {\n // Use Permissions API if available\n if (navigator.permissions) {\n const result = await navigator.permissions.query({ name: 'camera' });\n return {\n camera: result.state === 'granted' ? 'granted' : result.state === 'denied' ? 'denied' : 'prompt',\n };\n }\n // If Permissions API is not available, check if we have an active stream\n return {\n camera: this.stream ? 'granted' : 'prompt',\n };\n }\n catch (err) {\n // If permissions API is not supported or fails\n return {\n camera: 'prompt',\n };\n }\n }\n /**\n * Request camera permission from the user\n */\n async requestPermissions() {\n try {\n // Try to access the camera to trigger the permission prompt\n const stream = await navigator.mediaDevices.getUserMedia({ video: true });\n // If we get here, permission was granted\n // Clean up the test stream\n stream.getTracks().forEach((track) => track.stop());\n return { camera: 'granted' };\n }\n catch (err) {\n // Permission denied or other error\n return { camera: 'denied' };\n }\n }\n /**\n * Start barcode detection if supported\n */\n async startBarcodeDetection() {\n const barcodeDetector = this.barcodeDetector;\n const videoElement = this.videoElement;\n if (!this.barcodeDetectionSupported || !barcodeDetector || !videoElement) {\n return;\n }\n // Make sure video is fully loaded before starting detection\n if (videoElement.readyState < 2) {\n await new Promise((resolve) => {\n const loadHandler = () => {\n videoElement.removeEventListener('loadeddata', loadHandler);\n resolve();\n };\n videoElement.addEventListener('loadeddata', loadHandler);\n });\n }\n // Add throttling to reduce CPU usage\n let lastDetectionTime = 0;\n const minTimeBetweenDetections = 100; // ms\n // Set up periodic frame analysis for barcode detection\n const detectFrame = async () => {\n if (!__classPrivateFieldGet(this, _isRunning) || !videoElement || !barcodeDetector) {\n return;\n }\n const now = Date.now();\n if (now - lastDetectionTime >= minTimeBetweenDetections) {\n try {\n const barcodes = await barcodeDetector.detect(videoElement);\n lastDetectionTime = now;\n if (barcodes.length > 0) {\n const barcode = barcodes[0];\n // Transform barcode coordinates using the utility function\n const boundingRect = transformBarcodeBoundingBox(barcode.boundingBox, videoElement);\n this.notifyListeners('barcodeDetected', {\n value: barcode.rawValue,\n type: barcode.format.toLowerCase(),\n boundingRect,\n });\n }\n }\n catch (err) {\n console.error('Barcode detection error', err);\n }\n }\n if (__classPrivateFieldGet(this, _isRunning)) {\n requestAnimationFrame(detectFrame);\n }\n };\n requestAnimationFrame(detectFrame);\n }\n /**\n * Clean up resources when the plugin is disposed\n */\n async handleOnDestroy() {\n var _a;\n await this.stop();\n // Remove elements from DOM\n if ((_a = this.videoElement) === null || _a === void 0 ? void 0 : _a.parentNode) {\n this.videoElement.parentNode.removeChild(this.videoElement);\n this.videoElement = null;\n }\n if (this.canvasElement) {\n this.canvasElement = null;\n }\n this.barcodeDetector = null;\n }\n /**\n * Check if barcode detection is supported in this browser\n */\n async checkBarcodeDetectionSupport() {\n if ('BarcodeDetector' in window) {\n try {\n this.barcodeDetector = new BarcodeDetector();\n this.barcodeDetectionSupported = true;\n }\n catch (e) {\n console.warn('BarcodeDetector is not supported by this browser.');\n this.barcodeDetectionSupported = false;\n }\n }\n }\n /**\n * Set up the video element for the camera view\n */\n async setupVideoElement(containerElementId) {\n this.videoElement = document.createElement('video');\n this.videoElement.playsInline = true;\n this.videoElement.autoplay = true;\n this.videoElement.muted = true;\n this.videoElement.style.width = '100%';\n this.videoElement.style.height = '100%';\n this.videoElement.style.objectFit = 'cover';\n // If a container ID is provided, find that element and append the video to it\n if (containerElementId) {\n const container = document.getElementById(containerElementId);\n if (!container) {\n throw new Error(`Container element with ID ${containerElementId} not found`);\n }\n container.appendChild(this.videoElement);\n }\n else {\n // Otherwise, append to body as fallback\n document.body.appendChild(this.videoElement);\n }\n }\n /**\n * Ensures canvas element exists and returns it\n */\n getCanvasElement() {\n if (!this.canvasElement) {\n this.canvasElement = document.createElement('canvas');\n }\n return this.canvasElement;\n }\n /**\n * Format error message\n */\n formatError(err) {\n return err instanceof Error ? err.message : String(err);\n }\n}\n_isRunning = new WeakMap();\n//# sourceMappingURL=web.js.map"],"names":["registerPlugin","this","WebPlugin"],"mappings":"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"}
|
package/dist/plugin.js
CHANGED
|
@@ -244,8 +244,24 @@ var capacitorCameraView = (function (exports, core) {
|
|
|
244
244
|
const visibleArea = calculateVisibleArea(videoElement);
|
|
245
245
|
drawVisibleAreaToCanvas(canvas, videoElement, visibleArea);
|
|
246
246
|
const quality = Math.min(1.0, Math.max(0.1, options.quality / 100));
|
|
247
|
-
|
|
248
|
-
|
|
247
|
+
if (options.saveToFile) {
|
|
248
|
+
// Create a blob from canvas and return a blob URL
|
|
249
|
+
return new Promise((resolve, reject) => {
|
|
250
|
+
canvas.toBlob((blob) => {
|
|
251
|
+
if (!blob) {
|
|
252
|
+
reject(new Error('Failed to create blob from canvas'));
|
|
253
|
+
return;
|
|
254
|
+
}
|
|
255
|
+
const url = URL.createObjectURL(blob);
|
|
256
|
+
resolve({ webPath: url });
|
|
257
|
+
}, 'image/jpeg', quality);
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
else {
|
|
261
|
+
// Return base64 data
|
|
262
|
+
const base64Data = canvasToBase64(canvas, quality);
|
|
263
|
+
return { photo: base64Data };
|
|
264
|
+
}
|
|
249
265
|
}
|
|
250
266
|
catch (err) {
|
|
251
267
|
throw new Error(`Failed to capture photo: ${this.formatError(err)}`);
|