@capgo/camera-preview 8.2.2 → 8.3.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.
Files changed (33) hide show
  1. package/README.md +31 -29
  2. package/android/build.gradle +4 -0
  3. package/android/src/main/java/app/capgo/capacitor/camera/preview/CameraPreview.java +87 -20
  4. package/android/src/main/java/app/capgo/capacitor/camera/preview/CameraXView.java +553 -158
  5. package/android/src/main/java/app/capgo/capacitor/camera/preview/model/CameraSessionConfiguration.java +13 -0
  6. package/dist/docs.json +17 -1
  7. package/dist/esm/definitions.d.ts +9 -1
  8. package/dist/esm/definitions.js.map +1 -1
  9. package/dist/esm/web.d.ts +1 -1
  10. package/dist/esm/web.js +120 -92
  11. package/dist/esm/web.js.map +1 -1
  12. package/dist/plugin.cjs.js +119 -92
  13. package/dist/plugin.cjs.js.map +1 -1
  14. package/dist/plugin.js +119 -92
  15. package/dist/plugin.js.map +1 -1
  16. package/ios/Sources/CapgoCameraPreviewPlugin/CameraController.swift +14 -12
  17. package/ios/Sources/CapgoCameraPreviewPlugin/Plugin.swift +16 -14
  18. package/package.json +8 -7
  19. package/android/.gradle/8.14.4/checksums/checksums.lock +0 -0
  20. package/android/.gradle/8.14.4/checksums/md5-checksums.bin +0 -0
  21. package/android/.gradle/8.14.4/checksums/sha1-checksums.bin +0 -0
  22. package/android/.gradle/8.14.4/executionHistory/executionHistory.bin +0 -0
  23. package/android/.gradle/8.14.4/executionHistory/executionHistory.lock +0 -0
  24. package/android/.gradle/8.14.4/fileChanges/last-build.bin +0 -0
  25. package/android/.gradle/8.14.4/fileHashes/fileHashes.bin +0 -0
  26. package/android/.gradle/8.14.4/fileHashes/fileHashes.lock +0 -0
  27. package/android/.gradle/8.14.4/fileHashes/resourceHashesCache.bin +0 -0
  28. package/android/.gradle/8.14.4/gc.properties +0 -0
  29. package/android/.gradle/buildOutputCleanup/buildOutputCleanup.lock +0 -0
  30. package/android/.gradle/buildOutputCleanup/cache.properties +0 -2
  31. package/android/.gradle/buildOutputCleanup/outputFiles.bin +0 -0
  32. package/android/.gradle/file-system.probe +0 -0
  33. package/android/.gradle/vcs-1/gc.properties +0 -0
package/dist/plugin.js CHANGED
@@ -306,103 +306,130 @@ var capacitorCapacitorCameraView = (function (exports, core) {
306
306
  height: container.offsetHeight,
307
307
  id: container.id,
308
308
  });
309
+ const containerWidth = container.offsetWidth || window.innerWidth;
310
+ const containerHeight = container.offsetHeight || window.innerHeight;
309
311
  // Now adjust video element size based on camera's native aspect ratio
