@capgo/camera-preview 7.4.0-beta.7 → 7.4.0-beta.8

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 (41) hide show
  1. package/README.md +62 -28
  2. package/android/.gradle/8.14.2/checksums/checksums.lock +0 -0
  3. package/android/.gradle/8.14.2/checksums/md5-checksums.bin +0 -0
  4. package/android/.gradle/8.14.2/checksums/sha1-checksums.bin +0 -0
  5. package/android/.gradle/8.14.2/executionHistory/executionHistory.bin +0 -0
  6. package/android/.gradle/8.14.2/executionHistory/executionHistory.lock +0 -0
  7. package/android/.gradle/8.14.2/fileHashes/fileHashes.bin +0 -0
  8. package/android/.gradle/8.14.2/fileHashes/fileHashes.lock +0 -0
  9. package/android/.gradle/8.14.2/fileHashes/resourceHashesCache.bin +0 -0
  10. package/android/.gradle/buildOutputCleanup/buildOutputCleanup.lock +0 -0
  11. package/android/.gradle/buildOutputCleanup/cache.properties +1 -1
  12. package/android/.gradle/buildOutputCleanup/outputFiles.bin +0 -0
  13. package/android/.gradle/file-system.probe +0 -0
  14. package/android/build.gradle +1 -0
  15. package/android/src/main/java/com/ahm/capacitor/camera/preview/CameraPreview.java +127 -14
  16. package/android/src/main/java/com/ahm/capacitor/camera/preview/CameraXView.java +479 -29
  17. package/android/src/main/java/com/ahm/capacitor/camera/preview/GridOverlayView.java +2 -0
  18. package/dist/docs.json +46 -7
  19. package/dist/esm/definitions.d.ts +42 -5
  20. package/dist/esm/definitions.js.map +1 -1
  21. package/dist/esm/web.d.ts +25 -1
  22. package/dist/esm/web.js +81 -9
  23. package/dist/esm/web.js.map +1 -1
  24. package/dist/plugin.cjs.js +81 -9
  25. package/dist/plugin.cjs.js.map +1 -1
  26. package/dist/plugin.js +81 -9
  27. package/dist/plugin.js.map +1 -1
  28. package/ios/Sources/CapgoCameraPreview/CameraController.swift +95 -18
  29. package/ios/Sources/CapgoCameraPreview/Plugin.swift +271 -91
  30. package/package.json +1 -1
  31. package/android/.gradle/config.properties +0 -2
  32. package/android/.idea/AndroidProjectSystem.xml +0 -6
  33. package/android/.idea/caches/deviceStreaming.xml +0 -811
  34. package/android/.idea/compiler.xml +0 -6
  35. package/android/.idea/gradle.xml +0 -18
  36. package/android/.idea/migrations.xml +0 -10
  37. package/android/.idea/misc.xml +0 -10
  38. package/android/.idea/runConfigurations.xml +0 -17
  39. package/android/.idea/vcs.xml +0 -6
  40. package/android/.idea/workspace.xml +0 -55
  41. package/android/local.properties +0 -8
@@ -62,11 +62,14 @@ public class CameraPreview: CAPPlugin, CAPBridgedPlugin, CLLocationManagerDelega
62
62
  CAPPluginMethod(name: "setAspectRatio", returnType: CAPPluginReturnPromise),
63
63
  CAPPluginMethod(name: "getAspectRatio", returnType: CAPPluginReturnPromise),
64
64
  CAPPluginMethod(name: "setGridMode", returnType: CAPPluginReturnPromise),
65
- CAPPluginMethod(name: "getGridMode", returnType: CAPPluginReturnPromise)
65
+ CAPPluginMethod(name: "getGridMode", returnType: CAPPluginReturnPromise),
66
+ CAPPluginMethod(name: "getPreviewSize", returnType: CAPPluginReturnPromise),
67
+ CAPPluginMethod(name: "setPreviewSize", returnType: CAPPluginReturnPromise)
66
68
  ]
67
69
  // Camera state tracking
