@capgo/camera-preview 7.4.0-beta.13 → 7.4.0-beta.15

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/README.md CHANGED
@@ -562,14 +562,14 @@ Gets the current zoom state, including min/max and current lens info.
562
562
  ### setZoom(...)
563
563
 
564
564
  ```typescript
565
- setZoom(options: { level: number; ramp?: boolean; }) => Promise<void>
565
+ setZoom(options: { level: number; ramp?: boolean; autoFocus?: boolean; }) => Promise<void>
566
566
  ```
567
567
 
568
- Sets the camera's zoom level.
568
+ Sets the zoom level of the camera.
569
569
 
570
- | Param | Type | Description |
571
- | ------------- | ----------------------------------------------- | ----------------------------------------------------- |
572
- | **`options`** | <code>{ level: number; ramp?: boolean; }</code> | - The desired zoom level. `ramp` is currently unused. |
570
+ | Param | Type | Description |
571
+ | ------------- | -------------------------------------------------------------------- | ----------------------------------------------------------------------------------- |
572
+ | **`options`** | <code>{ level: number; ramp?: boolean; autoFocus?: boolean; }</code> | - The desired zoom level. `ramp` is currently unused. `autoFocus` defaults to true. |
573
573
 
574
574
  **Since:** 7.4.0
575
575
 
@@ -652,14 +652,14 @@ Gets the current preview size and position.
652
652
  ### setPreviewSize(...)
653
653
 
654
654
  ```typescript
655
- setPreviewSize(options: { x: number; y: number; width: number; height: number; }) => Promise<{ width: number; height: number; x: number; y: number; }>
655
+ setPreviewSize(options: { x?: number; y?: number; width: number; height: number; }) => Promise<{ width: number; height: number; x: number; y: number; }>
656
656
  ```
657
657
 
658
658
  Sets the preview size and position.
659
659
 
660
- | Param | Type | Description |
661
- | ------------- | --------------------------------------------------------------------- | -------------------------------- |
662
- | **`options`** | <code>{ x: number; y: number; width: number; height: number; }</code> | The new position and dimensions. |
660
+ | Param | Type | Description |
661
+ | ------------- | ----------------------------------------------------------------------- | -------------------------------- |
662
+ | **`options`** | <code>{ x?: number; y?: number; width: number; height: number; }</code> | The new position and dimensions. |
663
663
 
664
664
  **Returns:** <code>Promise&lt;{ width: number; height: number; x: number; y: number; }&gt;</code>
665
665
 
@@ -707,13 +707,13 @@ Defines the configuration options for starting the camera preview.
707
707
  | **`position`** | <code>string</code> | The camera to use. | <code>"rear"</code> | |
708
708
  | **`storeToFile`** | <code>boolean</code> | If true, saves the captured image to a file and returns the file path. If false, returns a base64 encoded string. | <code>false</code> | |
709
709
  | **`disableExifHeaderStripping`** | <code>boolean</code> | If true, prevents the plugin from rotating the image based on EXIF data. | <code>false</code> | |
710
- | **`enableHighResolution`** | <code>boolean</code> | If true, enables high-resolution image capture. | <code>false</code> | |
711
710
  | **`disableAudio`** | <code>boolean</code> | If true, disables the audio stream, preventing audio permission requests. | <code>true</code> | |
712
711
  | **`lockAndroidOrientation`** | <code>boolean</code> | If true, locks the device orientation while the camera is active. | <code>false</code> | |
713
712
  | **`enableOpacity`** | <code>boolean</code> | If true, allows the camera preview's opacity to be changed. | <code>false</code> | |
714
713
  | **`enableZoom`** | <code>boolean</code> | If true, enables pinch-to-zoom functionality on the preview. | <code>false</code> | |
715
714
  | **`enableVideoMode`** | <code>boolean</code> | If true, uses the video-optimized preset for the camera session. | <code>false</code> | |
716
715
  | **`deviceId`** | <code>string</code> | The `deviceId` of the camera to use. If provided, `position` is ignored. | | |
