@capgo/camera-preview 7.4.0-beta.13 → 7.4.0-beta.16
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 +19 -18
- package/android/.gradle/8.14.2/executionHistory/executionHistory.bin +0 -0
- package/android/.gradle/8.14.2/executionHistory/executionHistory.lock +0 -0
- package/android/.gradle/8.14.2/fileHashes/fileHashes.bin +0 -0
- package/android/.gradle/8.14.2/fileHashes/fileHashes.lock +0 -0
- package/android/.gradle/8.14.2/fileHashes/resourceHashesCache.bin +0 -0
- package/android/.gradle/buildOutputCleanup/buildOutputCleanup.lock +0 -0
- package/android/.gradle/file-system.probe +0 -0
- package/android/src/main/java/com/ahm/capacitor/camera/preview/CameraPreview.java +271 -20
- package/android/src/main/java/com/ahm/capacitor/camera/preview/CameraXView.java +816 -134
- package/android/src/main/java/com/ahm/capacitor/camera/preview/model/CameraSessionConfiguration.java +9 -0
- package/dist/docs.json +39 -23
- package/dist/esm/definitions.d.ts +20 -10
- package/dist/esm/definitions.js.map +1 -1
- package/dist/esm/web.d.ts +1 -0
- package/dist/esm/web.js +266 -38
- package/dist/esm/web.js.map +1 -1
- package/dist/plugin.cjs.js +266 -38
- package/dist/plugin.cjs.js.map +1 -1
- package/dist/plugin.js +266 -38
- package/dist/plugin.js.map +1 -1
- package/ios/Sources/CapgoCameraPreview/CameraController.swift +430 -71
- package/ios/Sources/CapgoCameraPreview/Plugin.swift +139 -114
- package/package.json +1 -1
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
|
|
568
|
+
Sets the zoom level of the camera.
|
|
569
569
|
|
|
570
|
-
| Param | Type
|
|
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
|
|
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
|
|
661
|
-
| ------------- |
|
|
662
|
-
| **`options`** | <code>{ x
|
|
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<{ width: number; height: number; x: number; y: number; }></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
|
|
@@ -725,14 +725,15 @@ Represents EXIF data extracted from an image.
|
|
|
725
725
|
|
|
726
726
|
Defines the options for capturing a picture.
|
|
727
727
|
|
|
728
|
-
| Prop | Type | Description
|
|
729
|
-
| ---------------------- | ------------------------------------------------------- |
|
|
730
|
-
| **`height`** | <code>number</code> | The desired height of the picture in pixels. If not provided, the device default is used.
|
|
731
|
-
| **`width`** | <code>number</code> | The desired width of the picture in pixels. If not provided, the device default is used.
|
|
732
|
-
| **`
|
|
733
|
-
| **`
|
|
734
|
-
| **`
|
|
735
|
-
| **`
|
|
728
|
+
| Prop | Type | Description | Default | Since |
|
|
729
|
+
| ---------------------- | ------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------- | ----- |
|
|
730
|
+
| **`height`** | <code>number</code> | The desired height of the picture in pixels. If not provided, the device default is used. | | |
|
|
731
|
+
| **`width`** | <code>number</code> | The desired width of the picture in pixels. If not provided, the device default is used. | | |
|
|
732
|
+
| **`aspectRatio`** | <code>string</code> | The desired aspect ratio of the captured image (e.g., '4:3', '16:9'). If specified without width/height, captures the largest possible image with this ratio. Cannot be used together with width or height - the capture will be rejected with an error. | | 7.7.0 |
|
|
733
|
+
| **`quality`** | <code>number</code> | The quality of the captured image, from 0 to 100. Does not apply to `png` format. | <code>85</code> | |
|
|
734
|
+
| **`format`** | <code><a href="#pictureformat">PictureFormat</a></code> | The format of the captured image. | <code>"jpeg"</code> | |
|
|
735
|
+
| **`saveToGallery`** | <code>boolean</code> | If true, the captured image will be saved to the user's gallery. | <code>false</code> | 7.5.0 |
|
|
736
|
+
| **`withExifLocation`** | <code>boolean</code> | If true, the plugin will attempt to add GPS location data to the image's EXIF metadata. This may prompt the user for location permissions. | <code>false</code> | 7.6.0 |
|
|
736
737
|
|
|
737
738
|
|
|
738
739
|
#### CameraSampleOptions
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -9,7 +9,9 @@ import android.location.Location;
|
|
|
9
9
|
import android.util.DisplayMetrics;
|
|
10
10
|
import android.util.Log;
|
|
11
11
|
import android.util.Size;
|
|
12
|
+
import android.view.View;
|
|
12
13
|
import android.view.ViewGroup;
|
|
14
|
+
import android.webkit.WebView;
|
|
13
15
|
import com.ahm.capacitor.camera.preview.model.CameraDevice;
|
|
14
16
|
import com.ahm.capacitor.camera.preview.model.CameraSessionConfiguration;
|
|
15
17
|
import com.ahm.capacitor.camera.preview.model.LensInfo;
|
|
@@ -170,8 +172,9 @@ public class CameraPreview
|
|
|
170
172
|
final boolean saveToGallery = call.getBoolean("saveToGallery", false);
|
|
171
173
|
Integer width = call.getInt("width");
|
|
172
174
|
Integer height = call.getInt("height");
|
|
175
|
+
String aspectRatio = call.getString("aspectRatio");
|
|
173
176
|
|
|
174
|
-
cameraXView.capturePhoto(quality, saveToGallery, width, height, location);
|
|
177
|
+
cameraXView.capturePhoto(quality, saveToGallery, width, height, aspectRatio, location);
|
|
175
178
|
}
|
|
176
179
|
|
|
177
180
|
@PluginMethod
|
|
@@ -277,8 +280,9 @@ public class CameraPreview
|
|
|
277
280
|
call.reject("level parameter is required");
|
|
278
281
|
return;
|
|
279
282
|
}
|
|
283
|
+
Boolean autoFocus = call.getBoolean("autoFocus", true);
|
|
280
284
|
try {
|
|
281
|
-
cameraXView.setZoom(level);
|
|
285
|
+
cameraXView.setZoom(level, autoFocus);
|
|
282
286
|
call.resolve();
|
|
283
287
|
} catch (Exception e) {
|
|
284
288
|
call.reject("Failed to set zoom: " + e.getMessage());
|
|
@@ -297,14 +301,16 @@ public class CameraPreview
|
|
|
297
301
|
call.reject("x and y parameters are required");
|
|
298
302
|
return;
|
|
299
303
|
}
|
|
300
|
-
//
|
|
301
|
-
|
|
302
|
-
|
|
304
|
+
// Reject if values are outside 0-1 range
|
|
305
|
+
if (x < 0f || x > 1f || y < 0f || y > 1f) {
|
|
306
|
+
call.reject("Focus coordinates must be between 0 and 1");
|
|
307
|
+
return;
|
|
308
|
+
}
|
|
303
309
|
|
|
304
310
|
getActivity()
|
|
305
311
|
.runOnUiThread(() -> {
|
|
306
312
|
try {
|
|
307
|
-
cameraXView.setFocus(
|
|
313
|
+
cameraXView.setFocus(x, y);
|
|
308
314
|
call.resolve();
|
|
309
315
|
} catch (Exception e) {
|
|
310
316
|
call.reject("Failed to set focus: " + e.getMessage());
|
|
@@ -439,8 +445,30 @@ public class CameraPreview
|
|
|
439
445
|
"back".equals(positionParam))
|
|
440
446
|
? "back"
|
|
441
447
|
: "front";
|
|
442
|
-
|
|
443
|
-
final
|
|
448
|
+
// Use -1 as default to indicate centering is needed when x/y not provided
|
|
449
|
+
final Integer xParam = call.getInt("x");
|
|
450
|
+
final Integer yParam = call.getInt("y");
|
|
451
|
+
final int x = xParam != null ? xParam : -1;
|
|
452
|
+
final int y = yParam != null ? yParam : -1;
|
|
453
|
+
|
|
454
|
+
Log.d("CameraPreview", "========================");
|
|
455
|
+
Log.d("CameraPreview", "CAMERA POSITION TRACKING START:");
|
|
456
|
+
Log.d(
|
|
457
|
+
"CameraPreview",
|
|
458
|
+
"1. RAW PARAMS - xParam: " + xParam + ", yParam: " + yParam
|
|
459
|
+
);
|
|
460
|
+
Log.d(
|
|
461
|
+
"CameraPreview",
|
|
462
|
+
"2. AFTER DEFAULT - x: " +
|
|
463
|
+
x +
|
|
464
|
+
" (center=" +
|
|
465
|
+
(x == -1) +
|
|
466
|
+
"), y: " +
|
|
467
|
+
y +
|
|
468
|
+
" (center=" +
|
|
469
|
+
(y == -1) +
|
|
470
|
+
")"
|
|
471
|
+
);
|
|
444
472
|
final int width = call.getInt("width", 0);
|
|
445
473
|
final int height = call.getInt("height", 0);
|
|
446
474
|
final int paddingBottom = call.getInt("paddingBottom", 0);
|
|
@@ -465,6 +493,7 @@ public class CameraPreview
|
|
|
465
493
|
);
|
|
466
494
|
final String aspectRatio = call.getString("aspectRatio", "4:3");
|
|
467
495
|
final String gridMode = call.getString("gridMode", "none");
|
|
496
|
+
final float initialZoomLevel = call.getFloat("initialZoomLevel", 1.0f);
|
|
468
497
|
|
|
469
498
|
// Check for conflict between aspectRatio and size
|
|
470
499
|
if (
|
|
@@ -477,7 +506,7 @@ public class CameraPreview
|
|
|
477
506
|
return;
|
|
478
507
|
}
|
|
479
508
|
|
|
480
|
-
float targetZoom =
|
|
509
|
+
float targetZoom = initialZoomLevel;
|
|
481
510
|
// Check if the selected device is a physical ultra-wide
|
|
482
511
|
if (originalDeviceId != null) {
|
|
483
512
|
List<CameraDevice> devices = CameraXView.getAvailableDevicesStatic(
|
|
@@ -547,11 +576,162 @@ public class CameraPreview
|
|
|
547
576
|
|
|
548
577
|
// Calculate pixel ratio
|
|
549
578
|
float pixelRatio = metrics.density;
|
|
579
|
+
|
|
580
|
+
// The key insight: JavaScript coordinates are relative to the WebView's viewport
|
|
581
|
+
// If the WebView is positioned below the status bar (webViewLocationOnScreen[1] > 0),
|
|
582
|
+
// we need to add that offset when placing native views
|
|
583
|
+
int webViewTopInset = webViewLocationOnScreen[1];
|
|
584
|
+
boolean isEdgeToEdgeActive = webViewLocationOnScreen[1] > 0;
|
|
585
|
+
|
|
586
|
+
// Log all the positioning information for debugging
|
|
587
|
+
Log.d("CameraPreview", "WebView Position Debug:");
|
|
588
|
+
Log.d("CameraPreview", " - webView.getTop(): " + webViewTop);
|
|
589
|
+
Log.d("CameraPreview", " - webView.getLeft(): " + webViewLeft);
|
|
590
|
+
Log.d("CameraPreview", " - webView locationInWindow: (" + webViewLocationInWindow[0] + ", " + webViewLocationInWindow[1] + ")");
|
|
591
|
+
Log.d("CameraPreview", " - webView locationOnScreen: (" + webViewLocationOnScreen[0] + ", " + webViewLocationOnScreen[1] + ")");
|
|
592
|
+
Log.d("CameraPreview", " - parent locationInWindow: (" + parentLocationInWindow[0] + ", " + parentLocationInWindow[1] + ")");
|
|
593
|
+
Log.d("CameraPreview", " - parent locationOnScreen: (" + parentLocationOnScreen[0] + ", " + parentLocationOnScreen[1] + ")");
|
|
594
|
+
|
|
595
|
+
// Check if WebView has margins
|
|
596
|
+
View webView = getBridge().getWebView();
|
|
597
|
+
ViewGroup.LayoutParams webViewLayoutParams = webView.getLayoutParams();
|
|
598
|
+
if (webViewLayoutParams instanceof ViewGroup.MarginLayoutParams) {
|
|
599
|
+
ViewGroup.MarginLayoutParams marginParams = (ViewGroup.MarginLayoutParams) webViewLayoutParams;
|
|
600
|
+
Log.d("CameraPreview", " - webView margins: left=" + marginParams.leftMargin +
|
|
601
|
+
", top=" + marginParams.topMargin +
|
|
602
|
+
", right=" + marginParams.rightMargin +
|
|
603
|
+
", bottom=" + marginParams.bottomMargin);
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
// Check WebView padding
|
|
607
|
+
Log.d("CameraPreview", " - webView padding: left=" + webView.getPaddingLeft() +
|
|
608
|
+
", top=" + webView.getPaddingTop() +
|
|
609
|
+
", right=" + webView.getPaddingRight() +
|
|
610
|
+
", bottom=" + webView.getPaddingBottom());
|
|
611
|
+
|
|
612
|
+
Log.d("CameraPreview", " - Using webViewTopInset: " + webViewTopInset);
|
|
613
|
+
Log.d("CameraPreview", " - isEdgeToEdgeActive: " + isEdgeToEdgeActive);
|
|
614
|
+
|
|
615
|
+
// Calculate position - center if x or y is -1
|
|
616
|
+
int computedX;
|
|
617
|
+
int computedY;
|
|
618
|
+
|
|
619
|
+
// Calculate dimensions first
|
|
620
|
+
int computedWidth = width != 0
|
|
621
|
+
? (int) (width * pixelRatio)
|
|
622
|
+
: getBridge().getWebView().getWidth();
|
|
623
|
+
int computedHeight = height != 0
|
|
624
|
+
? (int) (height * pixelRatio)
|
|
625
|
+
: getBridge().getWebView().getHeight();
|
|
626
|
+
computedHeight -= (int) (paddingBottom * pixelRatio);
|
|
550
627
|
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
628
|
+
Log.d("CameraPreview", "========================");
|
|
629
|
+
Log.d("CameraPreview", "POSITIONING CALCULATIONS:");
|
|
630
|
+
Log.d("CameraPreview", "1. INPUT - x: " + x + ", y: " + y + ", width: " + width + ", height: " + height);
|
|
631
|
+
Log.d("CameraPreview", "2. PIXEL RATIO: " + pixelRatio);
|
|
632
|
+
Log.d("CameraPreview", "3. SCREEN - width: " + metrics.widthPixels + ", height: " + metrics.heightPixels);
|
|
633
|
+
Log.d("CameraPreview", "4. WEBVIEW - width: " + getBridge().getWebView().getWidth() + ", height: " + getBridge().getWebView().getHeight());
|
|
634
|
+
Log.d("CameraPreview", "5. COMPUTED DIMENSIONS - width: " + computedWidth + ", height: " + computedHeight);
|
|
635
|
+
|
|
636
|
+
if (x == -1) {
|
|
637
|
+
// Center horizontally
|
|
638
|
+
int screenWidth = metrics.widthPixels;
|
|
639
|
+
computedX = (screenWidth - computedWidth) / 2;
|
|
640
|
+
Log.d(
|
|
641
|
+
"CameraPreview",
|
|
642
|
+
"Centering horizontally: screenWidth=" +
|
|
643
|
+
screenWidth +
|
|
644
|
+
", computedWidth=" +
|
|
645
|
+
computedWidth +
|
|
646
|
+
", computedX=" +
|
|
647
|
+
computedX
|
|
648
|
+
);
|
|
649
|
+
} else {
|
|
650
|
+
computedX = (int) (x * pixelRatio);
|
|
651
|
+
Log.d(
|
|
652
|
+
"CameraPreview",
|
|
653
|
+
"Using provided X position: " +
|
|
654
|
+
x +
|
|
655
|
+
" * " +
|
|
656
|
+
pixelRatio +
|
|
657
|
+
" = " +
|
|
658
|
+
computedX
|
|
659
|
+
);
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
if (y == -1) {
|
|
663
|
+
// Center vertically
|
|
664
|
+
if (isEdgeToEdgeActive) {
|
|
665
|
+
// When WebView is offset from top, center within the available space
|
|
666
|
+
// The camera should be centered in the full screen, not just the WebView area
|
|
667
|
+
computedY = (metrics.heightPixels - computedHeight) / 2;
|
|
668
|
+
Log.d(
|
|
669
|
+
"CameraPreview",
|
|
670
|
+
"Centering vertically with WebView offset: screenHeight=" +
|
|
671
|
+
metrics.heightPixels +
|
|
672
|
+
", webViewTop=" +
|
|
673
|
+
webViewTopInset +
|
|
674
|
+
", computedHeight=" +
|
|
675
|
+
computedHeight +
|
|
676
|
+
", computedY=" +
|
|
677
|
+
computedY
|
|
678
|
+
);
|
|
679
|
+
} else {
|
|
680
|
+
// Normal mode - use full screen height
|
|
681
|
+
computedY = (metrics.heightPixels - computedHeight) / 2;
|
|
682
|
+
Log.d(
|
|
683
|
+
"CameraPreview",
|
|
684
|
+
"Centering vertically (normal): screenHeight=" +
|
|
685
|
+
metrics.heightPixels +
|
|
686
|
+
", computedHeight=" +
|
|
687
|
+
computedHeight +
|
|
688
|
+
", computedY=" +
|
|
689
|
+
computedY
|
|
690
|
+
);
|
|
691
|
+
}
|
|
692
|
+
} else {
|
|
693
|
+
computedY = (int) (y * pixelRatio);
|
|
694
|
+
// If edge-to-edge is active, JavaScript Y is relative to WebView content area
|
|
695
|
+
// We need to add the inset to get absolute screen position
|
|
696
|
+
if (isEdgeToEdgeActive) {
|
|
697
|
+
computedY += webViewTopInset;
|
|
698
|
+
Log.d(
|
|
699
|
+
"CameraPreview",
|
|
700
|
+
"Edge-to-edge adjustment: Y position " +
|
|
701
|
+
(int)(y * pixelRatio) +
|
|
702
|
+
" + inset " +
|
|
703
|
+
webViewTopInset +
|
|
704
|
+
" = " +
|
|
705
|
+
computedY
|
|
706
|
+
);
|
|
707
|
+
}
|
|
708
|
+
Log.d(
|
|
709
|
+
"CameraPreview",
|
|
710
|
+
"Using provided Y position: " +
|
|
711
|
+
y +
|
|
712
|
+
" * " +
|
|
713
|
+
pixelRatio +
|
|
714
|
+
" = " +
|
|
715
|
+
computedY +
|
|
716
|
+
(isEdgeToEdgeActive ? " (adjusted for edge-to-edge)" : "")
|
|
717
|
+
);
|
|
718
|
+
}
|
|
554
719
|
|
|
720
|
+
Log.d(
|
|
721
|
+
"CameraPreview",
|
|
722
|
+
"2b. EDGE-TO-EDGE - " + (isEdgeToEdgeActive ? "ACTIVE (inset=" + webViewTopInset + ")" : "INACTIVE")
|
|
723
|
+
);
|
|
724
|
+
Log.d(
|
|
725
|
+
"CameraPreview",
|
|
726
|
+
"3. COMPUTED POSITION - x=" + computedX + ", y=" + computedY
|
|
727
|
+
);
|
|
728
|
+
Log.d(
|
|
729
|
+
"CameraPreview",
|
|
730
|
+
"4. COMPUTED SIZE - width=" +
|
|
731
|
+
computedWidth +
|
|
732
|
+
", height=" +
|
|
733
|
+
computedHeight
|
|
734
|
+
);
|
|
555
735
|
Log.d("CameraPreview", "=== COORDINATE DEBUG ===");
|
|
556
736
|
Log.d(
|
|
557
737
|
"CameraPreview",
|
|
@@ -606,14 +786,11 @@ public class CameraPreview
|
|
|
606
786
|
computedY +
|
|
607
787
|
")"
|
|
608
788
|
);
|
|
789
|
+
Log.d("CameraPreview", "5. IS_CENTERED - " + (x == -1 || y == -1));
|
|
609
790
|
Log.d("CameraPreview", "========================");
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
int computedHeight = height != 0
|
|
614
|
-
? (int) (height * pixelRatio)
|
|
615
|
-
: getBridge().getWebView().getHeight();
|
|
616
|
-
computedHeight -= (int) (paddingBottom * pixelRatio);
|
|
791
|
+
|
|
792
|
+
// Pass along whether we're centering so CameraXView knows not to add insets
|
|
793
|
+
boolean isCentered = (x == -1 || y == -1);
|
|
617
794
|
|
|
618
795
|
CameraSessionConfiguration config = new CameraSessionConfiguration(
|
|
619
796
|
finalDeviceId,
|
|
@@ -634,6 +811,7 @@ public class CameraPreview
|
|
|
634
811
|
gridMode
|
|
635
812
|
);
|
|
636
813
|
config.setTargetZoom(finalTargetZoom);
|
|
814
|
+
config.setCentered(isCentered);
|
|
637
815
|
|
|
638
816
|
bridge.saveCall(call);
|
|
639
817
|
cameraStartCallbackId = call.getCallbackId();
|
|
@@ -677,11 +855,68 @@ public class CameraPreview
|
|
|
677
855
|
.getDisplayMetrics();
|
|
678
856
|
float pixelRatio = metrics.density;
|
|
679
857
|
|
|
858
|
+
// When WebView is offset from the top (e.g., below status bar),
|
|
859
|
+
// we need to convert between JavaScript coordinates (relative to WebView)
|
|
860
|
+
// and native coordinates (relative to screen)
|
|
861
|
+
WebView webView = getBridge().getWebView();
|
|
862
|
+
int webViewTopInset = 0;
|
|
863
|
+
boolean isEdgeToEdgeActive = false;
|
|
864
|
+
if (webView != null) {
|
|
865
|
+
int[] location = new int[2];
|
|
866
|
+
webView.getLocationOnScreen(location);
|
|
867
|
+
webViewTopInset = location[1];
|
|
868
|
+
isEdgeToEdgeActive = webViewTopInset > 0;
|
|
869
|
+
}
|
|
870
|
+
|
|
871
|
+
// Only convert to relative position if edge-to-edge is active
|
|
872
|
+
int relativeY = isEdgeToEdgeActive ? (y - webViewTopInset) : y;
|
|
873
|
+
|
|
874
|
+
Log.d("CameraPreview", "========================");
|
|
875
|
+
Log.d("CameraPreview", "CAMERA STARTED - POSITION RETURNED:");
|
|
876
|
+
Log.d(
|
|
877
|
+
"CameraPreview",
|
|
878
|
+
"7. RETURNED (pixels) - x=" +
|
|
879
|
+
x +
|
|
880
|
+
", y=" +
|
|
881
|
+
y +
|
|
882
|
+
", width=" +
|
|
883
|
+
width +
|
|
884
|
+
", height=" +
|
|
885
|
+
height
|
|
886
|
+
);
|
|
887
|
+
Log.d(
|
|
888
|
+
"CameraPreview",
|
|
889
|
+
"8. EDGE-TO-EDGE - " + (isEdgeToEdgeActive ? "ACTIVE" : "INACTIVE")
|
|
890
|
+
);
|
|
891
|
+
Log.d("CameraPreview", "9. WEBVIEW INSET - " + webViewTopInset);
|
|
892
|
+
Log.d(
|
|
893
|
+
"CameraPreview",
|
|
894
|
+
"10. RELATIVE Y - " +
|
|
895
|
+
relativeY +
|
|
896
|
+
" (y=" +
|
|
897
|
+
y +
|
|
898
|
+
(isEdgeToEdgeActive ? " - inset=" + webViewTopInset : " unchanged") +
|
|
899
|
+
")"
|
|
900
|
+
);
|
|
901
|
+
Log.d(
|
|
902
|
+
"CameraPreview",
|
|
903
|
+
"11. RETURNED (logical) - x=" +
|
|
904
|
+
(x / pixelRatio) +
|
|
905
|
+
", y=" +
|
|
906
|
+
(relativeY / pixelRatio) +
|
|
907
|
+
", width=" +
|
|
908
|
+
(width / pixelRatio) +
|
|
909
|
+
", height=" +
|
|
910
|
+
(height / pixelRatio)
|
|
911
|
+
);
|
|
912
|
+
Log.d("CameraPreview", "12. PIXEL RATIO - " + pixelRatio);
|
|
913
|
+
Log.d("CameraPreview", "========================");
|
|
914
|
+
|
|
680
915
|
JSObject result = new JSObject();
|
|
681
916
|
result.put("width", width / pixelRatio);
|
|
682
917
|
result.put("height", height / pixelRatio);
|
|
683
918
|
result.put("x", x / pixelRatio);
|
|
684
|
-
result.put("y",
|
|
919
|
+
result.put("y", relativeY / pixelRatio);
|
|
685
920
|
call.resolve(result);
|
|
686
921
|
bridge.releaseCall(call);
|
|
687
922
|
cameraStartCallbackId = null; // Prevent re-use
|
|
@@ -814,8 +1049,24 @@ public class CameraPreview
|
|
|
814
1049
|
.getDisplayMetrics();
|
|
815
1050
|
float pixelRatio = metrics.density;
|
|
816
1051
|
|
|
1052
|
+
// Check if edge-to-edge mode is active
|
|
1053
|
+
WebView webView = getBridge().getWebView();
|
|
1054
|
+
int webViewTopInset = 0;
|
|
1055
|
+
boolean isEdgeToEdgeActive = false;
|
|
1056
|
+
if (webView != null) {
|
|
1057
|
+
int[] location = new int[2];
|
|
1058
|
+
webView.getLocationOnScreen(location);
|
|
1059
|
+
webViewTopInset = location[1];
|
|
1060
|
+
isEdgeToEdgeActive = webViewTopInset > 0;
|
|
1061
|
+
}
|
|
1062
|
+
|
|
817
1063
|
int x = (xParam != null && xParam > 0) ? (int) (xParam * pixelRatio) : 0;
|
|
818
1064
|
int y = (yParam != null && yParam > 0) ? (int) (yParam * pixelRatio) : 0;
|
|
1065
|
+
|
|
1066
|
+
// Add edge-to-edge inset to Y if active
|
|
1067
|
+
if (isEdgeToEdgeActive && y > 0) {
|
|
1068
|
+
y += webViewTopInset;
|
|
1069
|
+
}
|
|
819
1070
|
int width = (widthParam != null && widthParam > 0)
|
|
820
1071
|
? (int) (widthParam * pixelRatio)
|
|
821
1072
|
: 0;
|