@capgo/camera-preview 7.23.9 → 7.23.11

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/dist/esm/web.js CHANGED
@@ -1,6 +1,6 @@
1
- import { WebPlugin } from "@capacitor/core";
2
- import { DeviceType } from "./definitions";
3
- const DEFAULT_VIDEO_ID = "capgo_video";
1
+ import { WebPlugin } from '@capacitor/core';
2
+ import { DeviceType } from './definitions';
3
+ const DEFAULT_VIDEO_ID = 'capgo_video';
4
4
  export class CameraPreviewWeb extends WebPlugin {
5
5
  constructor() {
6
6
  super();
@@ -16,32 +16,32 @@ export class CameraPreviewWeb extends WebPlugin {
16
16
  }
17
17
  async checkPermissions(options) {
18
18
  const result = {
19
- camera: "prompt",
19
+ camera: 'prompt',
20
20
  };
21
21
  const permissionsApi = navigator === null || navigator === void 0 ? void 0 : navigator.permissions;
22
22
  if (permissionsApi === null || permissionsApi === void 0 ? void 0 : permissionsApi.query) {
23
23
  try {
24
- const cameraPermission = await permissionsApi.query({ name: "camera" });
24
+ const cameraPermission = await permissionsApi.query({ name: 'camera' });
25
25
  result.camera = this.mapWebPermission(cameraPermission.state);
26
26
  }
27
27
  catch (error) {
28
- console.warn("Camera permission query failed", error);
28
+ console.warn('Camera permission query failed', error);
29
29
  }
30
30
  if ((options === null || options === void 0 ? void 0 : options.disableAudio) === false) {
31
31
  try {
32
32
  const microphonePermission = await permissionsApi.query({
33
- name: "microphone",
33
+ name: 'microphone',
34
34
  });
35
35
  result.microphone = this.mapWebPermission(microphonePermission.state);
36
36
  }
37
37
  catch (error) {
38
- console.warn("Microphone permission query failed", error);
39
- result.microphone = "prompt";
38
+ console.warn('Microphone permission query failed', error);
39
+ result.microphone = 'prompt';
40
40
  }
41
41
  }
42
42
  }
43
43
  else if ((options === null || options === void 0 ? void 0 : options.disableAudio) === false) {
44
- result.microphone = "prompt";
44
+ result.microphone = 'prompt';
45
45
  }
46
46
  return result;
47
47
  }
@@ -49,15 +49,13 @@ export class CameraPreviewWeb extends WebPlugin {
49
49
  var _a, _b;
50
50
  const disableAudio = (_a = options === null || options === void 0 ? void 0 : options.disableAudio) !== null && _a !== void 0 ? _a : true;
51
51
  if ((_b = navigator === null || navigator === void 0 ? void 0 : navigator.mediaDevices) === null || _b === void 0 ? void 0 : _b.getUserMedia) {
52
- const constraints = disableAudio
53
- ? { video: true }
54
- : { video: true, audio: true };
52
+ const constraints = disableAudio ? { video: true } : { video: true, audio: true };
55
53
  let stream;
56
54
  try {
57
55
  stream = await navigator.mediaDevices.getUserMedia(constraints);
58
56
  }
59
57
  catch (error) {
60
- console.warn("Unable to obtain camera or microphone stream", error);
58
+ console.warn('Unable to obtain camera or microphone stream', error);
61
59
  }
62
60
  finally {
63
61
  try {
@@ -70,19 +68,19 @@ export class CameraPreviewWeb extends WebPlugin {
70
68
  }
71
69
  const status = await this.checkPermissions({ disableAudio: disableAudio });
72
70
  if (options === null || options === void 0 ? void 0 : options.showSettingsAlert) {
73
- console.warn("showSettingsAlert is not supported on the web platform; returning permission status only.");
71
+ console.warn('showSettingsAlert is not supported on the web platform; returning permission status only.');
74
72
  }
75
73
  return status;
76
74
  }
77
75
  mapWebPermission(state) {
78
76
  switch (state) {
79
- case "granted":
80
- return "granted";
81
- case "denied":
82
- return "denied";
83
- case "prompt":
77
+ case 'granted':
78
+ return 'granted';
79
+ case 'denied':
80
+ return 'denied';
81
+ case 'prompt':
84
82
  default:
85
- return "prompt";
83
+ return 'prompt';
86
84
  }
87
85
  }
88
86
  getCurrentOrientation() {
@@ -90,113 +88,111 @@ export class CameraPreviewWeb extends WebPlugin {
90
88
  try {
91
89
  const so = screen.orientation;
92
90
  const type = (so === null || so === void 0 ? void 0 : so.type) || (so === null || so === void 0 ? void 0 : so.mozOrientation) || (so === null || so === void 0 ? void 0 : so.msOrientation);
93
- if (typeof type === "string") {
94
- if (type.includes("portrait-primary"))
95
- return "portrait";
96
- if (type.includes("portrait-secondary"))
97
- return "portrait-upside-down";
98
- if (type.includes("landscape-primary"))
99
- return "landscape-left";
100
- if (type.includes("landscape-secondary"))
101
- return "landscape-right";
102
- if (type.includes("landscape"))
103
- return "landscape-right"; // avoid generic landscape
104
- if (type.includes("portrait"))
105
- return "portrait";
91
+ if (typeof type === 'string') {
92
+ if (type.includes('portrait-primary'))
93
+ return 'portrait';
94
+ if (type.includes('portrait-secondary'))
95
+ return 'portrait-upside-down';
96
+ if (type.includes('landscape-primary'))
97
+ return 'landscape-left';
98
+ if (type.includes('landscape-secondary'))
99
+ return 'landscape-right';
100
+ if (type.includes('landscape'))
101
+ return 'landscape-right'; // avoid generic landscape
102
+ if (type.includes('portrait'))
103
+ return 'portrait';
106
104
  }
107
105
  const angle = window.orientation;
108
- if (typeof angle === "number") {
106
+ if (typeof angle === 'number') {
109
107
  if (angle === 0)
110
- return "portrait";
108
+ return 'portrait';
111
109
  if (angle === 180)
112
- return "portrait-upside-down";
110
+ return 'portrait-upside-down';
113
111
  if (angle === 90)
114
- return "landscape-right";
112
+ return 'landscape-right';
115
113
  if (angle === -90)
116
- return "landscape-left";
114
+ return 'landscape-left';
117
115
  if (angle === 270)
118
- return "landscape-left";
116
+ return 'landscape-left';
119
117
  }
120
- if ((_a = window.matchMedia("(orientation: portrait)")) === null || _a === void 0 ? void 0 : _a.matches) {
121
- return "portrait";
118
+ if ((_a = window.matchMedia('(orientation: portrait)')) === null || _a === void 0 ? void 0 : _a.matches) {
119
+ return 'portrait';
122
120
  }
123
- if ((_b = window.matchMedia("(orientation: landscape)")) === null || _b === void 0 ? void 0 : _b.matches) {
121
+ if ((_b = window.matchMedia('(orientation: landscape)')) === null || _b === void 0 ? void 0 : _b.matches) {
124
122
  // Default to landscape-right when we can't distinguish primary/secondary
125
- return "landscape-right";
123
+ return 'landscape-right';
126
124
  }
127
125
  }
128
126
  catch (e) {
129
127
  console.error(e);
130
128
  }
131
- return "unknown";
129
+ return 'unknown';
132
130
  }
133
131
  ensureOrientationListener() {
134
132
  if (this.orientationListenerBound)
135
133
  return;
136
134
  const emit = () => {
137
- this.notifyListeners("orientationChange", {
135
+ this.notifyListeners('orientationChange', {
138
136
  orientation: this.getCurrentOrientation(),
139
137
  });
140
138
  };
141
- window.addEventListener("orientationchange", emit);
142
- window.addEventListener("resize", emit);
139
+ window.addEventListener('orientationchange', emit);
140
+ window.addEventListener('resize', emit);
143
141
  this.orientationListenerBound = true;
144
142
  }
145
143
  async getOrientation() {
146
144
  return { orientation: this.getCurrentOrientation() };
147
145
  }
148
146
  getSafeAreaInsets() {
149
- throw new Error("Method not implemented.");
147
+ throw new Error('Method not implemented.');
150
148
  }
151
149
  async getZoomButtonValues() {
152
- throw new Error("getZoomButtonValues not supported under the web platform");
150
+ throw new Error('getZoomButtonValues not supported under the web platform');
153
151
  }
154
152
  async getSupportedPictureSizes() {
155
- throw new Error("getSupportedPictureSizes not supported under the web platform");
153
+ throw new Error('getSupportedPictureSizes not supported under the web platform');
156
154
  }
157
155
  async start(options) {
158
156
  if (options.aspectRatio && (options.width || options.height)) {
159
- throw new Error("Cannot set both aspectRatio and size (width/height). Use setPreviewSize after start.");
157
+ throw new Error('Cannot set both aspectRatio and size (width/height). Use setPreviewSize after start.');
160
158
  }
161
159
  if (this.isStarted) {
162
- throw new Error("camera already started");
160
+ throw new Error('camera already started');
163
161
  }
164
162
  this.isBackCamera = true;
165
163
  this.isStarted = false;
166
- const parent = document.getElementById((options === null || options === void 0 ? void 0 : options.parent) || "");
167
- const gridMode = (options === null || options === void 0 ? void 0 : options.gridMode) || "none";
168
- const positioning = (options === null || options === void 0 ? void 0 : options.positioning) || "top";
164
+ const parent = document.getElementById((options === null || options === void 0 ? void 0 : options.parent) || '');
165
+ const gridMode = (options === null || options === void 0 ? void 0 : options.gridMode) || 'none';
166
+ const positioning = (options === null || options === void 0 ? void 0 : options.positioning) || 'top';
169
167
  if (options.position) {
170
- this.isBackCamera = options.position === "rear";
168
+ this.isBackCamera = options.position === 'rear';
171
169
  }
172
170
  const video = document.getElementById(DEFAULT_VIDEO_ID);
173
171
  if (video) {
174
172
  video.remove();
175
173
  }
176
- const container = options.parent
177
- ? document.getElementById(options.parent)
178
- : document.body;
174
+ const container = options.parent ? document.getElementById(options.parent) : document.body;
179
175
  if (!container) {
180
- throw new Error("container not found");
176
+ throw new Error('container not found');
181
177
  }
182
- this.videoElement = document.createElement("video");
178
+ this.videoElement = document.createElement('video');
183
179
  this.videoElement.id = DEFAULT_VIDEO_ID;
184
- this.videoElement.className = options.className || "";
180
+ this.videoElement.className = options.className || '';
185
181
  this.videoElement.playsInline = true;
186
182
  this.videoElement.muted = true;
187
183
  this.videoElement.autoplay = true;
188
184
  // Remove objectFit as we'll match camera's native aspect ratio
189
- this.videoElement.style.backgroundColor = "transparent";
185
+ this.videoElement.style.backgroundColor = 'transparent';
190
186
  // Reset any default margins that might interfere
191
- this.videoElement.style.margin = "0";
192
- this.videoElement.style.padding = "0";
187
+ this.videoElement.style.margin = '0';
188
+ this.videoElement.style.padding = '0';
193
189
  container.appendChild(this.videoElement);
194
190
  if (options.toBack) {
195
- this.videoElement.style.zIndex = "-1";
191
+ this.videoElement.style.zIndex = '-1';
196
192
  }
197
193
  // Default to 4:3 if no aspect ratio or size specified
198
194
  const useDefaultAspectRatio = !options.aspectRatio && !options.width && !options.height;
199
- const effectiveAspectRatio = options.aspectRatio || (useDefaultAspectRatio ? "4:3" : null);
195
+ const effectiveAspectRatio = options.aspectRatio || (useDefaultAspectRatio ? '4:3' : null);
200
196
  if (options.width) {
201
197
  this.videoElement.width = options.width;
202
198
  this.videoElement.style.width = `${options.width}px`;
@@ -209,8 +205,8 @@ export class CameraPreviewWeb extends WebPlugin {
209
205
  const centerX = options.x === undefined;
210
206
  const centerY = options.y === undefined;
211
207
  // Always set position to absolute for proper positioning
212
- this.videoElement.style.position = "absolute";
213
- console.log("Initial positioning flags:", {
208
+ this.videoElement.style.position = 'absolute';
209
+ console.log('Initial positioning flags:', {
214
210
  centerX,
215
211
  centerY,
216
212
  x: options.x,
@@ -223,28 +219,28 @@ export class CameraPreviewWeb extends WebPlugin {
223
219
  this.videoElement.style.top = `${options.y}px`;
224
220
  }
225
221
  // Create and add grid overlay if needed
226
- if (gridMode !== "none") {
222
+ if (gridMode !== 'none') {
227
223
  const gridOverlay = this.createGridOverlay(gridMode);
228
- gridOverlay.id = "camera-grid-overlay";
224
+ gridOverlay.id = 'camera-grid-overlay';
229
225
  parent === null || parent === void 0 ? void 0 : parent.appendChild(gridOverlay);
230
226
  }
231
227
  // Aspect ratio handling is now done after getting camera stream
232
228
  // Store centering flags for later use
233
229
  const needsCenterX = centerX;
234
230
  const needsCenterY = centerY;
235
- console.log("Centering flags stored:", { needsCenterX, needsCenterY });
231
+ console.log('Centering flags stored:', { needsCenterX, needsCenterY });
236
232
  // First get the camera stream with basic constraints
237
233
  const constraints = {
238
234
  video: {
239
- facingMode: this.isBackCamera ? "environment" : "user",
235
+ facingMode: this.isBackCamera ? 'environment' : 'user',
240
236
  },
241
237
  };
242
238
  const stream = await navigator.mediaDevices.getUserMedia(constraints);
243
239
  if (!stream) {
244
- throw new Error("could not acquire stream");
240
+ throw new Error('could not acquire stream');
245
241
  }
246
242
  if (!this.videoElement) {
247
- throw new Error("video element not found");
243
+ throw new Error('video element not found');
248
244
  }
249
245
  // Get the actual camera dimensions from the video track
250
246
  const videoTrack = stream.getVideoTracks()[0];
@@ -252,12 +248,12 @@ export class CameraPreviewWeb extends WebPlugin {
252
248
  const cameraWidth = settings.width || 640;
253
249
  const cameraHeight = settings.height || 480;
254
250
  const cameraAspectRatio = cameraWidth / cameraHeight;
255
- console.log("Camera native dimensions:", {
251
+ console.log('Camera native dimensions:', {
256
252
  width: cameraWidth,
257
253
  height: cameraHeight,
258
254
  aspectRatio: cameraAspectRatio,
259
255
  });
260
- console.log("Container dimensions:", {
256
+ console.log('Container dimensions:', {
261
257
  width: container.offsetWidth,
262
258
  height: container.offsetHeight,
263
259
  id: container.id,
@@ -277,7 +273,7 @@ export class CameraPreviewWeb extends WebPlugin {
277
273
  targetHeight = containerHeight;
278
274
  targetWidth = targetHeight * cameraAspectRatio;
279
275
  }
280
- console.log("Video element dimensions:", {
276
+ console.log('Video element dimensions:', {
281
277
  width: targetWidth,
282
278
  height: targetHeight,
283
279
  container: { width: containerWidth, height: containerHeight },
@@ -294,21 +290,21 @@ export class CameraPreviewWeb extends WebPlugin {
294
290
  if (needsCenterY || options.y === undefined) {
295
291
  let y;
296
292
  switch (positioning) {
297
- case "top":
293
+ case 'top':
298
294
  y = 0;
299
295
  break;
300
- case "bottom":
296
+ case 'bottom':
301
297
  y = window.innerHeight - targetHeight;
302
298
  break;
303
- case "center":
299
+ case 'center':
304
300
  default:
305
301
  y = Math.round((window.innerHeight - targetHeight) / 2);
306
302
  break;
307
303
  }
308
- this.videoElement.style.setProperty("top", `${y}px`, "important");
304
+ this.videoElement.style.setProperty('top', `${y}px`, 'important');
309
305
  // Force a style recalculation
310
306
  this.videoElement.offsetHeight;
311
- console.log("Positioning video:", {
307
+ console.log('Positioning video:', {
312
308
  positioning,
313
309
  viewportHeight: window.innerHeight,
314
310
  targetHeight,
@@ -320,9 +316,7 @@ export class CameraPreviewWeb extends WebPlugin {
320
316
  }
321
317
  else if (effectiveAspectRatio && !options.width && !options.height) {
322
318
  // Aspect ratio specified but no size
323
- const [widthRatio, heightRatio] = effectiveAspectRatio
324
- .split(":")
325
- .map(Number);
319
+ const [widthRatio, heightRatio] = effectiveAspectRatio.split(':').map(Number);
326
320
  const targetRatio = widthRatio / heightRatio;
327
321
  const viewportWidth = window.innerWidth;
328
322
  const viewportHeight = window.innerHeight;
@@ -349,13 +343,13 @@ export class CameraPreviewWeb extends WebPlugin {
349
343
  const parentHeight = container.offsetHeight || viewportHeight;
350
344
  let y;
351
345
  switch (positioning) {
352
- case "top":
346
+ case 'top':
353
347
  y = 0;
354
348
  break;
355
- case "bottom":
349
+ case 'bottom':
356
350
  y = parentHeight - targetHeight;
357
351
  break;
358
- case "center":
352
+ case 'center':
359
353
  default:
360
354
  y = Math.round((parentHeight - targetHeight) / 2);
361
355
  break;
@@ -365,11 +359,10 @@ export class CameraPreviewWeb extends WebPlugin {
365
359
  }
366
360
  this.videoElement.srcObject = stream;
367
361
  if (!this.isBackCamera) {
368
- this.videoElement.style.transform = "scaleX(-1)";
362
+ this.videoElement.style.transform = 'scaleX(-1)';
369
363
  }
370
364
  // Set initial zoom level if specified and supported
371
- if (options.initialZoomLevel !== undefined &&
372
- options.initialZoomLevel !== 1.0) {
365
+ if (options.initialZoomLevel !== undefined && options.initialZoomLevel !== 1.0) {
373
366
  // videoTrack already declared above
374
367
  if (videoTrack) {
375
368
  const capabilities = videoTrack.getCapabilities();
@@ -399,26 +392,26 @@ export class CameraPreviewWeb extends WebPlugin {
399
392
  await new Promise((resolve) => {
400
393
  const videoEl = this.videoElement;
401
394
  if (!videoEl) {
402
- throw new Error("video element not found");
395
+ throw new Error('video element not found');
403
396
  }
404
397
  if (videoEl.readyState >= 2) {
405
398
  resolve();
406
399
  }
407
400
  else {
408
- videoEl.addEventListener("loadeddata", () => resolve(), {
401
+ videoEl.addEventListener('loadeddata', () => resolve(), {
409
402
  once: true,
410
403
  });
411
404
  }
412
405
  });
413
406
  // Ensure centering is applied after DOM updates
414
407
  await new Promise((resolve) => requestAnimationFrame(resolve));
415
- console.log("About to re-center, flags:", { needsCenterX, needsCenterY });
408
+ console.log('About to re-center, flags:', { needsCenterX, needsCenterY });
416
409
  // Re-apply centering with correct parent dimensions
417
410
  if (needsCenterX) {
418
411
  const parentWidth = container.offsetWidth;
419
412
  const x = Math.round((parentWidth - this.videoElement.offsetWidth) / 2);
420
413
  this.videoElement.style.left = `${x}px`;
421
- console.log("Re-centering X:", {
414
+ console.log('Re-centering X:', {
422
415
  parentWidth,
423
416
  videoWidth: this.videoElement.offsetWidth,
424
417
  x,
@@ -427,19 +420,19 @@ export class CameraPreviewWeb extends WebPlugin {
427
420
  if (needsCenterY) {
428
421
  let y;
429
422
  switch (positioning) {
430
- case "top":
423
+ case 'top':
431
424
  y = 0;
432
425
  break;
433
- case "bottom":
426
+ case 'bottom':
434
427
  y = window.innerHeight - this.videoElement.offsetHeight;
435
428
  break;
436
- case "center":
429
+ case 'center':
437
430
  default:
438
431
  y = Math.round((window.innerHeight - this.videoElement.offsetHeight) / 2);
439
432
  break;
440
433
  }
441
- this.videoElement.style.setProperty("top", `${y}px`, "important");
442
- console.log("Re-positioning Y:", {
434
+ this.videoElement.style.setProperty('top', `${y}px`, 'important');
435
+ console.log('Re-positioning Y:', {
443
436
  positioning,
444
437
  viewportHeight: window.innerHeight,
445
438
  videoHeight: this.videoElement.offsetHeight,
@@ -451,7 +444,7 @@ export class CameraPreviewWeb extends WebPlugin {
451
444
  // Get the actual rendered dimensions after video is loaded
452
445
  const rect = this.videoElement.getBoundingClientRect();
453
446
  const computedStyle = window.getComputedStyle(this.videoElement);
454
- console.log("Final video element state:", {
447
+ console.log('Final video element state:', {
455
448
  rect: { x: rect.x, y: rect.y, width: rect.width, height: rect.height },
456
449
  style: {
457
450
  position: computedStyle.position,
@@ -484,21 +477,21 @@ export class CameraPreviewWeb extends WebPlugin {
484
477
  this.isStarted = false;
485
478
  }
486
479
  // Remove grid overlay if it exists
487
- const gridOverlay = document.getElementById("camera-grid-overlay");
480
+ const gridOverlay = document.getElementById('camera-grid-overlay');
488
481
  gridOverlay === null || gridOverlay === void 0 ? void 0 : gridOverlay.remove();
489
482
  }
490
483
  async capture(options) {
491
484
  return new Promise((resolve, reject) => {
492
485
  const video = document.getElementById(DEFAULT_VIDEO_ID);
493
486
  if (!(video === null || video === void 0 ? void 0 : video.srcObject)) {
494
- reject(new Error("camera is not running"));
487
+ reject(new Error('camera is not running'));
495
488
  return;
496
489
  }
497
490
  // video.width = video.offsetWidth;
498
491
  let base64EncodedImage;
499
492
  if (video && video.videoWidth > 0 && video.videoHeight > 0) {
500
- const canvas = document.createElement("canvas");
501
- const context = canvas.getContext("2d");
493
+ const canvas = document.createElement('canvas');
494
+ const context = canvas.getContext('2d');
502
495
  // Calculate capture dimensions
503
496
  let captureWidth = video.videoWidth;
504
497
  let captureHeight = video.videoHeight;
@@ -549,15 +542,13 @@ export class CameraPreviewWeb extends WebPlugin {
549
542
  if (options.withExifLocation) {
550
543
  // withExifLocation is not supported on web
551
544
  }
552
- if ((options.format || "jpeg") === "jpeg") {
545
+ if ((options.format || 'jpeg') === 'jpeg') {
553
546
  base64EncodedImage = canvas
554
- .toDataURL("image/jpeg", (options.quality || 85) / 100.0)
555
- .replace("data:image/jpeg;base64,", "");
547
+ .toDataURL('image/jpeg', (options.quality || 85) / 100.0)
548
+ .replace('data:image/jpeg;base64,', '');
556
549
  }
557
550
  else {
558
- base64EncodedImage = canvas
559
- .toDataURL("image/png")
560
- .replace("data:image/png;base64,", "");
551
+ base64EncodedImage = canvas.toDataURL('image/png').replace('data:image/png;base64,', '');
561
552
  }
562
553
  }
563
554
  resolve({
@@ -570,17 +561,17 @@ export class CameraPreviewWeb extends WebPlugin {
570
561
  return this.capture(_options);
571
562
  }
572
563
  async stopRecordVideo() {
573
- throw new Error("stopRecordVideo not supported under the web platform");
564
+ throw new Error('stopRecordVideo not supported under the web platform');
574
565
  }
575
566
  async startRecordVideo(_options) {
576
- console.log("startRecordVideo", _options);
577
- throw new Error("startRecordVideo not supported under the web platform");
567
+ console.log('startRecordVideo', _options);
568
+ throw new Error('startRecordVideo not supported under the web platform');
578
569
  }
579
570
  async getSupportedFlashModes() {
580
- throw new Error("getSupportedFlashModes not supported under the web platform");
571
+ throw new Error('getSupportedFlashModes not supported under the web platform');
581
572
  }
582
573
  async getHorizontalFov() {
583
- throw new Error("getHorizontalFov not supported under the web platform");
574
+ throw new Error('getHorizontalFov not supported under the web platform');
584
575
  }
585
576
  async setFlashMode(_options) {
586
577
  throw new Error(`setFlashMode not supported under the web platform${_options}`);
@@ -588,7 +579,7 @@ export class CameraPreviewWeb extends WebPlugin {
588
579
  async flip() {
589
580
  const video = document.getElementById(DEFAULT_VIDEO_ID);
590
581
  if (!(video === null || video === void 0 ? void 0 : video.srcObject)) {
591
- throw new Error("camera is not running");
582
+ throw new Error('camera is not running');
592
583
  }
593
584
  // Stop current stream
594
585
  this.stopStream(video.srcObject);
@@ -597,7 +588,7 @@ export class CameraPreviewWeb extends WebPlugin {
597
588
  // Get new constraints
598
589
  const constraints = {
599
590
  video: {
600
- facingMode: this.isBackCamera ? "environment" : "user",
591
+ facingMode: this.isBackCamera ? 'environment' : 'user',
601
592
  width: { ideal: video.videoWidth || 640 },
602
593
  height: { ideal: video.videoHeight || 480 },
603
594
  },
@@ -612,12 +603,12 @@ export class CameraPreviewWeb extends WebPlugin {
612
603
  }
613
604
  // Update video transform based on camera
614
605
  if (this.isBackCamera) {
615
- video.style.transform = "none";
616
- video.style.webkitTransform = "none";
606
+ video.style.transform = 'none';
607
+ video.style.webkitTransform = 'none';
617
608
  }
618
609
  else {
619
- video.style.transform = "scaleX(-1)";
620
- video.style.webkitTransform = "scaleX(-1)";
610
+ video.style.transform = 'scaleX(-1)';
611
+ video.style.webkitTransform = 'scaleX(-1)';
621
612
  }
622
613
  await video.play();
623
614
  }
@@ -628,7 +619,7 @@ export class CameraPreviewWeb extends WebPlugin {
628
619
  async setOpacity(_options) {
629
620
  const video = document.getElementById(DEFAULT_VIDEO_ID);
630
621
  if (!!video && !!_options.opacity)
631
- video.style.setProperty("opacity", _options.opacity.toString());
622
+ video.style.setProperty('opacity', _options.opacity.toString());
632
623
  }
633
624
  async isRunning() {
634
625
  const video = document.getElementById(DEFAULT_VIDEO_ID);
@@ -637,10 +628,10 @@ export class CameraPreviewWeb extends WebPlugin {
637
628
  async getAvailableDevices() {
638
629
  var _a;
639
630
  if (!((_a = navigator.mediaDevices) === null || _a === void 0 ? void 0 : _a.enumerateDevices)) {
640
- throw new Error("getAvailableDevices not supported under the web platform");
631
+ throw new Error('getAvailableDevices not supported under the web platform');
641
632
  }
642
633
  const devices = await navigator.mediaDevices.enumerateDevices();
643
- const videoDevices = devices.filter((device) => device.kind === "videoinput");
634
+ const videoDevices = devices.filter((device) => device.kind === 'videoinput');
644
635
  // Group devices by position (front/back)
645
636
  const frontDevices = [];
646
637
  const backDevices = [];
@@ -650,19 +641,18 @@ export class CameraPreviewWeb extends WebPlugin {
650
641
  // Determine device type based on label
651
642
  let deviceType = DeviceType.WIDE_ANGLE;
652
643
  let baseZoomRatio = 1.0;
653
- if (labelLower.includes("ultra") || labelLower.includes("0.5")) {
644
+ if (labelLower.includes('ultra') || labelLower.includes('0.5')) {
654
645
  deviceType = DeviceType.ULTRA_WIDE;
655
646
  baseZoomRatio = 0.5;
656
647
  }
657
- else if (labelLower.includes("telephoto") ||
658
- labelLower.includes("tele") ||
659
- labelLower.includes("2x") ||
660
- labelLower.includes("3x")) {
648
+ else if (labelLower.includes('telephoto') ||
649
+ labelLower.includes('tele') ||
650
+ labelLower.includes('2x') ||
651
+ labelLower.includes('3x')) {
661
652
  deviceType = DeviceType.TELEPHOTO;
662
653
  baseZoomRatio = 2.0;
663
654
  }
664
- else if (labelLower.includes("depth") ||
665
- labelLower.includes("truedepth")) {
655
+ else if (labelLower.includes('depth') || labelLower.includes('truedepth')) {
666
656
  deviceType = DeviceType.TRUE_DEPTH;
667
657
  baseZoomRatio = 1.0;
668
658
  }
@@ -676,7 +666,7 @@ export class CameraPreviewWeb extends WebPlugin {
676
666
  maxZoom: 1.0,
677
667
  };
678
668
  // Determine position and add to appropriate array
679
- if (labelLower.includes("back") || labelLower.includes("rear")) {
669
+ if (labelLower.includes('back') || labelLower.includes('rear')) {
680
670
  backDevices.push(lensInfo);
681
671
  }
682
672
  else {
@@ -687,8 +677,8 @@ export class CameraPreviewWeb extends WebPlugin {
687
677
  if (frontDevices.length > 0) {
688
678
  result.push({
689
679
  deviceId: frontDevices[0].deviceId,
690
- label: "Front Camera",
691
- position: "front",
680
+ label: 'Front Camera',
681
+ position: 'front',
692
682
  lenses: frontDevices,
693
683
  isLogical: false,
694
684
  minZoom: Math.min(...frontDevices.map((d) => d.minZoom)),
@@ -698,8 +688,8 @@ export class CameraPreviewWeb extends WebPlugin {
698
688
  if (backDevices.length > 0) {
699
689
  result.push({
700
690
  deviceId: backDevices[0].deviceId,
701
- label: "Back Camera",
702
- position: "rear",
691
+ label: 'Back Camera',
692
+ position: 'rear',
703
693
  lenses: backDevices,
704
694
  isLogical: false,
705
695
  minZoom: Math.min(...backDevices.map((d) => d.minZoom)),
@@ -711,17 +701,17 @@ export class CameraPreviewWeb extends WebPlugin {
711
701
  async getZoom() {
712
702
  const video = document.getElementById(DEFAULT_VIDEO_ID);
713
703
  if (!(video === null || video === void 0 ? void 0 : video.srcObject)) {
714
- throw new Error("camera is not running");
704
+ throw new Error('camera is not running');
715
705
  }
716
706
  const stream = video.srcObject;
717
707
  const videoTrack = stream.getVideoTracks()[0];
718
708
  if (!videoTrack) {
719
- throw new Error("no video track found");
709
+ throw new Error('no video track found');
720
710
  }
721
711
  const capabilities = videoTrack.getCapabilities();
722
712
  const settings = videoTrack.getSettings();
723
713
  if (!capabilities.zoom) {
724
- throw new Error("zoom not supported by this device");
714
+ throw new Error('zoom not supported by this device');
725
715
  }
726
716
  // Get current device info to determine lens type
727
717
  let deviceType = DeviceType.WIDE_ANGLE;
@@ -731,19 +721,18 @@ export class CameraPreviewWeb extends WebPlugin {
731
721
  const device = devices.find((d) => d.deviceId === this.currentDeviceId);
732
722
  if (device) {
733
723
  const labelLower = device.label.toLowerCase();
734
- if (labelLower.includes("ultra") || labelLower.includes("0.5")) {
724
+ if (labelLower.includes('ultra') || labelLower.includes('0.5')) {
735
725
  deviceType = DeviceType.ULTRA_WIDE;
736
726
  baseZoomRatio = 0.5;
737
727
  }
738
- else if (labelLower.includes("telephoto") ||
739
- labelLower.includes("tele") ||
740
- labelLower.includes("2x") ||
741
- labelLower.includes("3x")) {
728
+ else if (labelLower.includes('telephoto') ||
729
+ labelLower.includes('tele') ||
730
+ labelLower.includes('2x') ||
731
+ labelLower.includes('3x')) {
742
732
  deviceType = DeviceType.TELEPHOTO;
743
733
  baseZoomRatio = 2.0;
744
734
  }
745
- else if (labelLower.includes("depth") ||
746
- labelLower.includes("truedepth")) {
735
+ else if (labelLower.includes('depth') || labelLower.includes('truedepth')) {
747
736
  deviceType = DeviceType.TRUE_DEPTH;
748
737
  baseZoomRatio = 1.0;
749
738
  }
@@ -766,16 +755,16 @@ export class CameraPreviewWeb extends WebPlugin {
766
755
  async setZoom(options) {
767
756
  const video = document.getElementById(DEFAULT_VIDEO_ID);
768
757
  if (!(video === null || video === void 0 ? void 0 : video.srcObject)) {
769
- throw new Error("camera is not running");
758
+ throw new Error('camera is not running');
770
759
  }
771
760
  const stream = video.srcObject;
772
761
  const videoTrack = stream.getVideoTracks()[0];
773
762
  if (!videoTrack) {
774
- throw new Error("no video track found");
763
+ throw new Error('no video track found');
775
764
  }
776
765
  const capabilities = videoTrack.getCapabilities();
777
766
  if (!capabilities.zoom) {
778
- throw new Error("zoom not supported by this device");
767
+ throw new Error('zoom not supported by this device');
779
768
  }
780
769
  const zoomLevel = Math.max(capabilities.zoom.min || 1, Math.min(capabilities.zoom.max || 1, options.level));
781
770
  // Note: autoFocus is not supported on web platform
@@ -789,15 +778,15 @@ export class CameraPreviewWeb extends WebPlugin {
789
778
  }
790
779
  }
791
780
  async getFlashMode() {
792
- throw new Error("getFlashMode not supported under the web platform");
781
+ throw new Error('getFlashMode not supported under the web platform');
793
782
  }
794
783
  async getDeviceId() {
795
- return { deviceId: this.currentDeviceId || "" };
784
+ return { deviceId: this.currentDeviceId || '' };
796
785
  }
797
786
  async setDeviceId(options) {
798
787
  const video = document.getElementById(DEFAULT_VIDEO_ID);
799
788
  if (!(video === null || video === void 0 ? void 0 : video.srcObject)) {
800
- throw new Error("camera is not running");
789
+ throw new Error('camera is not running');
801
790
  }
802
791
  // Stop current stream
803
792
  this.stopStream(video.srcObject);
@@ -816,19 +805,17 @@ export class CameraPreviewWeb extends WebPlugin {
816
805
  const devices = await navigator.mediaDevices.enumerateDevices();
817
806
  const device = devices.find((d) => d.deviceId === options.deviceId);
818
807
  this.isBackCamera =
819
- (device === null || device === void 0 ? void 0 : device.label.toLowerCase().includes("back")) ||
820
- (device === null || device === void 0 ? void 0 : device.label.toLowerCase().includes("rear")) ||
821
- false;
808
+ (device === null || device === void 0 ? void 0 : device.label.toLowerCase().includes('back')) || (device === null || device === void 0 ? void 0 : device.label.toLowerCase().includes('rear')) || false;
822
809
  const stream = await navigator.mediaDevices.getUserMedia(constraints);
823
810
  video.srcObject = stream;
824
811
  // Update video transform based on camera
825
812
  if (this.isBackCamera) {
826
- video.style.transform = "none";
827
- video.style.webkitTransform = "none";
813
+ video.style.transform = 'none';
814
+ video.style.webkitTransform = 'none';
828
815
  }
829
816
  else {
830
- video.style.transform = "scaleX(-1)";
831
- video.style.webkitTransform = "scaleX(-1)";
817
+ video.style.transform = 'scaleX(-1)';
818
+ video.style.webkitTransform = 'scaleX(-1)';
832
819
  }
833
820
  await video.play();
834
821
  }
@@ -839,7 +826,7 @@ export class CameraPreviewWeb extends WebPlugin {
839
826
  async getAspectRatio() {
840
827
  const video = document.getElementById(DEFAULT_VIDEO_ID);
841
828
  if (!video) {
842
- throw new Error("camera is not running");
829
+ throw new Error('camera is not running');
843
830
  }
844
831
  const width = video.offsetWidth;
845
832
  const height = video.offsetHeight;
@@ -847,24 +834,22 @@ export class CameraPreviewWeb extends WebPlugin {
847
834
  const ratio = width / height;
848
835
  // Check for portrait camera ratios: 4:3 -> 3:4, 16:9 -> 9:16
849
836
  if (Math.abs(ratio - 3 / 4) < 0.01) {
850
- return { aspectRatio: "4:3" };
837
+ return { aspectRatio: '4:3' };
851
838
  }
852
839
  if (Math.abs(ratio - 9 / 16) < 0.01) {
853
- return { aspectRatio: "16:9" };
840
+ return { aspectRatio: '16:9' };
854
841
  }
855
842
  }
856
843
  // Default to 4:3 if no specific aspect ratio is matched
857
- return { aspectRatio: "4:3" };
844
+ return { aspectRatio: '4:3' };
858
845
  }
859
846
  async setAspectRatio(options) {
860
847
  const video = document.getElementById(DEFAULT_VIDEO_ID);
861
848
  if (!video) {
862
- throw new Error("camera is not running");
849
+ throw new Error('camera is not running');
863
850
  }
864
851
  if (options.aspectRatio) {
865
- const [widthRatio, heightRatio] = options.aspectRatio
866
- .split(":")
867
- .map(Number);
852
+ const [widthRatio, heightRatio] = options.aspectRatio.split(':').map(Number);
868
853
  // For camera, use portrait orientation: 4:3 becomes 3:4, 16:9 becomes 9:16
869
854
  const ratio = heightRatio / widthRatio;
870
855
  // Get current position and size
@@ -900,7 +885,7 @@ export class CameraPreviewWeb extends WebPlugin {
900
885
  video.style.height = `${newHeight}px`;
901
886
  video.style.left = `${x}px`;
902
887
  video.style.top = `${y}px`;
903
- video.style.position = "absolute";
888
+ video.style.position = 'absolute';
904
889
  const offsetX = newWidth / 8;
905
890
  const offsetY = newHeight / 8;
906
891
  return {
@@ -911,7 +896,7 @@ export class CameraPreviewWeb extends WebPlugin {
911
896
  };
912
897
  }
913
898
  else {
914
- video.style.objectFit = "cover";
899
+ video.style.objectFit = 'cover';
915
900
  const rect = video.getBoundingClientRect();
916
901
  const offsetX = rect.width / 8;
917
902
  const offsetY = rect.height / 8;
@@ -924,41 +909,41 @@ export class CameraPreviewWeb extends WebPlugin {
924
909
  }
925
910
  }
926
911
  createGridOverlay(gridMode) {
927
- const overlay = document.createElement("div");
928
- overlay.style.position = "absolute";
929
- overlay.style.top = "0";
930
- overlay.style.left = "0";
931
- overlay.style.width = "100%";
932
- overlay.style.height = "100%";
933
- overlay.style.pointerEvents = "none";
934
- overlay.style.zIndex = "10";
935
- const divisions = gridMode === "3x3" ? 3 : 4;
912
+ const overlay = document.createElement('div');
913
+ overlay.style.position = 'absolute';
914
+ overlay.style.top = '0';
915
+ overlay.style.left = '0';
916
+ overlay.style.width = '100%';
917
+ overlay.style.height = '100%';
918
+ overlay.style.pointerEvents = 'none';
919
+ overlay.style.zIndex = '10';
920
+ const divisions = gridMode === '3x3' ? 3 : 4;
936
921
  // Create SVG for grid lines
937
- const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
938
- svg.style.width = "100%";
939
- svg.style.height = "100%";
940
- svg.style.position = "absolute";
941
- svg.style.top = "0";
942
- svg.style.left = "0";
922
+ const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
923
+ svg.style.width = '100%';
924
+ svg.style.height = '100%';
925
+ svg.style.position = 'absolute';
926
+ svg.style.top = '0';
927
+ svg.style.left = '0';
943
928
  // Create grid lines
944
929
  for (let i = 1; i < divisions; i++) {
945
930
  // Vertical lines
946
- const verticalLine = document.createElementNS("http://www.w3.org/2000/svg", "line");
947
- verticalLine.setAttribute("x1", `${(i / divisions) * 100}%`);
948
- verticalLine.setAttribute("y1", "0%");
949
- verticalLine.setAttribute("x2", `${(i / divisions) * 100}%`);
950
- verticalLine.setAttribute("y2", "100%");
951
- verticalLine.setAttribute("stroke", "rgba(255, 255, 255, 0.5)");
952
- verticalLine.setAttribute("stroke-width", "1");
931
+ const verticalLine = document.createElementNS('http://www.w3.org/2000/svg', 'line');
932
+ verticalLine.setAttribute('x1', `${(i / divisions) * 100}%`);
933
+ verticalLine.setAttribute('y1', '0%');
934
+ verticalLine.setAttribute('x2', `${(i / divisions) * 100}%`);
935
+ verticalLine.setAttribute('y2', '100%');
936
+ verticalLine.setAttribute('stroke', 'rgba(255, 255, 255, 0.5)');
937
+ verticalLine.setAttribute('stroke-width', '1');
953
938
  svg.appendChild(verticalLine);
954
939
  // Horizontal lines
955
- const horizontalLine = document.createElementNS("http://www.w3.org/2000/svg", "line");
956
- horizontalLine.setAttribute("x1", "0%");
957
- horizontalLine.setAttribute("y1", `${(i / divisions) * 100}%`);
958
- horizontalLine.setAttribute("x2", "100%");
959
- horizontalLine.setAttribute("y2", `${(i / divisions) * 100}%`);
960
- horizontalLine.setAttribute("stroke", "rgba(255, 255, 255, 0.5)");
961
- horizontalLine.setAttribute("stroke-width", "1");
940
+ const horizontalLine = document.createElementNS('http://www.w3.org/2000/svg', 'line');
941
+ horizontalLine.setAttribute('x1', '0%');
942
+ horizontalLine.setAttribute('y1', `${(i / divisions) * 100}%`);
943
+ horizontalLine.setAttribute('x2', '100%');
944
+ horizontalLine.setAttribute('y2', `${(i / divisions) * 100}%`);
945
+ horizontalLine.setAttribute('stroke', 'rgba(255, 255, 255, 0.5)');
946
+ horizontalLine.setAttribute('stroke-width', '1');
962
947
  svg.appendChild(horizontalLine);
963
948
  }
964
949
  overlay.appendChild(svg);
@@ -971,12 +956,12 @@ export class CameraPreviewWeb extends WebPlugin {
971
956
  }
972
957
  async getGridMode() {
973
958
  // Web implementation - default to none
974
- return { gridMode: "none" };
959
+ return { gridMode: 'none' };
975
960
  }
976
961
  async getPreviewSize() {
977
962
  const video = document.getElementById(DEFAULT_VIDEO_ID);
978
963
  if (!video) {
979
- throw new Error("camera is not running");
964
+ throw new Error('camera is not running');
980
965
  }
981
966
  const offsetX = video.width / 8;
982
967
  const offsetY = video.height / 8;
@@ -990,7 +975,7 @@ export class CameraPreviewWeb extends WebPlugin {
990
975
  async setPreviewSize(options) {
991
976
  const video = document.getElementById(DEFAULT_VIDEO_ID);
992
977
  if (!video) {
993
- throw new Error("camera is not running");
978
+ throw new Error('camera is not running');
994
979
  }
995
980
  video.style.left = `${options.x}px`;
996
981
  video.style.top = `${options.y}px`;
@@ -1008,16 +993,16 @@ export class CameraPreviewWeb extends WebPlugin {
1008
993
  async setFocus(options) {
1009
994
  // Reject if values are outside 0-1 range
1010
995
  if (options.x < 0 || options.x > 1 || options.y < 0 || options.y > 1) {
1011
- throw new Error("Focus coordinates must be between 0 and 1");
996
+ throw new Error('Focus coordinates must be between 0 and 1');
1012
997
  }
1013
998
  const video = document.getElementById(DEFAULT_VIDEO_ID);
1014
999
  if (!(video === null || video === void 0 ? void 0 : video.srcObject)) {
1015
- throw new Error("camera is not running");
1000
+ throw new Error('camera is not running');
1016
1001
  }
1017
1002
  const stream = video.srcObject;
1018
1003
  const videoTrack = stream.getVideoTracks()[0];
1019
1004
  if (!videoTrack) {
1020
- throw new Error("no video track found");
1005
+ throw new Error('no video track found');
1021
1006
  }
1022
1007
  const capabilities = videoTrack.getCapabilities();
1023
1008
  // Check if focusing is supported
@@ -1028,7 +1013,7 @@ export class CameraPreviewWeb extends WebPlugin {
1028
1013
  await videoTrack.applyConstraints({
1029
1014
  advanced: [
1030
1015
  {
1031
- focusMode: "manual",
1016
+ focusMode: 'manual',
1032
1017
  focusDistance: 0.5, // Mid-range focus as fallback
1033
1018
  },
1034
1019
  ],
@@ -1039,32 +1024,32 @@ export class CameraPreviewWeb extends WebPlugin {
1039
1024
  }
1040
1025
  }
1041
1026
  else {
1042
- console.warn("Focus control is not supported on this device. Focus coordinates were provided but cannot be applied.");
1027
+ console.warn('Focus control is not supported on this device. Focus coordinates were provided but cannot be applied.');
1043
1028
  }
1044
1029
  }
1045
1030
  // Exposure stubs (unsupported on web)
1046
1031
  async getExposureModes() {
1047
- throw new Error("getExposureModes not supported under the web platform");
1032
+ throw new Error('getExposureModes not supported under the web platform');
1048
1033
  }
1049
1034
  async getExposureMode() {
1050
- throw new Error("getExposureMode not supported under the web platform");
1035
+ throw new Error('getExposureMode not supported under the web platform');
1051
1036
  }
1052
1037
  async setExposureMode(_options) {
1053
- throw new Error("setExposureMode not supported under the web platform");
1038
+ throw new Error('setExposureMode not supported under the web platform');
1054
1039
  }
1055
1040
  async getExposureCompensationRange() {
1056
- throw new Error("getExposureCompensationRange not supported under the web platform");
1041
+ throw new Error('getExposureCompensationRange not supported under the web platform');
1057
1042
  }
1058
1043
  async getExposureCompensation() {
1059
- throw new Error("getExposureCompensation not supported under the web platform");
1044
+ throw new Error('getExposureCompensation not supported under the web platform');
1060
1045
  }
1061
1046
  async setExposureCompensation(_options) {
1062
- throw new Error("setExposureCompensation not supported under the web platform");
1047
+ throw new Error('setExposureCompensation not supported under the web platform');
1063
1048
  }
1064
1049
  async deleteFile(_options) {
1065
1050
  // Mark parameter as intentionally unused to satisfy linter
1066
1051
  void _options;
1067
- throw new Error("deleteFile not supported under the web platform");
1052
+ throw new Error('deleteFile not supported under the web platform');
1068
1053
  }
1069
1054
  }
1070
1055
  //# sourceMappingURL=web.js.map