68
70
  private var isInitializing: Bool = false
69
71
  private var isInitialized: Bool = false
72
+ private var backgroundSession: AVCaptureSession?
70
73
 
71
74
  var previewView: UIView!
72
75
  var cameraPosition = String()
@@ -138,14 +141,26 @@ public class CameraPreview: CAPPlugin, CAPBridgedPlugin, CLLocationManagerDelega
138
141
  let paddingBottom = self.paddingBottom ?? 0
139
142
  let height = heightValue - paddingBottom
140
143
 
141
- if UIWindow.isLandscape {
142
- previewView.frame = CGRect(x: posY, y: posX, width: max(height, width), height: min(height, width))
143
- self.cameraController.previewLayer?.frame = previewView.frame
144
- }
144
+ // Handle auto-centering during rotation
145
+ if posX == -1 || posY == -1 {
146
+ // Trigger full recalculation for auto-centered views
147
+ self.updateCameraFrame()
148
+ } else {
149
+ // Manual positioning - use original rotation logic with no animation
150
+ CATransaction.begin()
151
+ CATransaction.setDisableActions(true)
152
+
153
+ if UIWindow.isLandscape {
154
+ previewView.frame = CGRect(x: posY, y: posX, width: max(height, width), height: min(height, width))
155
+ self.cameraController.previewLayer?.frame = previewView.bounds
156
+ }
145
157
 
146
- if UIWindow.isPortrait {
147
- previewView.frame = CGRect(x: posX, y: posY, width: min(height, width), height: max(height, width))
148
- self.cameraController.previewLayer?.frame = previewView.frame
158
+ if UIWindow.isPortrait {
159
+ previewView.frame = CGRect(x: posX, y: posY, width: min(height, width), height: max(height, width))
160
+ self.cameraController.previewLayer?.frame = previewView.bounds
161
+ }
162
+
163
+ CATransaction.commit()
149
164
  }
150
165
 
151
166
  if let connection = self.cameraController.fileVideoOutput?.connection(with: .video) {
@@ -165,11 +180,14 @@ public class CameraPreview: CAPPlugin, CAPBridgedPlugin, CLLocationManagerDelega
165
180
 
166
181
  cameraController.updateVideoOrientation()
167
182
 
168
- cameraController.updateVideoOrientation()
183
+ cameraController.updateVideoOrientation()
169
184
 
170
- // Update grid overlay frame if it exists
185
+ // Update grid overlay frame if it exists - no animation
171
186
  if let gridOverlay = self.cameraController.gridOverlayView {
187
+ CATransaction.begin()
188
+ CATransaction.setDisableActions(true)
172
189
  gridOverlay.frame = previewView.bounds
190
+ CATransaction.commit()
173
191
  }
174
192
 
175
193
  // Ensure webview remains transparent after rotation
@@ -183,9 +201,65 @@ public class CameraPreview: CAPPlugin, CAPBridgedPlugin, CLLocationManagerDelega
183
201
  call.reject("camera not started")
184
202
  return
185
203
  }
186
- self.aspectRatio = call.getString("aspectRatio")
204
+
205
+ guard let newAspectRatio = call.getString("aspectRatio") else {
206
+ call.reject("aspectRatio parameter is required")
207
+ return
208
+ }
209
+
210
+ self.aspectRatio = newAspectRatio
211
+
212
+ // When aspect ratio changes, calculate maximum size possible from current position
213
+ if let posX = self.posX, let posY = self.posY {
214
+ let webViewWidth = self.webView?.frame.width ?? UIScreen.main.bounds.width
215
+ let webViewHeight = self.webView?.frame.height ?? UIScreen.main.bounds.height
216
+ let paddingBottom = self.paddingBottom ?? 0
217
+
218
+ // Calculate available space from current position
219
+ let availableWidth: CGFloat
220
+ let availableHeight: CGFloat
221
+
222
+ if posX == -1 || posY == -1 {
223
+ // Auto-centering mode - use full dimensions
224
+ availableWidth = webViewWidth
225
+ availableHeight = webViewHeight - paddingBottom
226
+ } else {
227
+ // Manual positioning - calculate remaining space
228
+ availableWidth = webViewWidth - posX
229
+ availableHeight = webViewHeight - posY - paddingBottom
230
+ }
231
+
232
+ // Parse aspect ratio - convert to portrait orientation for camera use
233
+ let ratioParts = newAspectRatio.split(separator: ":").map { Double($0) ?? 1.0 }
234
+ // For camera, we want portrait orientation: 4:3 becomes 3:4, 16:9 becomes 9:16
235
+ let ratio = ratioParts[1] / ratioParts[0]
236
+
237
+ // Calculate maximum size that fits the aspect ratio in available space
238
+ let maxWidthByHeight = availableHeight * CGFloat(ratio)
239
+ let maxHeightByWidth = availableWidth / CGFloat(ratio)
240
+
241
+ if maxWidthByHeight <= availableWidth {
242
+ // Height is the limiting factor
243
+ self.width = maxWidthByHeight
244
+ self.height = availableHeight
245
+ } else {
246
+ // Width is the limiting factor
247
+ self.width = availableWidth
248
+ self.height = maxHeightByWidth
249
+ }
250
+
251
+ print("[CameraPreview] Aspect ratio changed to \(newAspectRatio), new size: \(self.width!)x\(self.height!)")
252
+ }
253
+
187
254
  self.updateCameraFrame()
188
- call.resolve()
255
+
256
+ // Return the actual preview bounds
257
+ var result = JSObject()
258
+ result["x"] = Double(self.previewView.frame.origin.x)
259
+ result["y"] = Double(self.previewView.frame.origin.y)
260
+ result["width"] = Double(self.previewView.frame.width)
261
+ result["height"] = Double(self.previewView.frame.height)
262
+ call.resolve(result)
189
263
  }