716
+ | **`initialZoomLevel`** | <code>number</code> | The initial zoom level when starting the camera preview. If the requested zoom level is not available, the native plugin will reject. | <code>1.0</code> | 2.2.0 |
717
717
 
718
718
 
719
719
  #### ExifData
Binary file
@@ -10,6 +10,7 @@ import android.util.DisplayMetrics;
10
10
  import android.util.Log;
11
11
  import android.util.Size;
12
12
  import android.view.ViewGroup;
13
+ import android.webkit.WebView;
13
14
  import com.ahm.capacitor.camera.preview.model.CameraDevice;
14
15
  import com.ahm.capacitor.camera.preview.model.CameraSessionConfiguration;
15
16
  import com.ahm.capacitor.camera.preview.model.LensInfo;
@@ -277,8 +278,9 @@ public class CameraPreview
277
278
  call.reject("level parameter is required");
278
279
  return;
279
280
  }
281
+ Boolean autoFocus = call.getBoolean("autoFocus", true);
280
282
  try {
281
- cameraXView.setZoom(level);
283
+ cameraXView.setZoom(level, autoFocus);
282
284
  call.resolve();
283
285
  } catch (Exception e) {
284
286
  call.reject("Failed to set zoom: " + e.getMessage());
@@ -297,14 +299,16 @@ public class CameraPreview
297
299
  call.reject("x and y parameters are required");
298
300
  return;
299
301
  }
300
- // Ensure values are between 0 and 1
301
- float normalizedX = Math.max(0f, Math.min(1f, x));
302
- float normalizedY = Math.max(0f, Math.min(1f, y));
302
+ // Reject if values are outside 0-1 range
303
+ if (x < 0f || x > 1f || y < 0f || y > 1f) {
304
+ call.reject("Focus coordinates must be between 0 and 1");
305
+ return;
306
+ }
303
307
 
304
308
  getActivity()