310
- if (!options.width && !options.height && !options.aspectRatio) {
311
- // No size specified, fit camera view within container bounds
312
- const containerWidth = container.offsetWidth || window.innerWidth;
313
- const containerHeight = container.offsetHeight || window.innerHeight;
314
- // Calculate dimensions that fit within container while maintaining camera aspect ratio
315
- let targetWidth, targetHeight;
316
- // Try fitting to container width first
317
- targetWidth = containerWidth;
318
- targetHeight = targetWidth / cameraAspectRatio;
319
- // If height exceeds container, fit to height instead
320
- if (targetHeight > containerHeight) {
321
- targetHeight = containerHeight;
322
- targetWidth = targetHeight * cameraAspectRatio;
323
- }
324
- console.log('Video element dimensions:', {
325
- width: targetWidth,
326
- height: targetHeight,
327
- container: { width: containerWidth, height: containerHeight },
328
- });
329
- this.videoElement.width = targetWidth;
330
- this.videoElement.height = targetHeight;
331
- this.videoElement.style.width = `${targetWidth}px`;
332
- this.videoElement.style.height = `${targetHeight}px`;
333
- // Center the video element within its parent container
334
- if (needsCenterX || options.x === undefined) {
335
- const x = Math.round((containerWidth - targetWidth) / 2);
336
- this.videoElement.style.left = `${x}px`;
312
+ if (!options.width && !options.height) {
313
+ if (aspectMode === 'cover') {
314
+ // Fill the container and rely on object-fit: cover to crop
315
+ const targetWidth = containerWidth;
316
+ const targetHeight = containerHeight;
317
+ this.videoElement.width = targetWidth;
318
+ this.videoElement.height = targetHeight;
319
+ this.videoElement.style.width = `${targetWidth}px`;
320
+ this.videoElement.style.height = `${targetHeight}px`;
321
+ if (needsCenterX || options.x === undefined) {
322
+ const x = Math.round((containerWidth - targetWidth) / 2);
323
+ this.videoElement.style.left = `${x}px`;
324
+ }
325
+ if (needsCenterY || options.y === undefined) {
326
+ let y;
327
+ switch (positioning) {
328
+ case 'top':
329
+ y = 0;
330
+ break;
331
+ case 'bottom':
332
+ y = containerHeight - targetHeight;
333
+ break;
334
+ case 'center':
335
+ default:
336
+ y = Math.round((containerHeight - targetHeight) / 2);
337
+ break;
338
+ }
339
+ this.videoElement.style.setProperty('top', `${y}px`, 'important');
340
+ }
337
341
  }
338
- if (needsCenterY || options.y === undefined) {
339
- let y;
340
- switch (positioning) {
341
- case 'top':
342
- y = 0;
343
- break;
344
- case 'bottom':
345
- y = window.innerHeight - targetHeight;
346
- break;
347
- case 'center':
348
- default:
349
- y = Math.round((window.innerHeight - targetHeight) / 2);
350
- break;
342
+ else if (!options.aspectRatio) {
343
+ // No size specified, fit camera view within container bounds
344
+ // Calculate dimensions that fit within container while maintaining camera aspect ratio
345
+ let targetWidth = containerWidth;
346
+ let targetHeight = targetWidth / cameraAspectRatio;
347
+ // If height exceeds container, fit to height instead
348
+ if (targetHeight > containerHeight) {
349
+ targetHeight = containerHeight;
350
+ targetWidth = targetHeight * cameraAspectRatio;
351
351
  }
352
- this.videoElement.style.setProperty('top', `${y}px`, 'important');
353
- // Force a style recalculation
354
- this.videoElement.offsetHeight;
355
- console.log('Positioning video:', {
356
- positioning,
357
- viewportHeight: window.innerHeight,
358
- targetHeight,
359
- calculatedY: y,
360
- actualTop: this.videoElement.style.top,
361
- position: this.videoElement.style.position,
352
+ console.log('Video element dimensions:', {
353
+ width: targetWidth,
354
+ height: targetHeight,
355
+ container: { width: containerWidth, height: containerHeight },
362
356
  });
357
+ this.videoElement.width = targetWidth;
358
+ this.videoElement.height = targetHeight;
359
+ this.videoElement.style.width = `${targetWidth}px`;
360
+ this.videoElement.style.height = `${targetHeight}px`;
361
+ // Center the video element within its parent container
362
+ if (needsCenterX || options.x === undefined) {
363
+ const x = Math.round((containerWidth - targetWidth) / 2);
364
+ this.videoElement.style.left = `${x}px`;
365
+ }
366
+ if (needsCenterY || options.y === undefined) {
367
+ let y;
368
+ switch (positioning) {
369
+ case 'top':
370
+ y = 0;
371
+ break;
372
+ case 'bottom':
373
+ y = window.innerHeight - targetHeight;
374
+ break;
375
+ case 'center':
376
+ default:
377
+ y = Math.round((window.innerHeight - targetHeight) / 2);
378
+ break;
379
+ }
380
+ this.videoElement.style.setProperty('top', `${y}px`, 'important');
381
+ // Force a style recalculation
382
+ this.videoElement.offsetHeight;
383
+ console.log('Positioning video:', {
384
+ positioning,
385
+ viewportHeight: window.innerHeight,
386
+ targetHeight,
387
+ calculatedY: y,
388
+ actualTop: this.videoElement.style.top,
389
+ position: this.videoElement.style.position,
390
+ });
391
+ }
363
392
  }
364
- }
365
- else if (effectiveAspectRatio && !options.width && !options.height) {
366
- // Aspect ratio specified but no size
367
- const [widthRatio, heightRatio] = effectiveAspectRatio.split(':').map(Number);
368
- const targetRatio = widthRatio / heightRatio;
369
- const viewportWidth = window.innerWidth;
370
- const viewportHeight = window.innerHeight;
371
- let targetWidth, targetHeight;
372
- // Try fitting to viewport width first
373
- targetWidth = viewportWidth;
374
- targetHeight = targetWidth / targetRatio;
375
- // If height exceeds viewport, fit to height instead
376
- if (targetHeight > viewportHeight) {
377
- targetHeight = viewportHeight;
378
- targetWidth = targetHeight * targetRatio;
379
- }
380
- this.videoElement.width = targetWidth;
381
- this.videoElement.height = targetHeight;
382
- this.videoElement.style.width = `${targetWidth}px`;
383
- this.videoElement.style.height = `${targetHeight}px`;
384
- // Center the video element within its parent container
385
- if (needsCenterX || options.x === undefined) {
386
- const parentWidth = container.offsetWidth || viewportWidth;
387
- const x = Math.round((parentWidth - targetWidth) / 2);
388
- this.videoElement.style.left = `${x}px`;
389
- }
390
- if (needsCenterY || options.y === undefined) {
391
- const parentHeight = container.offsetHeight || viewportHeight;
392
- let y;
393
- switch (positioning) {
394
- case 'top':
395
- y = 0;
396
- break;
397
- case 'bottom':
398
- y = parentHeight - targetHeight;
399
- break;
400
- case 'center':
401
- default:
402
- y = Math.round((parentHeight - targetHeight) / 2);
403
- break;
393
+ else if (effectiveAspectRatio) {
394
+ // Aspect ratio specified but no size
395
+ const [widthRatio, heightRatio] = effectiveAspectRatio.split(':').map(Number);
396
+ const targetRatio = widthRatio / heightRatio;
397
+ const viewportWidth = window.innerWidth;
398
+ const viewportHeight = window.innerHeight;
399
+ let targetWidth = viewportWidth;
400
+ let targetHeight = targetWidth / targetRatio;
401
+ // If height exceeds viewport, fit to height instead
402
+ if (targetHeight > viewportHeight) {
403
+ targetHeight = viewportHeight;
404
+ targetWidth = targetHeight * targetRatio;
405
+ }
406
+ this.videoElement.width = targetWidth;
407
+ this.videoElement.height = targetHeight;
408
+ this.videoElement.style.width = `${targetWidth}px`;
409
+ this.videoElement.style.height = `${targetHeight}px`;
410
+ // Center the video element within its parent container
411
+ if (needsCenterX || options.x === undefined) {
412
+ const parentWidth = container.offsetWidth || viewportWidth;
413
+ const x = Math.round((parentWidth - targetWidth) / 2);
414
+ this.videoElement.style.left = `${x}px`;
415
+ }
416
+ if (needsCenterY || options.y === undefined) {
417
+ const parentHeight = container.offsetHeight || viewportHeight;
418
+ let y;
419
+ switch (positioning) {
420
+ case 'top':
421
+ y = 0;
422
+ break;
423
+ case 'bottom':
424
+ y = parentHeight - targetHeight;
425
+ break;
426
+ case 'center':
427
+ default:
428
+ y = Math.round((parentHeight - targetHeight) / 2);
429
+ break;
430
+ }
431
+ this.videoElement.style.top = `${y}px`;
404
432
  }
405
- this.videoElement.style.top = `${y}px`;
406
433
  }
407
434
  }
408
435
  this.videoElement.srcObject = stream;
@@ -632,7 +659,7 @@ var capacitorCapacitorCameraView = (function (exports, core) {
632
659
  recorder.stop();
633
660
  });
634
661
  }
635
- async startRecordVideo(_options) {
662
+ async startRecordVideo(options) {
636
663
  const video = document.getElementById(DEFAULT_VIDEO_ID);
637
664
  if (!(video === null || video === void 0 ? void 0 : video.srcObject)) {
638
665
  throw new Error('camera is not running');