@capgo/camera-preview 7.4.0-alpha.19 → 7.4.0-alpha.22

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.
@@ -61,6 +61,8 @@ public class CameraPreview
61
61
  extends Plugin
62
62
  implements CameraXView.CameraXViewListener {
63
63
 
64
+ private static final String TAG = "CameraPreview CameraXView";
65
+
64
66
  static final String CAMERA_WITH_AUDIO_PERMISSION_ALIAS = "cameraWithAudio";
65
67
  static final String CAMERA_ONLY_PERMISSION_ALIAS = "cameraOnly";
66
68
  static final String CAMERA_WITH_LOCATION_PERMISSION_ALIAS =
@@ -1031,7 +1033,12 @@ public class CameraPreview
1031
1033
  .orientation;
1032
1034
  if (current != lastOrientation) {
1033
1035
  lastOrientation = current;
1034
- handleOrientationChange();
1036
+ // Post to next frame so WebView has updated bounds before we recompute layout
1037
+ getBridge()
1038
+ .getActivity()
1039
+ .getWindow()
1040
+ .getDecorView()
1041
+ .post(() -> handleOrientationChange());
1035
1042
  }
1036
1043
  }
1037
1044
  };
@@ -1044,13 +1051,115 @@ public class CameraPreview
1044
1051
 