305
309
  .runOnUiThread(() -> {
306
310
  try {
307
- cameraXView.setFocus(normalizedX, normalizedY);
311
+ cameraXView.setFocus(x, y);
308
312
  call.resolve();
309
313
  } catch (Exception e) {
310
314
  call.reject("Failed to set focus: " + e.getMessage());
@@ -439,8 +443,30 @@ public class CameraPreview
439
443
  "back".equals(positionParam))
440
444
  ? "back"
441
445
  : "front";
442
- final int x = call.getInt("x", 0);
443
- final int y = call.getInt("y", 0);
446
+ // Use -1 as default to indicate centering is needed when x/y not provided
447
+ final Integer xParam = call.getInt("x");
448
+ final Integer yParam = call.getInt("y");
449
+ final int x = xParam != null ? xParam : -1;
450
+ final int y = yParam != null ? yParam : -1;
451
+
452
+ Log.d("CameraPreview", "========================");
453
+ Log.d("CameraPreview", "CAMERA POSITION TRACKING START:");
454
+ Log.d(
455
+ "CameraPreview",
456
+ "1. RAW PARAMS - xParam: " + xParam + ", yParam: " + yParam
457
+ );
458
+ Log.d(
459
+ "CameraPreview",
460
+ "2. AFTER DEFAULT - x: " +
461
+ x +
462
+ " (center=" +
463
+ (x == -1) +
464
+ "), y: " +
465
+ y +
466
+ " (center=" +
467
+ (y == -1) +
468
+ ")"
469
+ );
444
470
  final int width = call.getInt("width", 0);
445
471
  final int height = call.getInt("height", 0);
446
472
  final int paddingBottom = call.getInt("paddingBottom", 0);
@@ -465,6 +491,7 @@ public class CameraPreview
465
491
  );
466
492
  final String aspectRatio = call.getString("aspectRatio", "4:3");
467
493
  final String gridMode = call.getString("gridMode", "none");
494
+ final float initialZoomLevel = call.getFloat("initialZoomLevel", 1.0f);
468
495
 
469
496
  // Check for conflict between aspectRatio and size
470
497
  if (
@@ -477,7 +504,7 @@ public class CameraPreview
477
504
  return;
478
505
  }
479
506
 
480
- float targetZoom = 1.0f;
507
+ float targetZoom = initialZoomLevel;
481
508
  // Check if the selected device is a physical ultra-wide
482
509
  if (originalDeviceId != null) {
483
510
  List<CameraDevice> devices = CameraXView.getAvailableDevicesStatic(
@@ -548,10 +575,84 @@ public class CameraPreview
548
575
  // Calculate pixel ratio
549
576
  float pixelRatio = metrics.density;
550
577
 
551
- // Try using just the pixel ratio without any webview offset for now
552
- int computedX = (int) (x * pixelRatio);
553
- int computedY = (int) (y * pixelRatio);
578
+ // Calculate position - center if x or y is -1
579
+ int computedX;
580
+ int computedY;
581
+
582
+ // Calculate dimensions first
583
+ int computedWidth = width != 0
584
+ ? (int) (width * pixelRatio)
585
+ : getBridge().getWebView().getWidth();
586
+ int computedHeight = height != 0
587
+ ? (int) (height * pixelRatio)
588
+ : getBridge().getWebView().getHeight();
589
+ computedHeight -= (int) (paddingBottom * pixelRatio);
590
+
591
+ Log.d("CameraPreview", "Positioning logic - x: " + x + ", y: " + y);
592
+
593
+ if (x == -1) {
594
+ // Center horizontally
595
+ int screenWidth = metrics.widthPixels;
596
+ computedX = (screenWidth - computedWidth) / 2;
597
+ Log.d(
598
+ "CameraPreview",
599
+ "Centering horizontally: screenWidth=" +
600
+ screenWidth +
601
+ ", computedWidth=" +
602
+ computedWidth +
603
+ ", computedX=" +
604
+ computedX
605
+ );
606
+ } else {
607
+ computedX = (int) (x * pixelRatio);
608
+ Log.d(
609
+ "CameraPreview",
610
+ "Using provided X position: " +
611
+ x +
612
+ " * " +
613
+ pixelRatio +
614
+ " = " +
615
+ computedX
616
+ );
617
+ }
618
+
619
+ if (y == -1) {
620
+ // Center vertically using full screen height
621
+ int screenHeight = metrics.heightPixels;
622
+ computedY = (screenHeight - computedHeight) / 2;
623
+ Log.d(
624
+ "CameraPreview",
625
+ "Centering vertically: screenHeight=" +
626
+ screenHeight +
627
+ ", computedHeight=" +
628
+ computedHeight +
629
+ ", computedY=" +
630
+ computedY
631
+ );
632
+ } else {
633
+ computedY = (int) (y * pixelRatio);
634
+ Log.d(
635
+ "CameraPreview",
636
+ "Using provided Y position: " +
637
+ y +
638
+ " * " +
639
+ pixelRatio +
640
+ " = " +
641
+ computedY
642
+ );
643
+ }
554
644
 
645
+ Log.d(
646
+ "CameraPreview",
647
+ "3. COMPUTED POSITION - x=" + computedX + ", y=" + computedY
648
+ );
649
+ Log.d(
650
+ "CameraPreview",
651
+ "4. COMPUTED SIZE - width=" +
652
+ computedWidth +
653
+ ", height=" +
654
+ computedHeight
655
+ );
555
656
  Log.d("CameraPreview", "=== COORDINATE DEBUG ===");
556
657
  Log.d(
557
658
  "CameraPreview",
@@ -606,14 +707,11 @@ public class CameraPreview
606
707
  computedY +
607
708
  ")"
608
709
  );
710
+ Log.d("CameraPreview", "5. IS_CENTERED - " + (x == -1 || y == -1));
609
711
  Log.d("CameraPreview", "========================");
610
- int computedWidth = width != 0
611
- ? (int) (width * pixelRatio)
612
- : getBridge().getWebView().getWidth();
613
- int computedHeight = height != 0
614
- ? (int) (height * pixelRatio)
615
- : getBridge().getWebView().getHeight();
616
- computedHeight -= (int) (paddingBottom * pixelRatio);
712
+
713
+ // Pass along whether we're centering so CameraXView knows not to add insets
714
+ boolean isCentered = (x == -1 || y == -1);
617
715
 
618
716
  CameraSessionConfiguration config = new CameraSessionConfiguration(
619
717
  finalDeviceId,
@@ -634,6 +732,7 @@ public class CameraPreview
634
732
  gridMode
635
733
  );
636
734
  config.setTargetZoom(finalTargetZoom);
735
+ config.setCentered(isCentered);
637
736
 
638
737
  bridge.saveCall(call);
639
738
  cameraStartCallbackId = call.getCallbackId();
@@ -677,11 +776,70 @@ public class CameraPreview
677
776
  .getDisplayMetrics();
678
777
  float pixelRatio = metrics.density;
679
778
 
779
+ // Check if edge-to-edge mode is active by looking at WebView insets
780
+ // If the WebView has a top margin, it means edge-to-edge is active
781
+ // and JavaScript positions are relative to WebView content area
782
+ int webViewTopInset = 0;
783
+ boolean isEdgeToEdgeActive = false;
784
+ WebView webView = getBridge().getWebView();
785
+ if (
786
+ webView != null &&
787
+ webView.getLayoutParams() instanceof ViewGroup.MarginLayoutParams
788
+ ) {
789
+ webViewTopInset =
790
+ ((ViewGroup.MarginLayoutParams) webView.getLayoutParams()).topMargin;
791
+ isEdgeToEdgeActive = webViewTopInset > 0;
792
+ }
793
+
794
+ // Only convert to relative position if edge-to-edge is active
795
+ int relativeY = isEdgeToEdgeActive ? (y - webViewTopInset) : y;
796
+
797
+ Log.d("CameraPreview", "========================");
798
+ Log.d("CameraPreview", "CAMERA STARTED - POSITION RETURNED:");
799
+ Log.d(
800
+ "CameraPreview",
801
+ "7. RETURNED (pixels) - x=" +
802
+ x +
803
+ ", y=" +
804
+ y +
805
+ ", width=" +
806
+ width +
807
+ ", height=" +
808
+ height
809
+ );
810
+ Log.d(
811
+ "CameraPreview",
812
+ "8. EDGE-TO-EDGE - " + (isEdgeToEdgeActive ? "ACTIVE" : "INACTIVE")
813
+ );
814
+ Log.d("CameraPreview", "9. WEBVIEW INSET - " + webViewTopInset);
815
+ Log.d(
816
+ "CameraPreview",
817
+ "10. RELATIVE Y - " +
818
+ relativeY +
819
+ " (y=" +
820
+ y +
821
+ (isEdgeToEdgeActive ? " - inset=" + webViewTopInset : " unchanged") +
822
+ ")"
823
+ );
824
+ Log.d(
825
+ "CameraPreview",
826
+ "11. RETURNED (logical) - x=" +
827
+ (x / pixelRatio) +
828
+ ", y=" +
829
+ (relativeY / pixelRatio) +
830
+ ", width=" +
831
+ (width / pixelRatio) +
832
+ ", height=" +
833
+ (height / pixelRatio)
834
+ );
835
+ Log.d("CameraPreview", "12. PIXEL RATIO - " + pixelRatio);
836
+ Log.d("CameraPreview", "========================");
837
+
680
838
  JSObject result = new JSObject();
681
839
  result.put("width", width / pixelRatio);
682
840
  result.put("height", height / pixelRatio);
683
841
  result.put("x", x / pixelRatio);
684
- result.put("y", y / pixelRatio);
842
+ result.put("y", relativeY / pixelRatio);
685
843
  call.resolve(result);
686
844
  bridge.releaseCall(call);
687
845
  cameraStartCallbackId = null; // Prevent re-use