@capgo/camera-preview 7.23.10 → 7.23.12

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.
@@ -13,7 +13,7 @@ exports.DeviceType = void 0;
13
13
  DeviceType["TRIPLE"] = "triple";
14
14
  })(exports.DeviceType || (exports.DeviceType = {}));
15
15
 
16
- const CameraPreview = core.registerPlugin("CameraPreview", {
16
+ const CameraPreview = core.registerPlugin('CameraPreview', {
17
17
  web: () => Promise.resolve().then(function () { return web; }).then((m) => new m.CameraPreviewWeb()),
18
18
  });
19
19
  async function getBase64FromFilePath(filePath) {
@@ -27,7 +27,7 @@ async function getBase64FromFilePath(filePath) {
27
27
  const reader = new FileReader();
28
28
  reader.onloadend = () => {
29
29
  const dataUrl = reader.result;
30
- const commaIndex = dataUrl.indexOf(",");
30
+ const commaIndex = dataUrl.indexOf(',');
31
31
  resolve(commaIndex >= 0 ? dataUrl.substring(commaIndex + 1) : dataUrl);
32
32
  };
33
33
  reader.onerror = () => reject(reader.error);
@@ -40,7 +40,7 @@ async function deleteFile(path) {
40
40
  return !!success;
41
41
  }
42
42
 
43
- const DEFAULT_VIDEO_ID = "capgo_video";
43
+ const DEFAULT_VIDEO_ID = 'capgo_video';
44
44
  class CameraPreviewWeb extends core.WebPlugin {
45
45
  constructor() {
46
46
  super();
@@ -56,32 +56,32 @@ class CameraPreviewWeb extends core.WebPlugin {
56
56
  }
57
57
  async checkPermissions(options) {
58
58
  const result = {
59
- camera: "prompt",
59
+ camera: 'prompt',
60
60
  };
61
61
  const permissionsApi = navigator === null || navigator === void 0 ? void 0 : navigator.permissions;
62
62
  if (permissionsApi === null || permissionsApi === void 0 ? void 0 : permissionsApi.query) {
63
63
  try {
64
- const cameraPermission = await permissionsApi.query({ name: "camera" });
64
+ const cameraPermission = await permissionsApi.query({ name: 'camera' });
65
65
  result.camera = this.mapWebPermission(cameraPermission.state);
66
66
  }
67
67
  catch (error) {
68
- console.warn("Camera permission query failed", error);
68
+ console.warn('Camera permission query failed', error);
69
69
  }
70
70
  if ((options === null || options === void 0 ? void 0 : options.disableAudio) === false) {
71
71
  try {
72
72
  const microphonePermission = await permissionsApi.query({
73
- name: "microphone",
73
+ name: 'microphone',
74
74
  });
75
75
  result.microphone = this.mapWebPermission(microphonePermission.state);
76
76
  }
77
77
  catch (error) {
78
- console.warn("Microphone permission query failed", error);
79
- result.microphone = "prompt";
78
+ console.warn('Microphone permission query failed', error);
79
+ result.microphone = 'prompt';
80
80
  }
81
81
  }
82
82
  }
83
83
  else if ((options === null || options === void 0 ? void 0 : options.disableAudio) === false) {
84
- result.microphone = "prompt";
84
+ result.microphone = 'prompt';
85
85
  }
86
86
  return result;
87
87
  }
@@ -89,15 +89,13 @@ class CameraPreviewWeb extends core.WebPlugin {
89
89
  var _a, _b;
90
90
  const disableAudio = (_a = options === null || options === void 0 ? void 0 : options.disableAudio) !== null && _a !== void 0 ? _a : true;
91
91
  if ((_b = navigator === null || navigator === void 0 ? void 0 : navigator.mediaDevices) === null || _b === void 0 ? void 0 : _b.getUserMedia) {
92
- const constraints = disableAudio
93
- ? { video: true }
94
- : { video: true, audio: true };
92
+ const constraints = disableAudio ? { video: true } : { video: true, audio: true };
95
93
  let stream;
96
94
  try {
97
95
  stream = await navigator.mediaDevices.getUserMedia(constraints);
98
96
  }
99
97
  catch (error) {
100
- console.warn("Unable to obtain camera or microphone stream", error);
98
+ console.warn('Unable to obtain camera or microphone stream', error);
101
99
  }
102
100
  finally {
103
101
  try {
@@ -110,19 +108,19 @@ class CameraPreviewWeb extends core.WebPlugin {
110
108
  }
111
109
  const status = await this.checkPermissions({ disableAudio: disableAudio });
112
110
  if (options === null || options === void 0 ? void 0 : options.showSettingsAlert) {
113
- console.warn("showSettingsAlert is not supported on the web platform; returning permission status only.");
111
+ console.warn('showSettingsAlert is not supported on the web platform; returning permission status only.');
114
112
  }
115
113
  return status;
116
114
  }
117
115
  mapWebPermission(state) {
118
116
  switch (state) {
119
- case "granted":
120
- return "granted";
121
- case "denied":
122
- return "denied";
123
- case "prompt":
117
+ case 'granted':
118
+ return 'granted';
119
+ case 'denied':
120
+ return 'denied';
121
+ case 'prompt':
124
122
  default:
125
- return "prompt";
123
+ return 'prompt';
126
124
  }
127
125
  }
128
126
  getCurrentOrientation() {
@@ -130,113 +128,111 @@ class CameraPreviewWeb extends core.WebPlugin {
130
128
  try {
131
129
  const so = screen.orientation;
132
130
  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);
133
- if (typeof type === "string") {
134
- if (type.includes("portrait-primary"))
135
- return "portrait";
136
- if (type.includes("portrait-secondary"))
137
- return "portrait-upside-down";
138
- if (type.includes("landscape-primary"))
139
- return "landscape-left";
140
- if (type.includes("landscape-secondary"))
141
- return "landscape-right";
142
- if (type.includes("landscape"))
143
- return "landscape-right"; // avoid generic landscape
144
- if (type.includes("portrait"))
145
- return "portrait";
131
+ if (typeof type === 'string') {
132
+ if (type.includes('portrait-primary'))
133
+ return 'portrait';
134
+ if (type.includes('portrait-secondary'))
135
+ return 'portrait-upside-down';
136
+ if (type.includes('landscape-primary'))
137
+ return 'landscape-left';
138
+ if (type.includes('landscape-secondary'))
139
+ return 'landscape-right';
140
+ if (type.includes('landscape'))
141
+ return 'landscape-right'; // avoid generic landscape
142
+ if (type.includes('portrait'))
143
+ return 'portrait';
146
144
  }
147
145
  const angle = window.orientation;
148
- if (typeof angle === "number") {
146
+ if (typeof angle === 'number') {
149
147
  if (angle === 0)
150
- return "portrait";
148
+ return 'portrait';
151
149
  if (angle === 180)
152
- return "portrait-upside-down";
150
+ return 'portrait-upside-down';
153
151
  if (angle === 90)
154
- return "landscape-right";
152
+ return 'landscape-right';
155
153
  if (angle === -90)
156
- return "landscape-left";
154
+ return 'landscape-left';
157
155
  if (angle === 270)
158
- return "landscape-left";
156
+ return 'landscape-left';
159
157
  }
160
- if ((_a = window.matchMedia("(orientation: portrait)")) === null || _a === void 0 ? void 0 : _a.matches) {
161
- return "portrait";
158
+ if ((_a = window.matchMedia('(orientation: portrait)')) === null || _a === void 0 ? void 0 : _a.matches) {
159
+ return 'portrait';
162
160
  }
163
- if ((_b = window.matchMedia("(orientation: landscape)")) === null || _b === void 0 ? void 0 : _b.matches) {
161
+ if ((_b = window.matchMedia('(orientation: landscape)')) === null || _b === void 0 ? void 0 : _b.matches) {
164
162
  // Default to landscape-right when we can't distinguish primary/secondary
165
- return "landscape-right";
163
+ return 'landscape-right';
166
164
  }
167
165
  }
168
166
  catch (e) {
169
167
  console.error(e);
170
168
  }
171
- return "unknown";
169
+ return 'unknown';
172
170
  }
173
171
  ensureOrientationListener() {
174
172
  if (this.orientationListenerBound)
175
173
  return;
176
174
  const emit = () => {
177
- this.notifyListeners("orientationChange", {
175
+ this.notifyListeners('orientationChange', {
178
176
  orientation: this.getCurrentOrientation(),
179
177
  });
180
178
  };
181
- window.addEventListener("orientationchange", emit);
182
- window.addEventListener("resize", emit);
179
+ window.addEventListener('orientationchange', emit);
180
+ window.addEventListener('resize', emit);
183
181
  this.orientationListenerBound = true;
184
182
  }
185
183
  async getOrientation() {
186
184
  return { orientation: this.getCurrentOrientation() };
187
185
  }
188
186
  getSafeAreaInsets() {
189
- throw new Error("Method not implemented.");
187
+ throw new Error('Method not implemented.');
190
188
  }
191
189
  async getZoomButtonValues() {
192
- throw new Error("getZoomButtonValues not supported under the web platform");
190
+ throw new Error('getZoomButtonValues not supported under the web platform');
193
191
  }
194
192
  async getSupportedPictureSizes() {
195
- throw new Error("getSupportedPictureSizes not supported under the web platform");
193
+ throw new Error('getSupportedPictureSizes not supported under the web platform');
196
194
  }
197
195
  async start(options) {
198
196
  if (options.aspectRatio && (options.width || options.height)) {
199
- throw new Error("Cannot set both aspectRatio and size (width/height). Use setPreviewSize after start.");
197
+ throw new Error('Cannot set both aspectRatio and size (width/height). Use setPreviewSize after start.');
200
198
  }
201
199
  if (this.isStarted) {
202
- throw new Error("camera already started");
200
+ throw new Error('camera already started');
203
201
  }
204
202
  this.isBackCamera = true;
205
203
  this.isStarted = false;
206
- const parent = document.getElementById((options === null || options === void 0 ? void 0 : options.parent) || "");
207
- const gridMode = (options === null || options === void 0 ? void 0 : options.gridMode) || "none";
208
- const positioning = (options === null || options === void 0 ? void 0 : options.positioning) || "top";
204
+ const parent = document.getElementById((options === null || options === void 0 ? void 0 : options.parent) || '');
205
+ const gridMode = (options === null || options === void 0 ? void 0 : options.gridMode) || 'none';
206
+ const positioning = (options === null || options === void 0 ? void 0 : options.positioning) || 'top';
209
207
  if (options.position) {
210
- this.isBackCamera = options.position === "rear";
208
+ this.isBackCamera = options.position === 'rear';
211
209
  }
212
210
  const video = document.getElementById(DEFAULT_VIDEO_ID);
213
211
  if (video) {
214
212
  video.remove();
215
213
  }
216
- const container = options.parent
217
- ? document.getElementById(options.parent)
218
- : document.body;
214
+ const container = options.parent ? document.getElementById(options.parent) : document.body;
219
215
  if (!container) {
220
- throw new Error("container not found");
216
+ throw new Error('container not found');
221
217
  }
222
- this.videoElement = document.createElement("video");
218
+ this.videoElement = document.createElement('video');
223
219
  this.videoElement.id = DEFAULT_VIDEO_ID;
224
- this.videoElement.className = options.className || "";
220
+ this.videoElement.className = options.className || '';
225
221
  this.videoElement.playsInline = true;
226
222
  this.videoElement.muted = true;
227
223
  this.videoElement.autoplay = true;
228
224
  // Remove objectFit as we'll match camera's native aspect ratio
229
- this.videoElement.style.backgroundColor = "transparent";
225
+ this.videoElement.style.backgroundColor = 'transparent';
230
226
  // Reset any default margins that might interfere
231
- this.videoElement.style.margin = "0";
232
- this.videoElement.style.padding = "0";
227
+ this.videoElement.style.margin = '0';
228
+ this.videoElement.style.padding = '0';
233
229
  container.appendChild(this.videoElement);
234
230
  if (options.toBack) {
235
- this.videoElement.style.zIndex = "-1";
231
+ this.videoElement.style.zIndex = '-1';
236
232
  }
237
233
  // Default to 4:3 if no aspect ratio or size specified
238
234
  const useDefaultAspectRatio = !options.aspectRatio && !options.width && !options.height;
239
- const effectiveAspectRatio = options.aspectRatio || (useDefaultAspectRatio ? "4:3" : null);
235
+ const effectiveAspectRatio = options.aspectRatio || (useDefaultAspectRatio ? '4:3' : null);
240
236
  if (options.width) {
241
237
  this.videoElement.width = options.width;
242
238
  this.videoElement.style.width = `${options.width}px`;
@@ -249,8 +245,8 @@ class CameraPreviewWeb extends core.WebPlugin {
249
245
  const centerX = options.x === undefined;
250
246
  const centerY = options.y === undefined;
251
247
  // Always set position to absolute for proper positioning
252
- this.videoElement.style.position = "absolute";
253
- console.log("Initial positioning flags:", {
248
+ this.videoElement.style.position = 'absolute';
249
+ console.log('Initial positioning flags:', {
254
250
  centerX,
255
251
  centerY,
256
252
  x: options.x,
@@ -263,28 +259,28 @@ class CameraPreviewWeb extends core.WebPlugin {
263
259
  this.videoElement.style.top = `${options.y}px`;
264
260
  }
265
261
  // Create and add grid overlay if needed
266
- if (gridMode !== "none") {
262
+ if (gridMode !== 'none') {
267
263
  const gridOverlay = this.createGridOverlay(gridMode);
268
- gridOverlay.id = "camera-grid-overlay";
264
+ gridOverlay.id = 'camera-grid-overlay';
269
265
  parent === null || parent === void 0 ? void 0 : parent.appendChild(gridOverlay);
270
266
  }
271
267
  // Aspect ratio handling is now done after getting camera stream
272
268
  // Store centering flags for later use
273
269
  const needsCenterX = centerX;
274
270
  const needsCenterY = centerY;
275
- console.log("Centering flags stored:", { needsCenterX, needsCenterY });
271
+ console.log('Centering flags stored:', { needsCenterX, needsCenterY });
276
272
  // First get the camera stream with basic constraints
277
273
  const constraints = {
278
274
  video: {
279
- facingMode: this.isBackCamera ? "environment" : "user",
275
+ facingMode: this.isBackCamera ? 'environment' : 'user',
280
276
  },
281
277
  };
282
278
  const stream = await navigator.mediaDevices.getUserMedia(constraints);
283
279
  if (!stream) {
284
- throw new Error("could not acquire stream");
280
+ throw new Error('could not acquire stream');
285
281
  }
286
282
  if (!this.videoElement) {
287
- throw new Error("video element not found");
283
+ throw new Error('video element not found');
288
284
  }
289
285
  // Get the actual camera dimensions from the video track
290
286
  const videoTrack = stream.getVideoTracks()[0];
@@ -292,12 +288,12 @@ class CameraPreviewWeb extends core.WebPlugin {
292
288
  const cameraWidth = settings.width || 640;
293
289
  const cameraHeight = settings.height || 480;
294
290
  const cameraAspectRatio = cameraWidth / cameraHeight;
295
- console.log("Camera native dimensions:", {
291
+ console.log('Camera native dimensions:', {
296
292
  width: cameraWidth,
297
293
  height: cameraHeight,
298
294
  aspectRatio: cameraAspectRatio,
299
295
  });
300
- console.log("Container dimensions:", {
296
+ console.log('Container dimensions:', {
301
297
  width: container.offsetWidth,
302
298
  height: container.offsetHeight,
303
299
  id: container.id,
@@ -317,7 +313,7 @@ class CameraPreviewWeb extends core.WebPlugin {
317
313
  targetHeight = containerHeight;
318
314
  targetWidth = targetHeight * cameraAspectRatio;
319
315
  }
320
- console.log("Video element dimensions:", {
316
+ console.log('Video element dimensions:', {
321
317
  width: targetWidth,
322
318
  height: targetHeight,
323
319
  container: { width: containerWidth, height: containerHeight },
@@ -334,21 +330,21 @@ class CameraPreviewWeb extends core.WebPlugin {
334
330
  if (needsCenterY || options.y === undefined) {
335
331
  let y;
336
332
  switch (positioning) {
337
- case "top":
333
+ case 'top':
338
334
  y = 0;
339
335
  break;
340
- case "bottom":
336
+ case 'bottom':
341
337
  y = window.innerHeight - targetHeight;
342
338
  break;
343
- case "center":
339
+ case 'center':
344
340
  default:
345
341
  y = Math.round((window.innerHeight - targetHeight) / 2);
346
342
  break;
347
343
  }
348
- this.videoElement.style.setProperty("top", `${y}px`, "important");
344
+ this.videoElement.style.setProperty('top', `${y}px`, 'important');
349
345
  // Force a style recalculation
350
346
  this.videoElement.offsetHeight;
351
- console.log("Positioning video:", {
347
+ console.log('Positioning video:', {
352
348
  positioning,
353
349
  viewportHeight: window.innerHeight,
354
350
  targetHeight,
@@ -360,9 +356,7 @@ class CameraPreviewWeb extends core.WebPlugin {
360
356
  }
361
357
  else if (effectiveAspectRatio && !options.width && !options.height) {
362
358
  // Aspect ratio specified but no size
363
- const [widthRatio, heightRatio] = effectiveAspectRatio
364
- .split(":")
365
- .map(Number);
359
+ const [widthRatio, heightRatio] = effectiveAspectRatio.split(':').map(Number);
366
360
  const targetRatio = widthRatio / heightRatio;
367
361
  const viewportWidth = window.innerWidth;
368
362
  const viewportHeight = window.innerHeight;
@@ -389,13 +383,13 @@ class CameraPreviewWeb extends core.WebPlugin {
389
383
  const parentHeight = container.offsetHeight || viewportHeight;
390
384
  let y;
391
385
  switch (positioning) {
392
- case "top":
386
+ case 'top':
393
387
  y = 0;
394
388
  break;
395
- case "bottom":
389
+ case 'bottom':
396
390
  y = parentHeight - targetHeight;
397
391
  break;
398
- case "center":
392
+ case 'center':
399
393
  default:
400
394
  y = Math.round((parentHeight - targetHeight) / 2);
401
395
  break;
@@ -405,11 +399,10 @@ class CameraPreviewWeb extends core.WebPlugin {
405
399
  }
406
400
  this.videoElement.srcObject = stream;
407
401
  if (!this.isBackCamera) {
408
- this.videoElement.style.transform = "scaleX(-1)";
402
+ this.videoElement.style.transform = 'scaleX(-1)';
409
403
  }
410
404
  // Set initial zoom level if specified and supported
411
- if (options.initialZoomLevel !== undefined &&
412
- options.initialZoomLevel !== 1.0) {
405
+ if (options.initialZoomLevel !== undefined && options.initialZoomLevel !== 1.0) {
413
406
  // videoTrack already declared above
414
407
  if (videoTrack) {
415
408
  const capabilities = videoTrack.getCapabilities();
@@ -439,26 +432,26 @@ class CameraPreviewWeb extends core.WebPlugin {
439
432
  await new Promise((resolve) => {
440
433
  const videoEl = this.videoElement;
441
434
  if (!videoEl) {
442
- throw new Error("video element not found");
435
+ throw new Error('video element not found');
443
436
  }
444
437
  if (videoEl.readyState >= 2) {
445
438
  resolve();
446
439
  }
447
440
  else {
448
- videoEl.addEventListener("loadeddata", () => resolve(), {
441
+ videoEl.addEventListener('loadeddata', () => resolve(), {
449
442
  once: true,
450
443
  });
451
444
  }
452
445
  });
453
446
  // Ensure centering is applied after DOM updates
454
447
  await new Promise((resolve) => requestAnimationFrame(resolve));
455
- console.log("About to re-center, flags:", { needsCenterX, needsCenterY });
448
+ console.log('About to re-center, flags:', { needsCenterX, needsCenterY });
456
449
  // Re-apply centering with correct parent dimensions
457
450
  if (needsCenterX) {
458
451
  const parentWidth = container.offsetWidth;
459
452
  const x = Math.round((parentWidth - this.videoElement.offsetWidth) / 2);
460
453
  this.videoElement.style.left = `${x}px`;
461
- console.log("Re-centering X:", {
454
+ console.log('Re-centering X:', {
462
455
  parentWidth,
463
456
  videoWidth: this.videoElement.offsetWidth,
464
457
  x,
@@ -467,19 +460,19 @@ class CameraPreviewWeb extends core.WebPlugin {
467
460
  if (needsCenterY) {
468
461
  let y;
469
462
  switch (positioning) {
470
- case "top":
463
+ case 'top':
471
464
  y = 0;
472
465
  break;
473
- case "bottom":
466
+ case 'bottom':
474
467
  y = window.innerHeight - this.videoElement.offsetHeight;
475
468
  break;
476
- case "center":
469
+ case 'center':
477
470
  default:
478
471
  y = Math.round((window.innerHeight - this.videoElement.offsetHeight) / 2);
479
472
  break;
480
473
  }
481
- this.videoElement.style.setProperty("top", `${y}px`, "important");
482
- console.log("Re-positioning Y:", {
474
+ this.videoElement.style.setProperty('top', `${y}px`, 'important');
475
+ console.log('Re-positioning Y:', {
483
476
  positioning,
484
477
  viewportHeight: window.innerHeight,
485
478
  videoHeight: this.videoElement.offsetHeight,
@@ -491,7 +484,7 @@ class CameraPreviewWeb extends core.WebPlugin {
491
484
  // Get the actual rendered dimensions after video is loaded
492
485
  const rect = this.videoElement.getBoundingClientRect();
493
486
  const computedStyle = window.getComputedStyle(this.videoElement);
494
- console.log("Final video element state:", {
487
+ console.log('Final video element state:', {
495
488
  rect: { x: rect.x, y: rect.y, width: rect.width, height: rect.height },
496
489
  style: {
497
490
  position: computedStyle.position,
@@ -524,21 +517,21 @@ class CameraPreviewWeb extends core.WebPlugin {
524
517
  this.isStarted = false;
525
518
  }
526
519
  // Remove grid overlay if it exists
527
- const gridOverlay = document.getElementById("camera-grid-overlay");
520
+ const gridOverlay = document.getElementById('camera-grid-overlay');
528
521
  gridOverlay === null || gridOverlay === void 0 ? void 0 : gridOverlay.remove();
529
522
  }
530
523
  async capture(options) {
531
524
  return new Promise((resolve, reject) => {
532
525
  const video = document.getElementById(DEFAULT_VIDEO_ID);
533
526
  if (!(video === null || video === void 0 ? void 0 : video.srcObject)) {
534
- reject(new Error("camera is not running"));
527
+ reject(new Error('camera is not running'));
535
528
  return;
536
529
  }
537
530
  // video.width = video.offsetWidth;
538
531
  let base64EncodedImage;
539
532
  if (video && video.videoWidth > 0 && video.videoHeight > 0) {
540
- const canvas = document.createElement("canvas");
541
- const context = canvas.getContext("2d");
533
+ const canvas = document.createElement('canvas');
534
+ const context = canvas.getContext('2d');
542
535
  // Calculate capture dimensions
543
536
  let captureWidth = video.videoWidth;
544
537
  let captureHeight = video.videoHeight;
@@ -585,15 +578,13 @@ class CameraPreviewWeb extends core.WebPlugin {
585
578
  context === null || context === void 0 ? void 0 : context.drawImage(video, sourceX, sourceY, captureWidth, captureHeight, 0, 0, captureWidth, captureHeight);
586
579
  if (options.saveToGallery) ;
587
580
  if (options.withExifLocation) ;
588
- if ((options.format || "jpeg") === "jpeg") {
581
+ if ((options.format || 'jpeg') === 'jpeg') {
589
582
  base64EncodedImage = canvas
590
- .toDataURL("image/jpeg", (options.quality || 85) / 100.0)
591
- .replace("data:image/jpeg;base64,", "");
583
+ .toDataURL('image/jpeg', (options.quality || 85) / 100.0)
584
+ .replace('data:image/jpeg;base64,', '');
592
585
  }
593
586
  else {
594
- base64EncodedImage = canvas
595
- .toDataURL("image/png")
596
- .replace("data:image/png;base64,", "");
587
+ base64EncodedImage = canvas.toDataURL('image/png').replace('data:image/png;base64,', '');
597
588
  }
598
589
  }
599
590
  resolve({
@@ -606,17 +597,17 @@ class CameraPreviewWeb extends core.WebPlugin {
606
597
  return this.capture(_options);
607
598
  }
608
599
  async stopRecordVideo() {
609
- throw new Error("stopRecordVideo not supported under the web platform");
600
+ throw new Error('stopRecordVideo not supported under the web platform');
610
601
  }
611
602
  async startRecordVideo(_options) {
612
- console.log("startRecordVideo", _options);
613
- throw new Error("startRecordVideo not supported under the web platform");
603
+ console.log('startRecordVideo', _options);
604
+ throw new Error('startRecordVideo not supported under the web platform');
614
605
  }
615
606
  async getSupportedFlashModes() {
616
- throw new Error("getSupportedFlashModes not supported under the web platform");
607
+ throw new Error('getSupportedFlashModes not supported under the web platform');
617
608
  }
618
609
  async getHorizontalFov() {
619
- throw new Error("getHorizontalFov not supported under the web platform");
610
+ throw new Error('getHorizontalFov not supported under the web platform');
620
611
  }
621
612
  async setFlashMode(_options) {
622
613
  throw new Error(`setFlashMode not supported under the web platform${_options}`);
@@ -624,7 +615,7 @@ class CameraPreviewWeb extends core.WebPlugin {
624
615
  async flip() {
625
616
  const video = document.getElementById(DEFAULT_VIDEO_ID);
626
617
  if (!(video === null || video === void 0 ? void 0 : video.srcObject)) {
627
- throw new Error("camera is not running");
618
+ throw new Error('camera is not running');
628
619
  }
629
620
  // Stop current stream
630
621
  this.stopStream(video.srcObject);
@@ -633,7 +624,7 @@ class CameraPreviewWeb extends core.WebPlugin {
633
624
  // Get new constraints
634
625
  const constraints = {
635
626
  video: {
636
- facingMode: this.isBackCamera ? "environment" : "user",
627
+ facingMode: this.isBackCamera ? 'environment' : 'user',
637
628
  width: { ideal: video.videoWidth || 640 },
638
629
  height: { ideal: video.videoHeight || 480 },
639
630
  },
@@ -648,12 +639,12 @@ class CameraPreviewWeb extends core.WebPlugin {
648
639
  }
649
640
  // Update video transform based on camera
650
641
  if (this.isBackCamera) {
651
- video.style.transform = "none";
652
- video.style.webkitTransform = "none";
642
+ video.style.transform = 'none';
643
+ video.style.webkitTransform = 'none';
653
644
  }
654
645
  else {
655
- video.style.transform = "scaleX(-1)";
656
- video.style.webkitTransform = "scaleX(-1)";
646
+ video.style.transform = 'scaleX(-1)';
647
+ video.style.webkitTransform = 'scaleX(-1)';
657
648
  }
658
649
  await video.play();
659
650
  }
@@ -664,7 +655,7 @@ class CameraPreviewWeb extends core.WebPlugin {
664
655
  async setOpacity(_options) {
665
656
  const video = document.getElementById(DEFAULT_VIDEO_ID);
666
657
  if (!!video && !!_options.opacity)
667
- video.style.setProperty("opacity", _options.opacity.toString());
658
+ video.style.setProperty('opacity', _options.opacity.toString());
668
659
  }
669
660
  async isRunning() {
670
661
  const video = document.getElementById(DEFAULT_VIDEO_ID);
@@ -673,10 +664,10 @@ class CameraPreviewWeb extends core.WebPlugin {
673
664
  async getAvailableDevices() {
674
665
  var _a;
675
666
  if (!((_a = navigator.mediaDevices) === null || _a === void 0 ? void 0 : _a.enumerateDevices)) {
676
- throw new Error("getAvailableDevices not supported under the web platform");
667
+ throw new Error('getAvailableDevices not supported under the web platform');
677
668
  }
678
669
  const devices = await navigator.mediaDevices.enumerateDevices();
679
- const videoDevices = devices.filter((device) => device.kind === "videoinput");
670
+ const videoDevices = devices.filter((device) => device.kind === 'videoinput');
680
671
  // Group devices by position (front/back)
681
672
  const frontDevices = [];
682
673
  const backDevices = [];
@@ -686,19 +677,18 @@ class CameraPreviewWeb extends core.WebPlugin {
686
677
  // Determine device type based on label
687
678
  let deviceType = exports.DeviceType.WIDE_ANGLE;
688
679
  let baseZoomRatio = 1.0;
689
- if (labelLower.includes("ultra") || labelLower.includes("0.5")) {
680
+ if (labelLower.includes('ultra') || labelLower.includes('0.5')) {
690
681
  deviceType = exports.DeviceType.ULTRA_WIDE;
691
682
  baseZoomRatio = 0.5;
692
683
  }
693
- else if (labelLower.includes("telephoto") ||
694
- labelLower.includes("tele") ||
695
- labelLower.includes("2x") ||
696
- labelLower.includes("3x")) {
684
+ else if (labelLower.includes('telephoto') ||
685
+ labelLower.includes('tele') ||
686
+ labelLower.includes('2x') ||
687
+ labelLower.includes('3x')) {
697
688
  deviceType = exports.DeviceType.TELEPHOTO;
698
689
  baseZoomRatio = 2.0;
699
690
  }
700
- else if (labelLower.includes("depth") ||
701
- labelLower.includes("truedepth")) {
691
+ else if (labelLower.includes('depth') || labelLower.includes('truedepth')) {
702
692
  deviceType = exports.DeviceType.TRUE_DEPTH;
703
693
  baseZoomRatio = 1.0;
704
694
  }
@@ -712,7 +702,7 @@ class CameraPreviewWeb extends core.WebPlugin {
712
702
  maxZoom: 1.0,
713
703
  };
714
704
  // Determine position and add to appropriate array
715
- if (labelLower.includes("back") || labelLower.includes("rear")) {
705
+ if (labelLower.includes('back') || labelLower.includes('rear')) {
716
706
  backDevices.push(lensInfo);
717
707
  }
718
708
  else {
@@ -723,8 +713,8 @@ class CameraPreviewWeb extends core.WebPlugin {
723
713
  if (frontDevices.length > 0) {
724
714
  result.push({
725
715
  deviceId: frontDevices[0].deviceId,
726
- label: "Front Camera",
727
- position: "front",
716
+ label: 'Front Camera',
717
+ position: 'front',
728
718
  lenses: frontDevices,
729
719
  isLogical: false,
730
720
  minZoom: Math.min(...frontDevices.map((d) => d.minZoom)),
@@ -734,8 +724,8 @@ class CameraPreviewWeb extends core.WebPlugin {
734
724
  if (backDevices.length > 0) {
735
725
  result.push({
736
726
  deviceId: backDevices[0].deviceId,
737
- label: "Back Camera",
738
- position: "rear",
727
+ label: 'Back Camera',
728
+ position: 'rear',
739
729
  lenses: backDevices,
740
730
  isLogical: false,
741
731
  minZoom: Math.min(...backDevices.map((d) => d.minZoom)),
@@ -747,17 +737,17 @@ class CameraPreviewWeb extends core.WebPlugin {
747
737
  async getZoom() {
748
738
  const video = document.getElementById(DEFAULT_VIDEO_ID);
749
739
  if (!(video === null || video === void 0 ? void 0 : video.srcObject)) {
750
- throw new Error("camera is not running");
740
+ throw new Error('camera is not running');
751
741
  }
752
742
  const stream = video.srcObject;
753
743
  const videoTrack = stream.getVideoTracks()[0];
754
744
  if (!videoTrack) {
755
- throw new Error("no video track found");
745
+ throw new Error('no video track found');
756
746
  }
757
747
  const capabilities = videoTrack.getCapabilities();
758
748
  const settings = videoTrack.getSettings();
759
749
  if (!capabilities.zoom) {
760
- throw new Error("zoom not supported by this device");
750
+ throw new Error('zoom not supported by this device');
761
751
  }
762
752
  // Get current device info to determine lens type
763
753
  let deviceType = exports.DeviceType.WIDE_ANGLE;
@@ -767,19 +757,18 @@ class CameraPreviewWeb extends core.WebPlugin {
767
757
  const device = devices.find((d) => d.deviceId === this.currentDeviceId);
768
758
  if (device) {
769
759
  const labelLower = device.label.toLowerCase();
770
- if (labelLower.includes("ultra") || labelLower.includes("0.5")) {
760
+ if (labelLower.includes('ultra') || labelLower.includes('0.5')) {
771
761
  deviceType = exports.DeviceType.ULTRA_WIDE;
772
762
  baseZoomRatio = 0.5;
773
763
  }
774
- else if (labelLower.includes("telephoto") ||
775
- labelLower.includes("tele") ||
776
- labelLower.includes("2x") ||
777
- labelLower.includes("3x")) {
764
+ else if (labelLower.includes('telephoto') ||
765
+ labelLower.includes('tele') ||
766
+ labelLower.includes('2x') ||
767
+ labelLower.includes('3x')) {
778
768
  deviceType = exports.DeviceType.TELEPHOTO;
779
769
  baseZoomRatio = 2.0;
780
770
  }
781
- else if (labelLower.includes("depth") ||
782
- labelLower.includes("truedepth")) {
771
+ else if (labelLower.includes('depth') || labelLower.includes('truedepth')) {
783
772
  deviceType = exports.DeviceType.TRUE_DEPTH;
784
773
  baseZoomRatio = 1.0;
785
774
  }
@@ -802,16 +791,16 @@ class CameraPreviewWeb extends core.WebPlugin {
802
791
  async setZoom(options) {
803
792
  const video = document.getElementById(DEFAULT_VIDEO_ID);
804
793
  if (!(video === null || video === void 0 ? void 0 : video.srcObject)) {
805
- throw new Error("camera is not running");
794
+ throw new Error('camera is not running');
806
795
  }
807
796
  const stream = video.srcObject;
808
797
  const videoTrack = stream.getVideoTracks()[0];
809
798
  if (!videoTrack) {
810
- throw new Error("no video track found");
799
+ throw new Error('no video track found');
811
800
  }
812
801
  const capabilities = videoTrack.getCapabilities();
813
802
  if (!capabilities.zoom) {
814
- throw new Error("zoom not supported by this device");
803
+ throw new Error('zoom not supported by this device');
815
804
  }
816
805
  const zoomLevel = Math.max(capabilities.zoom.min || 1, Math.min(capabilities.zoom.max || 1, options.level));
817
806
  // Note: autoFocus is not supported on web platform
@@ -825,15 +814,15 @@ class CameraPreviewWeb extends core.WebPlugin {
825
814
  }
826
815
  }
827
816
  async getFlashMode() {
828
- throw new Error("getFlashMode not supported under the web platform");
817
+ throw new Error('getFlashMode not supported under the web platform');
829
818
  }
830
819
  async getDeviceId() {
831
- return { deviceId: this.currentDeviceId || "" };
820
+ return { deviceId: this.currentDeviceId || '' };
832
821
  }
833
822
  async setDeviceId(options) {
834
823
  const video = document.getElementById(DEFAULT_VIDEO_ID);
835
824
  if (!(video === null || video === void 0 ? void 0 : video.srcObject)) {
836
- throw new Error("camera is not running");
825
+ throw new Error('camera is not running');
837
826
  }
838
827
  // Stop current stream
839
828
  this.stopStream(video.srcObject);
@@ -852,19 +841,17 @@ class CameraPreviewWeb extends core.WebPlugin {
852
841
  const devices = await navigator.mediaDevices.enumerateDevices();
853
842
  const device = devices.find((d) => d.deviceId === options.deviceId);
854
843
  this.isBackCamera =
855
- (device === null || device === void 0 ? void 0 : device.label.toLowerCase().includes("back")) ||
856
- (device === null || device === void 0 ? void 0 : device.label.toLowerCase().includes("rear")) ||
857
- false;
844
+ (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;
858
845
  const stream = await navigator.mediaDevices.getUserMedia(constraints);
859
846
  video.srcObject = stream;
860
847
  // Update video transform based on camera
861
848
  if (this.isBackCamera) {
862
- video.style.transform = "none";
863
- video.style.webkitTransform = "none";
849
+ video.style.transform = 'none';
850
+ video.style.webkitTransform = 'none';
864
851
  }
865
852
  else {
866
- video.style.transform = "scaleX(-1)";
867
- video.style.webkitTransform = "scaleX(-1)";
853
+ video.style.transform = 'scaleX(-1)';
854
+ video.style.webkitTransform = 'scaleX(-1)';
868
855
  }
869
856
  await video.play();
870
857
  }
@@ -875,7 +862,7 @@ class CameraPreviewWeb extends core.WebPlugin {
875
862
  async getAspectRatio() {
876
863
  const video = document.getElementById(DEFAULT_VIDEO_ID);
877
864
  if (!video) {
878
- throw new Error("camera is not running");
865
+ throw new Error('camera is not running');
879
866
  }
880
867
  const width = video.offsetWidth;
881
868
  const height = video.offsetHeight;
@@ -883,24 +870,22 @@ class CameraPreviewWeb extends core.WebPlugin {
883
870
  const ratio = width / height;
884
871
  // Check for portrait camera ratios: 4:3 -> 3:4, 16:9 -> 9:16
885
872
  if (Math.abs(ratio - 3 / 4) < 0.01) {
886
- return { aspectRatio: "4:3" };
873
+ return { aspectRatio: '4:3' };
887
874
  }
888
875
  if (Math.abs(ratio - 9 / 16) < 0.01) {
889
- return { aspectRatio: "16:9" };
876
+ return { aspectRatio: '16:9' };
890
877
  }
891
878
  }
892
879
  // Default to 4:3 if no specific aspect ratio is matched
893
- return { aspectRatio: "4:3" };
880
+ return { aspectRatio: '4:3' };
894
881
  }
895
882
  async setAspectRatio(options) {
896
883
  const video = document.getElementById(DEFAULT_VIDEO_ID);
897
884
  if (!video) {
898
- throw new Error("camera is not running");
885
+ throw new Error('camera is not running');
899
886
  }
900
887
  if (options.aspectRatio) {
901
- const [widthRatio, heightRatio] = options.aspectRatio
902
- .split(":")
903
- .map(Number);
888
+ const [widthRatio, heightRatio] = options.aspectRatio.split(':').map(Number);
904
889
  // For camera, use portrait orientation: 4:3 becomes 3:4, 16:9 becomes 9:16
905
890
  const ratio = heightRatio / widthRatio;
906
891
  // Get current position and size
@@ -936,7 +921,7 @@ class CameraPreviewWeb extends core.WebPlugin {
936
921
  video.style.height = `${newHeight}px`;
937
922
  video.style.left = `${x}px`;
938
923
  video.style.top = `${y}px`;
939
- video.style.position = "absolute";
924
+ video.style.position = 'absolute';
940
925
  const offsetX = newWidth / 8;
941
926
  const offsetY = newHeight / 8;
942
927
  return {
@@ -947,7 +932,7 @@ class CameraPreviewWeb extends core.WebPlugin {
947
932
  };
948
933
  }
949
934
  else {
950
- video.style.objectFit = "cover";
935
+ video.style.objectFit = 'cover';
951
936
  const rect = video.getBoundingClientRect();
952
937
  const offsetX = rect.width / 8;
953
938
  const offsetY = rect.height / 8;
@@ -960,41 +945,41 @@ class CameraPreviewWeb extends core.WebPlugin {
960
945
  }
961
946
  }
962
947
  createGridOverlay(gridMode) {
963
- const overlay = document.createElement("div");
964
- overlay.style.position = "absolute";
965
- overlay.style.top = "0";
966
- overlay.style.left = "0";
967
- overlay.style.width = "100%";
968
- overlay.style.height = "100%";
969
- overlay.style.pointerEvents = "none";
970
- overlay.style.zIndex = "10";
971
- const divisions = gridMode === "3x3" ? 3 : 4;
948
+ const overlay = document.createElement('div');
949
+ overlay.style.position = 'absolute';
950
+ overlay.style.top = '0';
951
+ overlay.style.left = '0';
952
+ overlay.style.width = '100%';
953
+ overlay.style.height = '100%';
954
+ overlay.style.pointerEvents = 'none';
955
+ overlay.style.zIndex = '10';
956
+ const divisions = gridMode === '3x3' ? 3 : 4;
972
957
  // Create SVG for grid lines
973
- const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
974
- svg.style.width = "100%";
975
- svg.style.height = "100%";
976
- svg.style.position = "absolute";
977
- svg.style.top = "0";
978
- svg.style.left = "0";
958
+ const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
959
+ svg.style.width = '100%';
960
+ svg.style.height = '100%';
961
+ svg.style.position = 'absolute';
962
+ svg.style.top = '0';
963
+ svg.style.left = '0';
979
964
  // Create grid lines
980
965
  for (let i = 1; i < divisions; i++) {
981
966
  // Vertical lines
982
- const verticalLine = document.createElementNS("http://www.w3.org/2000/svg", "line");
983
- verticalLine.setAttribute("x1", `${(i / divisions) * 100}%`);
984
- verticalLine.setAttribute("y1", "0%");
985
- verticalLine.setAttribute("x2", `${(i / divisions) * 100}%`);
986
- verticalLine.setAttribute("y2", "100%");
987
- verticalLine.setAttribute("stroke", "rgba(255, 255, 255, 0.5)");
988
- verticalLine.setAttribute("stroke-width", "1");
967
+ const verticalLine = document.createElementNS('http://www.w3.org/2000/svg', 'line');
968
+ verticalLine.setAttribute('x1', `${(i / divisions) * 100}%`);
969
+ verticalLine.setAttribute('y1', '0%');
970
+ verticalLine.setAttribute('x2', `${(i / divisions) * 100}%`);
971
+ verticalLine.setAttribute('y2', '100%');
972
+ verticalLine.setAttribute('stroke', 'rgba(255, 255, 255, 0.5)');
973
+ verticalLine.setAttribute('stroke-width', '1');
989
974
  svg.appendChild(verticalLine);
990
975
  // Horizontal lines
991
- const horizontalLine = document.createElementNS("http://www.w3.org/2000/svg", "line");
992
- horizontalLine.setAttribute("x1", "0%");
993
- horizontalLine.setAttribute("y1", `${(i / divisions) * 100}%`);
994
- horizontalLine.setAttribute("x2", "100%");
995
- horizontalLine.setAttribute("y2", `${(i / divisions) * 100}%`);
996
- horizontalLine.setAttribute("stroke", "rgba(255, 255, 255, 0.5)");
997
- horizontalLine.setAttribute("stroke-width", "1");
976
+ const horizontalLine = document.createElementNS('http://www.w3.org/2000/svg', 'line');
977
+ horizontalLine.setAttribute('x1', '0%');
978
+ horizontalLine.setAttribute('y1', `${(i / divisions) * 100}%`);
979
+ horizontalLine.setAttribute('x2', '100%');
980
+ horizontalLine.setAttribute('y2', `${(i / divisions) * 100}%`);
981
+ horizontalLine.setAttribute('stroke', 'rgba(255, 255, 255, 0.5)');
982
+ horizontalLine.setAttribute('stroke-width', '1');
998
983
  svg.appendChild(horizontalLine);
999
984
  }
1000
985
  overlay.appendChild(svg);
@@ -1007,12 +992,12 @@ class CameraPreviewWeb extends core.WebPlugin {
1007
992
  }
1008
993
  async getGridMode() {
1009
994
  // Web implementation - default to none
1010
- return { gridMode: "none" };
995
+ return { gridMode: 'none' };
1011
996
  }
1012
997
  async getPreviewSize() {
1013
998
  const video = document.getElementById(DEFAULT_VIDEO_ID);
1014
999
  if (!video) {
1015
- throw new Error("camera is not running");
1000
+ throw new Error('camera is not running');
1016
1001
  }
1017
1002
  const offsetX = video.width / 8;
1018
1003
  const offsetY = video.height / 8;
@@ -1026,7 +1011,7 @@ class CameraPreviewWeb extends core.WebPlugin {
1026
1011
  async setPreviewSize(options) {
1027
1012
  const video = document.getElementById(DEFAULT_VIDEO_ID);
1028
1013
  if (!video) {
1029
- throw new Error("camera is not running");
1014
+ throw new Error('camera is not running');
1030
1015
  }
1031
1016
  video.style.left = `${options.x}px`;
1032
1017
  video.style.top = `${options.y}px`;
@@ -1044,16 +1029,16 @@ class CameraPreviewWeb extends core.WebPlugin {
1044
1029
  async setFocus(options) {
1045
1030
  // Reject if values are outside 0-1 range
1046
1031
  if (options.x < 0 || options.x > 1 || options.y < 0 || options.y > 1) {
1047
- throw new Error("Focus coordinates must be between 0 and 1");
1032
+ throw new Error('Focus coordinates must be between 0 and 1');
1048
1033
  }
1049
1034
  const video = document.getElementById(DEFAULT_VIDEO_ID);
1050
1035
  if (!(video === null || video === void 0 ? void 0 : video.srcObject)) {
1051
- throw new Error("camera is not running");
1036
+ throw new Error('camera is not running');
1052
1037
  }
1053
1038
  const stream = video.srcObject;
1054
1039
  const videoTrack = stream.getVideoTracks()[0];
1055
1040
  if (!videoTrack) {
1056
- throw new Error("no video track found");
1041
+ throw new Error('no video track found');
1057
1042
  }
1058
1043
  const capabilities = videoTrack.getCapabilities();
1059
1044
  // Check if focusing is supported
@@ -1064,7 +1049,7 @@ class CameraPreviewWeb extends core.WebPlugin {
1064
1049
  await videoTrack.applyConstraints({
1065
1050
  advanced: [
1066
1051
  {
1067
- focusMode: "manual",
1052
+ focusMode: 'manual',
1068
1053
  focusDistance: 0.5, // Mid-range focus as fallback
1069
1054
  },
1070
1055
  ],
@@ -1075,30 +1060,30 @@ class CameraPreviewWeb extends core.WebPlugin {
1075
1060
  }
1076
1061
  }
1077
1062
  else {
1078
- console.warn("Focus control is not supported on this device. Focus coordinates were provided but cannot be applied.");
1063
+ console.warn('Focus control is not supported on this device. Focus coordinates were provided but cannot be applied.');
1079
1064
  }
1080
1065
  }
1081
1066
  // Exposure stubs (unsupported on web)
1082
1067
  async getExposureModes() {
1083
- throw new Error("getExposureModes not supported under the web platform");
1068
+ throw new Error('getExposureModes not supported under the web platform');
1084
1069
  }
1085
1070
  async getExposureMode() {
1086
- throw new Error("getExposureMode not supported under the web platform");
1071
+ throw new Error('getExposureMode not supported under the web platform');
1087
1072
  }
1088
1073
  async setExposureMode(_options) {
1089
- throw new Error("setExposureMode not supported under the web platform");
1074
+ throw new Error('setExposureMode not supported under the web platform');
1090
1075
  }
1091
1076
  async getExposureCompensationRange() {
1092
- throw new Error("getExposureCompensationRange not supported under the web platform");
1077
+ throw new Error('getExposureCompensationRange not supported under the web platform');
1093
1078
  }
1094
1079
  async getExposureCompensation() {
1095
- throw new Error("getExposureCompensation not supported under the web platform");
1080
+ throw new Error('getExposureCompensation not supported under the web platform');
1096
1081
  }
1097
1082
  async setExposureCompensation(_options) {
1098
- throw new Error("setExposureCompensation not supported under the web platform");
1083
+ throw new Error('setExposureCompensation not supported under the web platform');
1099
1084
  }
1100
1085
  async deleteFile(_options) {
1101
- throw new Error("deleteFile not supported under the web platform");
1086
+ throw new Error('deleteFile not supported under the web platform');
1102
1087
  }
1103
1088
  }
1104
1089