190
264
 
191
265
  @objc func getAspectRatio(_ call: CAPPluginCall) {
@@ -358,18 +432,18 @@ public class CameraPreview: CAPPlugin, CAPBridgedPlugin, CLLocationManagerDelega
358
432
  self.height = UIScreen.main.bounds.size.height
359
433
  }
360
434
 
361
- // Set x position - use 0 if not provided
362
- if let x = call.getInt("x"), x > 0 {
363
- self.posX = CGFloat(x) / UIScreen.main.scale
435
+ // Set x position - use exact CSS pixel value from web view, or mark for centering
436
+ if let x = call.getInt("x") {
437
+ self.posX = CGFloat(x)
364
438
  } else {
365
- self.posX = 0
439
+ self.posX = -1 // Use -1 to indicate auto-centering
366
440
  }
367
441
 
368
- // Set y position - use 0 if not provided
369
- if let y = call.getInt("y"), y > 0 {
370
- self.posY = CGFloat(y) / (call.getBool("includeSafeAreaInsets") ?? false ? 1.0 : UIScreen.main.scale) + (call.getBool("includeSafeAreaInsets") ?? false ? UIApplication.shared.windows.first?.safeAreaInsets.top ?? 0 : 0)
442
+ // Set y position - use exact CSS pixel value from web view, or mark for centering
443
+ if let y = call.getInt("y") {
444
+ self.posY = CGFloat(y)
371
445
  } else {
372
- self.posY = 0
446
+ self.posY = -1 // Use -1 to indicate auto-centering
373
447
  }
374
448
  if call.getInt("paddingBottom") != nil {
375
449
  self.paddingBottom = CGFloat(call.getInt("paddingBottom")!)
@@ -382,6 +456,10 @@ public class CameraPreview: CAPPlugin, CAPBridgedPlugin, CLLocationManagerDelega
382
456
  self.disableAudio = call.getBool("disableAudio") ?? true
383
457
  self.aspectRatio = call.getString("aspectRatio")
384
458
  self.gridMode = call.getString("gridMode") ?? "none"
459
+ if self.aspectRatio != nil && (call.getInt("width") != nil || call.getInt("height") != nil) {
460
+ call.reject("Cannot set both aspectRatio and size (width/height). Use setPreviewSize after start.")
461
+ return
462
+ }
385
463
 
386
464
  print("[CameraPreview] Camera start parameters - aspectRatio: \(String(describing: self.aspectRatio)), gridMode: \(self.gridMode)")
387
465
  print("[CameraPreview] Screen dimensions: \(UIScreen.main.bounds.size)")
@@ -403,54 +481,73 @@ public class CameraPreview: CAPPlugin, CAPBridgedPlugin, CLLocationManagerDelega
403
481
  call.reject(error.localizedDescription)
404
482
  return
405
483
  }
484
+ self.completeStartCamera(call: call)
485
+ }
486
+ }
487
+ }
488
+ })
489
+ }
406
490
 