1045
1052
  private void handleOrientationChange() {
1046
1053
  if (cameraXView == null || !cameraXView.isRunning()) return;
1054
+
1055
+ Log.d(
1056
+ TAG,
1057
+ "======================== ORIENTATION CHANGE DETECTED ========================"
1058
+ );
1059
+
1060
+ // Get comprehensive display and orientation information
1061
+ android.util.DisplayMetrics metrics = getContext()
1062
+ .getResources()
1063
+ .getDisplayMetrics();
1064
+ int screenWidthPx = metrics.widthPixels;
1065
+ int screenHeightPx = metrics.heightPixels;
1066
+ float density = metrics.density;
1067
+ int screenWidthDp = (int) (screenWidthPx / density);
1068
+ int screenHeightDp = (int) (screenHeightPx / density);
1069
+
1070
+ int current = getContext().getResources().getConfiguration().orientation;
1071
+ Log.d(TAG, "New orientation: " + current + " (1=PORTRAIT, 2=LANDSCAPE)");
1072
+ Log.d(
1073
+ TAG,
1074
+ "Screen dimensions - Pixels: " +
1075
+ screenWidthPx +
1076
+ "x" +
1077
+ screenHeightPx +
1078
+ ", DP: " +
1079
+ screenWidthDp +
1080
+ "x" +
1081
+ screenHeightDp +
1082
+ ", Density: " +
1083
+ density
1084
+ );
1085
+
1086
+ // Get WebView dimensions before rotation
1087
+ WebView webView = getBridge().getWebView();
1088
+ int webViewWidth = webView.getWidth();
1089
+ int webViewHeight = webView.getHeight();
1090
+ Log.d(TAG, "WebView dimensions: " + webViewWidth + "x" + webViewHeight);
1091
+
1092
+ // Get current preview bounds before rotation
1093
+ int[] oldBounds = cameraXView.getCurrentPreviewBounds();
1094
+ Log.d(
1095
+ TAG,
1096
+ "Current preview bounds before rotation: x=" +
1097
+ oldBounds[0] +
1098
+ ", y=" +
1099
+ oldBounds[1] +
1100
+ ", width=" +
1101
+ oldBounds[2] +
1102
+ ", height=" +
1103
+ oldBounds[3]
1104
+ );
1105
+
1047
1106
  getBridge()
1048
1107
  .getActivity()
1049
1108
  .runOnUiThread(() -> {
1050
1109
  // Reapply current aspect ratio to recompute layout, then emit screenResize
1051
1110
  String ar = cameraXView.getAspectRatio();
1052
- cameraXView.setAspectRatio(ar, null, null, () -> {
1111
+ Log.d(TAG, "Reapplying aspect ratio: " + ar);
1112
+
1113
+ // Re-get dimensions after potential layout pass
1114
+ android.util.DisplayMetrics newMetrics = getContext()
1115
+ .getResources()
1116
+ .getDisplayMetrics();
1117
+ int newScreenWidthPx = newMetrics.widthPixels;
1118
+ int newScreenHeightPx = newMetrics.heightPixels;
1119
+ int newWebViewWidth = webView.getWidth();
1120
+ int newWebViewHeight = webView.getHeight();
1121
+
1122
+ Log.d(
1123
+ TAG,
1124
+ "New screen dimensions after rotation: " +
1125
+ newScreenWidthPx +
1126
+ "x" +
1127
+ newScreenHeightPx
1128
+ );
1129
+ Log.d(
1130
+ TAG,
1131
+ "New WebView dimensions after rotation: " +
1132
+ newWebViewWidth +
1133
+ "x" +
1134
+ newWebViewHeight
1135
+ );
1136
+
1137
+ // Force aspect ratio recalculation on orientation change
1138
+ cameraXView.forceAspectRatioRecalculation(ar, null, null, () -> {
1053
1139
  int[] bounds = cameraXView.getCurrentPreviewBounds();
1140
+ Log.d(
1141
+ TAG,
1142
+ "New bounds after orientation change: x=" +
1143
+ bounds[0] +
1144
+ ", y=" +
1145
+ bounds[1] +
1146
+ ", width=" +
1147
+ bounds[2] +
1148
+ ", height=" +
1149
+ bounds[3]
1150
+ );
1151
+ Log.d(
1152
+ TAG,
1153
+ "Bounds change: deltaX=" +
1154
+ (bounds[0] - oldBounds[0]) +
1155
+ ", deltaY=" +
1156
+ (bounds[1] - oldBounds[1]) +
1157
+ ", deltaWidth=" +
1158
+ (bounds[2] - oldBounds[2]) +
1159
+ ", deltaHeight=" +
1160
+ (bounds[3] - oldBounds[3])
1161
+ );
1162
+
1054
1163
  JSObject data = new JSObject();
1055
1164
  data.put("x", bounds[0]);
1056
1165
  data.put("y", bounds[1]);
@@ -1059,10 +1168,6 @@ public class CameraPreview
1059
1168
  notifyListeners("screenResize", data);
1060
1169
 
1061
1170
  // Also emit orientationChange with a unified string value
1062
- int current = getContext()
1063
- .getResources()
1064
- .getConfiguration()
1065
- .orientation;
1066
1171
  String o;
1067
1172
  if (current == Configuration.ORIENTATION_PORTRAIT) {
1068
1173
  o = "portrait";
@@ -1074,6 +1179,11 @@ public class CameraPreview
1074
1179
  JSObject oData = new JSObject();
1075
1180
  oData.put("orientation", o);
1076
1181
  notifyListeners("orientationChange", oData);
1182
+
1183
+ Log.d(
1184
+ TAG,
1185
+ "================================================================================"
1186
+ );
1077
1187
  });
1078
1188
  });
1079
1189
  }
@@ -1171,11 +1281,116 @@ public class CameraPreview
1171
1281
  Log.d("CameraPreview", "12. PIXEL RATIO - " + pixelRatio);
1172
1282
  Log.d("CameraPreview", "========================");
1173
1283
 
1284
+ // Calculate logical values with proper rounding to avoid sub-pixel issues
1285
+ double logicalWidth = width / pixelRatio;
1286
+ double logicalHeight = height / pixelRatio;
1287
+ double logicalX = x / pixelRatio;
1288
+ double logicalY = relativeY / pixelRatio;
1289
+
1290
+ // Log exact calculations to debug one-pixel difference
1291
+ Log.d("CameraPreview", "========================");
1292
+ Log.d("CameraPreview", "FINAL POSITION CALCULATIONS:");
1293
+ Log.d(
1294
+ "CameraPreview",
1295
+ "Pixel values: x=" +
1296
+ x +
1297
+ ", y=" +
1298
+ relativeY +
1299
+ ", width=" +
1300
+ width +
1301
+ ", height=" +
1302
+ height
1303
+ );
1304
+ Log.d("CameraPreview", "Pixel ratio: " + pixelRatio);
1305
+ Log.d(
1306
+ "CameraPreview",
1307
+ "Logical values (exact): x=" +
1308
+ logicalX +
1309
+ ", y=" +
1310
+ logicalY +
1311
+ ", width=" +
1312
+ logicalWidth +
1313
+ ", height=" +
1314
+ logicalHeight
1315
+ );
1316
+ Log.d(
1317
+ "CameraPreview",
1318
+ "Logical values (rounded): x=" +
1319
+ Math.round(logicalX) +
1320
+ ", y=" +
1321
+ Math.round(logicalY) +
1322
+ ", width=" +
1323
+ Math.round(logicalWidth) +
1324
+ ", height=" +
1325
+ Math.round(logicalHeight)
1326
+ );
1327
+
1328
+ // Check if previewContainer has any padding or margin that might cause offset
1329
+ if (cameraXView != null) {
1330
+ View previewContainer = cameraXView.getPreviewContainer();
1331
+ if (previewContainer != null) {
1332
+ Log.d(
1333
+ "CameraPreview",
1334
+ "PreviewContainer padding: left=" +
1335
+ previewContainer.getPaddingLeft() +
1336
+ ", top=" +
1337
+ previewContainer.getPaddingTop() +
1338
+ ", right=" +
1339
+ previewContainer.getPaddingRight() +
1340
+ ", bottom=" +
1341
+ previewContainer.getPaddingBottom()
1342
+ );
1343
+ ViewGroup.LayoutParams params = previewContainer.getLayoutParams();
1344
+ if (params instanceof ViewGroup.MarginLayoutParams) {
1345
+ ViewGroup.MarginLayoutParams marginParams =
1346
+ (ViewGroup.MarginLayoutParams) params;
1347
+ Log.d(
1348
+ "CameraPreview",
1349
+ "PreviewContainer margins: left=" +
1350
+ marginParams.leftMargin +
1351
+ ", top=" +
1352
+ marginParams.topMargin +
1353
+ ", right=" +
1354
+ marginParams.rightMargin +
1355
+ ", bottom=" +
1356
+ marginParams.bottomMargin
1357
+ );
1358
+ }
1359
+ }
1360
+ }
1361
+ Log.d("CameraPreview", "========================");
1362
+
1174
1363
  JSObject result = new JSObject();
1175
- result.put("width", width / pixelRatio);
1176
- result.put("height", height / pixelRatio);
1177
- result.put("x", x / pixelRatio);
1178
- result.put("y", relativeY / pixelRatio);
1364
+ // Return values with proper rounding to avoid gaps
1365
+ // For positions (x, y): floor to avoid gaps at top/left
1366
+ // For dimensions (width, height): ceil to avoid gaps at bottom/right
1367
+ result.put("width", Math.floor(logicalWidth));
1368
+ result.put("height", Math.floor(logicalHeight));
1369
+ result.put("x", Math.ceil(logicalX));
1370
+ result.put("y", Math.ceil(logicalY));
1371
+
1372
+ // Log what we're returning
1373
+ Log.d(
1374
+ "CameraPreview",
1375
+ "Returning to JS - x: " +
1376
+ Math.ceil(logicalX) +
1377
+ " (from " +
1378
+ logicalX +
1379
+ "), y: " +
1380
+ Math.ceil(logicalY) +
1381
+ " (from " +
1382
+ logicalY +
1383
+ "), width: " +
1384
+ Math.floor(logicalWidth) +
1385
+ " (from " +
1386
+ logicalWidth +
1387
+ "), height: " +
1388
+ Math.floor(logicalHeight) +
1389
+ " (from " +
1390
+ logicalHeight +
1391
+ ")"
1392
+ );
1393
+
1179
1394
  call.resolve(result);
1180
1395
  bridge.releaseCall(call);
1181
1396
  cameraStartCallbackId = null; // Prevent re-use
@@ -1281,10 +1496,16 @@ public class CameraPreview
1281
1496
  float pixelRatio = metrics.density;
1282
1497
 
1283
1498
  JSObject ret = new JSObject();
1284
- ret.put("x", cameraXView.getPreviewX() / pixelRatio);
1285
- ret.put("y", cameraXView.getPreviewY() / pixelRatio);
1286
- ret.put("width", cameraXView.getPreviewWidth() / pixelRatio);
1287
- ret.put("height", cameraXView.getPreviewHeight() / pixelRatio);
1499
+ // Use same rounding strategy as start method
1500
+ double x = cameraXView.getPreviewX() / pixelRatio;
1501
+ double y = cameraXView.getPreviewY() / pixelRatio;
1502
+ double width = cameraXView.getPreviewWidth() / pixelRatio;
1503
+ double height = cameraXView.getPreviewHeight() / pixelRatio;
1504
+
1505
+ ret.put("x", Math.ceil(x));
1506
+ ret.put("y", Math.ceil(y));
1507
+ ret.put("width", Math.floor(width));
1508
+ ret.put("height", Math.floor(height));
1288
1509
  call.resolve(ret);
1289
1510
  }
1290
1511