407
- // Create and configure the preview view first
408
- self.updateCameraFrame()
409
-
410
- // Make webview transparent - comprehensive approach
411
- self.makeWebViewTransparent()
491
+ override public func load() {
492
+ super.load()
493
+ // Initialize camera session in background for faster startup
494
+ prepareBackgroundCamera()
495
+ }
412
496
 
413
- // Add the preview view to the webview's superview
414
- self.webView?.superview?.addSubview(self.previewView)
415
- if self.toBack! {
416
- self.webView?.superview?.bringSubviewToFront(self.webView!)
417
- }
497
+ private func prepareBackgroundCamera() {
498
+ DispatchQueue.global(qos: .background).async {
499
+ AVCaptureDevice.requestAccess(for: .video) { granted in
500
+ guard granted else { return }
501
+
502
+ // Pre-initialize camera controller for faster startup
503
+ DispatchQueue.main.async {
504
+ self.cameraController.prepareBasicSession()
505
+ }
506
+ }
507
+ }
508
+ }
418
509
 
419
- // Display the camera preview on the configured view
420
- try? self.cameraController.displayPreview(on: self.previewView)
510
+ private func completeStartCamera(call: CAPPluginCall) {
511
+ // Create and configure the preview view first
512
+ self.updateCameraFrame()
421
513
 
422
- let frontView = self.toBack! ? self.webView : self.previewView
423
- self.cameraController.setupGestures(target: frontView ?? self.previewView, enableZoom: self.enableZoom!)
514
+ // Make webview transparent - comprehensive approach
515
+ self.makeWebViewTransparent()
424
516
 
425
- // Add grid overlay if enabled
426
- if self.gridMode != "none" {
427
- self.cameraController.addGridOverlay(to: self.previewView, gridMode: self.gridMode)
428
- }
517
+ // Add the preview view to the webview itself to use same coordinate system
518
+ self.webView?.addSubview(self.previewView)
519
+ if self.toBack! {
520
+ self.webView?.sendSubviewToBack(self.previewView)
521
+ }
429
522
 
430
- if self.rotateWhenOrientationChanged == true {
431
- NotificationCenter.default.addObserver(self, selector: #selector(CameraPreview.rotated), name: UIDevice.orientationDidChangeNotification, object: nil)
432
- }
523
+ // Display the camera preview on the configured view
524
+ try? self.cameraController.displayPreview(on: self.previewView)
433
525
 
526
+ let frontView = self.toBack! ? self.webView : self.previewView
527
+ self.cameraController.setupGestures(target: frontView ?? self.previewView, enableZoom: self.enableZoom!)
434
528
 
435
- // Add observers for app state changes to maintain transparency
436
- NotificationCenter.default.addObserver(self, selector: #selector(CameraPreview.appDidBecomeActive), name: UIApplication.didBecomeActiveNotification, object: nil)
437
- NotificationCenter.default.addObserver(self, selector: #selector(CameraPreview.appWillEnterForeground), name: UIApplication.willEnterForegroundNotification, object: nil)
529
+ // Add grid overlay if enabled
530
+ if self.gridMode != "none" {
531
+ self.cameraController.addGridOverlay(to: self.previewView, gridMode: self.gridMode)
532
+ }
438
533
 
439
- self.isInitializing = false
440
- self.isInitialized = true
534
+ if self.rotateWhenOrientationChanged == true {
535
+ NotificationCenter.default.addObserver(self, selector: #selector(CameraPreview.rotated), name: UIDevice.orientationDidChangeNotification, object: nil)
536
+ }
441
537
 
442
- var returnedObject = JSObject()
443
- returnedObject["width"] = self.previewView.frame.width as any JSValue
444
- returnedObject["height"] = self.previewView.frame.height as any JSValue
445
- returnedObject["x"] = self.previewView.frame.origin.x as any JSValue
446
- returnedObject["y"] = self.previewView.frame.origin.y as any JSValue
447
- call.resolve(returnedObject)
538
+ // Add observers for app state changes to maintain transparency
539
+ NotificationCenter.default.addObserver(self, selector: #selector(CameraPreview.appDidBecomeActive), name: UIApplication.didBecomeActiveNotification, object: nil)
540
+ NotificationCenter.default.addObserver(self, selector: #selector(CameraPreview.appWillEnterForeground), name: UIApplication.willEnterForegroundNotification, object: nil)
448
541
 
449
- }
450
- }
451
- }
452
- })
542
+ self.isInitializing = false
543
+ self.isInitialized = true
453
544
 
545
+ var returnedObject = JSObject()
546
+ returnedObject["width"] = self.previewView.frame.width as any JSValue
547
+ returnedObject["height"] = self.previewView.frame.height as any JSValue
548
+ returnedObject["x"] = self.previewView.frame.origin.x as any JSValue
549
+ returnedObject["y"] = self.previewView.frame.origin.y as any JSValue
550
+ call.resolve(returnedObject)
454
551
  }
455
552
 
456
553
  @objc func flip(_ call: CAPPluginCall) {
@@ -478,8 +575,13 @@ public class CameraPreview: CAPPlugin, CAPBridgedPlugin, CLLocationManagerDelega
478
575
  try self.cameraController.switchCameras()
479
576
 
480
577
  DispatchQueue.main.async {
578
+ // Update preview layer frame without animation
579
+ CATransaction.begin()
580
+ CATransaction.setDisableActions(true)
481
581
  self.cameraController.previewLayer?.frame = self.previewView.bounds
482
582
  self.cameraController.previewLayer?.videoGravity = .resizeAspectFill
583
+ CATransaction.commit()
584
+
483
585
  self.previewView.isUserInteractionEnabled = true
484
586
 
485
587
 
@@ -930,8 +1032,13 @@ public class CameraPreview: CAPPlugin, CAPBridgedPlugin, CLLocationManagerDelega
930
1032
  try self.cameraController.swapToDevice(deviceId: deviceId)
931
1033
 
932
1034
  DispatchQueue.main.async {
1035
+ // Update preview layer frame without animation
1036
+ CATransaction.begin()
1037
+ CATransaction.setDisableActions(true)
933
1038
  self.cameraController.previewLayer?.frame = self.previewView.bounds
934
1039
  self.cameraController.previewLayer?.videoGravity = .resizeAspectFill
1040
+ CATransaction.commit()
1041
+
935
1042
  self.previewView.isUserInteractionEnabled = true
936
1043
 
937
1044
 
@@ -975,57 +1082,130 @@ public class CameraPreview: CAPPlugin, CAPBridgedPlugin, CLLocationManagerDelega
975
1082
  }
976
1083
 
977
1084
  private func updateCameraFrame() {
978
- print("[CameraPreview] updateCameraFrame called")
979
- print("[CameraPreview] width: \(String(describing: self.width)), height: \(String(describing: self.height)), posX: \(String(describing: self.posX)), posY: \(String(describing: self.posY))")
980
-
981
1085
  guard let width = self.width, var height = self.height, let posX = self.posX, let posY = self.posY else {
982
- print("[CameraPreview] Missing required frame parameters")
983
1086
  return
984
1087
  }
985
1088
 
986
1089
  let paddingBottom = self.paddingBottom ?? 0
987
1090
  height -= paddingBottom
988
1091
 
989
- var frame = CGRect(x: posX, y: posY, width: width, height: height)
990
- print("[CameraPreview] Initial frame: \(frame)")
991
-
992
- // Temporarily disable aspect ratio frame adjustment to debug black preview issue
993
- /*
994
- if let aspectRatio = self.aspectRatio {
995
- let ratioParts = aspectRatio.split(separator: ":").map { Double($0) ?? 1.0 }
996
- let ratio = ratioParts[0] / ratioParts[1]
997
- let viewWidth = Double(width)
998
- let viewHeight = Double(height)
999
-
1000
- print("[CameraPreview] Calculating aspect ratio frame: \(aspectRatio), ratio: \(ratio), viewSize: \(viewWidth)x\(viewHeight)")
1001
-
1002
- if viewWidth / ratio > viewHeight {
1003
- let newWidth = viewHeight * ratio
1004
- frame.origin.x += (viewWidth - newWidth) / 2
1005
- frame.size.width = newWidth
1006
- print("[CameraPreview] Adjusted width: \(newWidth)")
1007
- } else {
1008
- let newHeight = viewWidth / ratio
1009
- frame.origin.y += (viewHeight - newHeight) / 2
1010
- frame.size.height = newHeight
1011
- print("[CameraPreview] Adjusted height: \(newHeight)")
1092
+ // Cache webView dimensions for performance
1093
+ let webViewWidth = self.webView?.frame.width ?? UIScreen.main.bounds.width
1094
+ let webViewHeight = self.webView?.frame.height ?? UIScreen.main.bounds.height
1095
+
1096
+ var finalX = posX
1097
+ var finalY = posY
1098
+ var finalWidth = width
1099
+ var finalHeight = height
1100
+
1101
+ // Handle auto-centering when position is -1
1102
+ if posX == -1 || posY == -1 {
1103
+ finalWidth = webViewWidth
1104
+
1105
+ // Calculate height based on aspect ratio or use provided height
1106
+ if let aspectRatio = self.aspectRatio {
1107
+ let ratioParts = aspectRatio.split(separator: ":").compactMap { Double($0) }
1108
+ if ratioParts.count == 2 {
1109
+ // For camera, use portrait orientation: 4:3 becomes 3:4, 16:9 becomes 9:16
1110
+ let ratio = ratioParts[1] / ratioParts[0]
1111
+ finalHeight = finalWidth / CGFloat(ratio)
1112
+ }
1113
+ }
1114
+
1115
+ finalX = posX == -1 ? 0 : posX
1116
+
1117
+ if posY == -1 {
1118
+ let availableHeight = webViewHeight - paddingBottom
1119
+ finalY = finalHeight < availableHeight ? (availableHeight - finalHeight) / 2 : 0
1012
1120
  }
1013
1121
  }
1014
- */
1015
1122
 
1016
- print("[CameraPreview] Final calculated frame: \(frame)")
1123
+ var frame = CGRect(x: finalX, y: finalY, width: finalWidth, height: finalHeight)
1124
+
1125
+ // Apply aspect ratio adjustments only if not auto-centering
1126
+ if posX != -1 && posY != -1, let aspectRatio = self.aspectRatio {
1127
+ let ratioParts = aspectRatio.split(separator: ":").compactMap { Double($0) }
1128
+ if ratioParts.count == 2 {
1129
+ // For camera, use portrait orientation: 4:3 becomes 3:4, 16:9 becomes 9:16
1130
+ let ratio = ratioParts[1] / ratioParts[0]
1131
+ let currentRatio = Double(finalWidth) / Double(finalHeight)
1132
+
1133
+ if currentRatio > ratio {
1134
+ let newWidth = Double(finalHeight) * ratio
1135
+ frame.origin.x = finalX + (Double(finalWidth) - newWidth) / 2
1136
+ frame.size.width = CGFloat(newWidth)
1137
+ } else {
1138
+ let newHeight = Double(finalWidth) / ratio
1139
+ frame.origin.y = finalY + (Double(finalHeight) - newHeight) / 2
1140
+ frame.size.height = CGFloat(newHeight)
1141
+ }
1142
+ }
1143
+ }
1017
1144
 
1145
+ // Disable ALL animations for frame updates - we want instant positioning
1146
+ CATransaction.begin()
1147
+ CATransaction.setDisableActions(true)
1148
+
1149
+ // Batch UI updates for better performance
1018
1150
  if self.previewView == nil {
1019
- print("[CameraPreview] Creating new preview view with frame: \(frame)")
1020
1151
  self.previewView = UIView(frame: frame)
1021
- self.previewView.backgroundColor = UIColor.black // Add background color for debugging
1152
+ self.previewView.backgroundColor = UIColor.clear
1022
1153
  } else {
1023
- print("[CameraPreview] Updating existing preview view frame to: \(frame)")
1024
1154
  self.previewView.frame = frame
1025
1155
  }
1026
1156
 
1027
- // Update the preview layer frame to match the preview view
1028
- self.cameraController.previewLayer?.frame = frame
1029
- print("[CameraPreview] Set preview layer frame to: \(frame)")
1157
+ // Update preview layer frame efficiently
1158
+ if let previewLayer = self.cameraController.previewLayer {
1159
+ previewLayer.frame = self.previewView.bounds
1160
+ }
1161
+
1162
+ // Update grid overlay frame if it exists
1163
+ if let gridOverlay = self.cameraController.gridOverlayView {
1164
+ gridOverlay.frame = self.previewView.bounds
1165
+ }
1166
+
1167
+ CATransaction.commit()
1168
+ }
1169
+
1170
+ @objc func getPreviewSize(_ call: CAPPluginCall) {
1171
+ guard self.isInitialized else {
1172
+ call.reject("camera not started")
1173
+ return
1174
+ }
1175
+ var result = JSObject()
1176
+ result["x"] = Double(self.previewView.frame.origin.x)
1177
+ result["y"] = Double(self.previewView.frame.origin.y)
1178
+ result["width"] = Double(self.previewView.frame.width)
1179
+ result["height"] = Double(self.previewView.frame.height)
1180
+ call.resolve(result)
1181
+ }
1182
+
1183
+ @objc func setPreviewSize(_ call: CAPPluginCall) {
1184
+ guard self.isInitialized else {
1185
+ call.reject("camera not started")
1186
+ return
1187
+ }
1188
+
1189
+ // Only update position if explicitly provided, otherwise keep auto-centering
1190
+ if let x = call.getInt("x") {
1191
+ self.posX = CGFloat(x)
1192
+ }
1193
+ if let y = call.getInt("y") {
1194
+ self.posY = CGFloat(y)
1195
+ }
1196
+ if let width = call.getInt("width") { self.width = CGFloat(width) }
1197
+ if let height = call.getInt("height") { self.height = CGFloat(height) }
1198
+
1199
+ // Direct update without animation for better performance
1200
+ self.updateCameraFrame()
1201
+ self.makeWebViewTransparent()
1202
+
1203
+ // Return the actual preview bounds
1204
+ var result = JSObject()
1205
+ result["x"] = Double(self.previewView.frame.origin.x)
1206
+ result["y"] = Double(self.previewView.frame.origin.y)
1207
+ result["width"] = Double(self.previewView.frame.width)
1208
+ result["height"] = Double(self.previewView.frame.height)
1209
+ call.resolve(result)
1030
1210
  }
1031
1211
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@capgo/camera-preview",
3
- "version": "7.4.0-beta.7",
3
+ "version": "7.4.0-beta.8",
4
4
  "description": "Camera preview",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -1,2 +0,0 @@
1
- #Tue Jul 01 15:51:45 CEST 2025
2
- java.home=/Applications/Android Studio.app/Contents/jbr/Contents/Home
@@ -1,6 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <project version="4">
3
- <component name="AndroidProjectSystem">
4
- <option name="providerId" value="com.android.tools.idea.GradleProjectSystem" />
5
- </component>
6
- </project>