Added zoom control
Added max zoom control Added onZoom handler
This commit is contained in:
parent
6e054145bf
commit
f58bc77ef1
4
.github/workflows/build.yml
vendored
4
.github/workflows/build.yml
vendored
@ -9,8 +9,6 @@ jobs:
|
||||
uses: actions/checkout@v2
|
||||
- name: Install modules
|
||||
run: yarn
|
||||
- name: Bootstrap
|
||||
run: yarn bootstrap
|
||||
- name: Build
|
||||
run: cd example/ios && xcodebuild -workspace CameraKitExample.xcworkspace -configuration Debug -scheme CameraKitExample -sdk iphoneos build CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO
|
||||
build-example-android:
|
||||
@ -23,7 +21,5 @@ jobs:
|
||||
uses: gradle/wrapper-validation-action@v1
|
||||
- name: Install modules
|
||||
run: yarn
|
||||
- name: Bootstrap
|
||||
run: yarn bootstrap
|
||||
- name: Build
|
||||
run: cd example/android && ./gradlew assembleDebug
|
||||
|
||||
2
.github/workflows/linter.yml
vendored
2
.github/workflows/linter.yml
vendored
@ -8,6 +8,6 @@ jobs:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
- name: Install modules
|
||||
run: yarn
|
||||
run: yarn --ignore-scripts
|
||||
- name: Lint
|
||||
run: yarn lint
|
||||
|
||||
@ -575,7 +575,7 @@ EXTERNAL SOURCES:
|
||||
SPEC CHECKSUMS:
|
||||
boost: 57d2868c099736d80fcd648bf211b4431e51a558
|
||||
CocoaAsyncSocket: 065fd1e645c7abab64f7a6a2007a48038fdc6a99
|
||||
DoubleConversion: 5189b271737e1565bdce30deb4a08d647e3f5f54
|
||||
DoubleConversion: cde416483dac037923206447da6e1454df403714
|
||||
FBLazyVector: f637f31eacba90d4fdeff3fa41608b8f361c173b
|
||||
FBReactNativeSpec: 0d9a4f4de7ab614c49e98c00aedfd3bfbda33d59
|
||||
Flipper: 26fc4b7382499f1281eb8cb921e5c3ad6de91fe0
|
||||
@ -588,7 +588,7 @@ SPEC CHECKSUMS:
|
||||
Flipper-RSocket: d9d9ade67cbecf6ac10730304bf5607266dd2541
|
||||
FlipperKit: cbdee19bdd4e7f05472a66ce290f1b729ba3cb86
|
||||
fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9
|
||||
glog: 04b94705f318337d7ead9e6d17c019bd9b1f6b1b
|
||||
glog: 40a13f7840415b9a77023fbcae0f1e6f43192af3
|
||||
hermes-engine: 47986d26692ae75ee7a17ab049caee8864f855de
|
||||
libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913
|
||||
OpenSSL-Universal: ebc357f1e6bc71fa463ccb2fe676756aff50e88c
|
||||
|
||||
@ -128,6 +128,7 @@ const BarcodeExample = ({ onBack }: { onBack: () => void }) => {
|
||||
flashMode={flashData?.mode}
|
||||
zoomMode="on"
|
||||
focusMode="on"
|
||||
maxZoom={5}
|
||||
torchMode={torchMode ? 'on' : 'off'}
|
||||
onOrientationChange={(e) => {
|
||||
// We recommend locking the camera UI to portrait (using a different library)
|
||||
|
||||
@ -34,6 +34,7 @@ const CameraExample = ({ onBack }: { onBack: () => void }) => {
|
||||
const [captured, setCaptured] = useState(false);
|
||||
const [cameraType, setCameraType] = useState(CameraType.Back);
|
||||
const [showImageUri, setShowImageUri] = useState<string>('');
|
||||
const [zoom, setZoom] = useState(0);
|
||||
|
||||
// iOS will error out if capturing too fast,
|
||||
// so block capturing until the current capture is done
|
||||
@ -54,6 +55,7 @@ const CameraExample = ({ onBack }: { onBack: () => void }) => {
|
||||
const onSwitchCameraPressed = () => {
|
||||
const direction = cameraType === CameraType.Back ? CameraType.Front : CameraType.Back;
|
||||
setCameraType(direction);
|
||||
setZoom(0); // When changing camera type, reset to default zoom for that camera
|
||||
};
|
||||
|
||||
const onSetFlash = () => {
|
||||
@ -101,6 +103,10 @@ const CameraExample = ({ onBack }: { onBack: () => void }) => {
|
||||
<Image source={require('../images/cameraFlipIcon.png')} resizeMode="contain" />
|
||||
</TouchableOpacity>
|
||||
|
||||
<TouchableOpacity style={styles.zoom} onPress={() => setZoom(0)}>
|
||||
<Text style={styles.zoomFactor}>{Number(zoom).toFixed(1)}x</Text>
|
||||
</TouchableOpacity>
|
||||
|
||||
<TouchableOpacity style={styles.topButton} onPress={onSetTorch}>
|
||||
<Image
|
||||
source={torchMode ? require('../images/torchOn.png') : require('../images/torchOff.png')}
|
||||
@ -120,12 +126,18 @@ const CameraExample = ({ onBack }: { onBack: () => void }) => {
|
||||
flashMode={flashData?.mode}
|
||||
zoomMode="on"
|
||||
focusMode="on"
|
||||
zoom={zoom}
|
||||
maxZoom={15}
|
||||
torchMode={torchMode ? 'on' : 'off'}
|
||||
onZoom={(e) => {
|
||||
console.log('zoom', e.nativeEvent.zoom);
|
||||
setZoom(e.nativeEvent.zoom);
|
||||
}}
|
||||
onOrientationChange={(e) => {
|
||||
// We recommend locking the camera UI to portrait (using a different library)
|
||||
// and rotating the UI elements counter to the orientation
|
||||
// However, we include onOrientationChange so you can match your UI to what the camera does
|
||||
switch(e.nativeEvent.orientation) {
|
||||
switch (e.nativeEvent.orientation) {
|
||||
case Orientation.LANDSCAPE_LEFT:
|
||||
console.log('orientationChange', 'LANDSCAPE_LEFT');
|
||||
break;
|
||||
@ -141,7 +153,7 @@ const CameraExample = ({ onBack }: { onBack: () => void }) => {
|
||||
default:
|
||||
console.log('orientationChange', e.nativeEvent);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
@ -235,6 +247,13 @@ const styles = StyleSheet.create({
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
},
|
||||
zoom: {
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
},
|
||||
zoomFactor: {
|
||||
color: '#ffffff',
|
||||
},
|
||||
thumbnailContainer: {
|
||||
flex: 1,
|
||||
alignItems: 'flex-end',
|
||||
|
||||
@ -29,10 +29,13 @@ RCT_EXPORT_VIEW_PROPERTY(laserColor, UIColor)
|
||||
RCT_EXPORT_VIEW_PROPERTY(frameColor, UIColor)
|
||||
|
||||
RCT_EXPORT_VIEW_PROPERTY(onOrientationChange, RCTDirectEventBlock)
|
||||
RCT_EXPORT_VIEW_PROPERTY(onZoom, RCTDirectEventBlock)
|
||||
RCT_EXPORT_VIEW_PROPERTY(resetFocusTimeout, NSInteger)
|
||||
RCT_EXPORT_VIEW_PROPERTY(resetFocusWhenMotionDetected, BOOL)
|
||||
RCT_EXPORT_VIEW_PROPERTY(focusMode, CKFocusMode)
|
||||
RCT_EXPORT_VIEW_PROPERTY(zoomMode, CKZoomMode)
|
||||
RCT_EXPORT_VIEW_PROPERTY(zoom, NSNumber)
|
||||
RCT_EXPORT_VIEW_PROPERTY(maxZoom, NSNumber)
|
||||
|
||||
RCT_EXTERN_METHOD(capture:(NSDictionary*)options
|
||||
resolve:(RCTPromiseResolveBlock)resolve
|
||||
|
||||
@ -11,11 +11,16 @@ protocol CameraProtocol: AnyObject, FocusInterfaceViewDelegate {
|
||||
func setup(cameraType: CameraType, supportedBarcodeType: [AVMetadataObject.ObjectType])
|
||||
func cameraRemovedFromSuperview()
|
||||
|
||||
func update(pinchScale: CGFloat)
|
||||
func update(torchMode: TorchMode)
|
||||
func update(flashMode: FlashMode)
|
||||
func update(cameraType: CameraType)
|
||||
func update(onOrientationChange: RCTDirectEventBlock?)
|
||||
func update(onZoom: RCTDirectEventBlock?)
|
||||
func update(zoom: Double?)
|
||||
func update(maxZoom: Double?)
|
||||
|
||||
func zoomPinchStart()
|
||||
func zoomPinchChange(pinchScale: CGFloat)
|
||||
|
||||
func isBarcodeScannerEnabled(_ isEnabled: Bool,
|
||||
supportedBarcodeType: [AVMetadataObject.ObjectType],
|
||||
|
||||
@ -47,10 +47,13 @@ class CameraView: UIView {
|
||||
@objc var laserColor: UIColor?
|
||||
// other
|
||||
@objc var onOrientationChange: RCTDirectEventBlock?
|
||||
@objc var onZoom: RCTDirectEventBlock?
|
||||
@objc var resetFocusTimeout = 0
|
||||
@objc var resetFocusWhenMotionDetected = false
|
||||
@objc var focusMode: FocusMode = .on
|
||||
@objc var zoomMode: ZoomMode = .on
|
||||
@objc var zoom: NSNumber?
|
||||
@objc var maxZoom: NSNumber?
|
||||
|
||||
// MARK: - Setup
|
||||
|
||||
@ -149,6 +152,10 @@ class CameraView: UIView {
|
||||
if changedProps.contains("onOrientationChange") {
|
||||
camera.update(onOrientationChange: onOrientationChange)
|
||||
}
|
||||
|
||||
if changedProps.contains("onZoom") {
|
||||
camera.update(onZoom: onZoom)
|
||||
}
|
||||
|
||||
// Ratio overlay
|
||||
if changedProps.contains("ratioOverlay") {
|
||||
@ -217,6 +224,14 @@ class CameraView: UIView {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if changedProps.contains("zoom") {
|
||||
camera.update(zoom: zoom?.doubleValue)
|
||||
}
|
||||
|
||||
if changedProps.contains("maxZoom") {
|
||||
camera.update(maxZoom: maxZoom?.doubleValue)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: Public
|
||||
@ -240,7 +255,7 @@ class CameraView: UIView {
|
||||
}
|
||||
}, onError: onError)
|
||||
}
|
||||
|
||||
|
||||
// MARK: - Private Helper
|
||||
|
||||
private func handleCameraPermission() {
|
||||
@ -310,10 +325,11 @@ class CameraView: UIView {
|
||||
// MARK: - Gesture selectors
|
||||
|
||||
@objc func handlePinchToZoomRecognizer(_ pinchRecognizer: UIPinchGestureRecognizer) {
|
||||
if pinchRecognizer.state == .began {
|
||||
camera.zoomPinchStart()
|
||||
}
|
||||
if pinchRecognizer.state == .changed {
|
||||
camera.update(pinchScale: pinchRecognizer.scale)
|
||||
// Reset scale after every reading to get a one timeframe scale value. Otherwise pinchRecognizer.scale is relative to the start of the gesture
|
||||
pinchRecognizer.scale = 1.0
|
||||
camera.zoomPinchChange(pinchScale: pinchRecognizer.scale)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -34,6 +34,9 @@ class RealCamera: NSObject, CameraProtocol, AVCaptureMetadataOutputObjectsDelega
|
||||
private var onBarcodeRead: ((_ barcode: String) -> Void)?
|
||||
private var scannerFrameSize: CGRect? = nil
|
||||
private var onOrientationChange: RCTDirectEventBlock?
|
||||
private var onZoom: RCTDirectEventBlock?
|
||||
private var zoom: Double?
|
||||
private var maxZoom: Double?
|
||||
|
||||
private var deviceOrientation = UIDeviceOrientation.unknown
|
||||
private var motionManager: CMMotionManager?
|
||||
@ -118,8 +121,16 @@ class RealCamera: NSObject, CameraProtocol, AVCaptureMetadataOutputObjectsDelega
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private var zoomStartedAt: Double = 1.0
|
||||
func zoomPinchStart() {
|
||||
sessionQueue.async {
|
||||
guard let videoDevice = self.videoDeviceInput?.device else { return }
|
||||
self.zoomStartedAt = videoDevice.videoZoomFactor
|
||||
}
|
||||
}
|
||||
|
||||
func update(pinchScale: CGFloat) {
|
||||
func zoomPinchChange(pinchScale: CGFloat) {
|
||||
guard !pinchScale.isNaN else { return }
|
||||
|
||||
sessionQueue.async {
|
||||
@ -127,17 +138,70 @@ class RealCamera: NSObject, CameraProtocol, AVCaptureMetadataOutputObjectsDelega
|
||||
|
||||
do {
|
||||
try videoDevice.lockForConfiguration()
|
||||
defer { videoDevice.unlockForConfiguration() }
|
||||
|
||||
let desiredZoomFactor = videoDevice.videoZoomFactor * pinchScale
|
||||
let maxZoomFactor = min(20, videoDevice.maxAvailableVideoZoomFactor)
|
||||
videoDevice.videoZoomFactor = max(1.0, min(desiredZoomFactor, maxZoomFactor))
|
||||
|
||||
videoDevice.unlockForConfiguration()
|
||||
let desiredZoomFactor = self.zoomStartedAt * pinchScale
|
||||
var maxZoomFactor = videoDevice.maxAvailableVideoZoomFactor
|
||||
if let maxZoom = self.maxZoom {
|
||||
maxZoomFactor = min(maxZoom, maxZoomFactor)
|
||||
}
|
||||
let zoomForDevice = max(1.0, min(desiredZoomFactor, maxZoomFactor))
|
||||
|
||||
if zoomForDevice != videoDevice.videoZoomFactor {
|
||||
// Only trigger zoom changes if it's an uncontrolled component (zoom isn't manually set)
|
||||
// otherwise it's likely to cause issues inf. loops
|
||||
if self.zoom == nil {
|
||||
videoDevice.videoZoomFactor = zoomForDevice
|
||||
}
|
||||
self.onZoom?(["zoom": zoomForDevice])
|
||||
}
|
||||
} catch {
|
||||
print("Error setting zoom factor: \(error)")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func update(maxZoom: Double?) {
|
||||
self.maxZoom = maxZoom
|
||||
}
|
||||
|
||||
func update(zoom: Double?) {
|
||||
self.zoom = zoom
|
||||
|
||||
sessionQueue.async {
|
||||
guard let videoDevice = self.videoDeviceInput?.device else { return }
|
||||
|
||||
var zoomOrDefault = zoom ?? 0
|
||||
// -1 will reset to zoom default (which is not 1 on modern cameras)
|
||||
if zoomOrDefault == 0 {
|
||||
zoomOrDefault = self.wideAngleZoomFactor(for: videoDevice)
|
||||
}
|
||||
|
||||
do {
|
||||
try videoDevice.lockForConfiguration()
|
||||
defer { videoDevice.unlockForConfiguration() }
|
||||
|
||||
var maxZoomFactor = videoDevice.maxAvailableVideoZoomFactor
|
||||
if let maxZoom = self.maxZoom {
|
||||
maxZoomFactor = min(maxZoom, maxZoomFactor)
|
||||
}
|
||||
let zoomForDevice = max(1.0, min(zoomOrDefault, maxZoomFactor))
|
||||
videoDevice.videoZoomFactor = zoomForDevice
|
||||
|
||||
// If they wanted to reset, tell them what the default zoom turned out to be
|
||||
// regardless if it's controlled
|
||||
if self.zoom == nil || zoom == 0 {
|
||||
self.onZoom?(["zoom": zoomForDevice])
|
||||
}
|
||||
} catch {
|
||||
print("Error setting zoom factor: \(error)")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func update(onZoom: RCTDirectEventBlock?) {
|
||||
self.onZoom = onZoom
|
||||
}
|
||||
|
||||
func focus(at touchPoint: CGPoint, focusBehavior: FocusBehavior) {
|
||||
DispatchQueue.main.async {
|
||||
@ -227,7 +291,11 @@ class RealCamera: NSObject, CameraProtocol, AVCaptureMetadataOutputObjectsDelega
|
||||
|
||||
if self.session.canAddInput(videoDeviceInput) {
|
||||
self.session.addInput(videoDeviceInput)
|
||||
videoDevice.videoZoomFactor = self.wideAngleZoomFactor(for: videoDevice)
|
||||
let zoomForDevice = self.wideAngleZoomFactor(for: videoDevice)
|
||||
if self.zoom == nil {
|
||||
videoDevice.videoZoomFactor = zoomForDevice
|
||||
}
|
||||
self.onZoom?(["zoom": zoomForDevice])
|
||||
self.videoDeviceInput = videoDeviceInput
|
||||
} else {
|
||||
// If it fails, put back current camera
|
||||
@ -408,7 +476,11 @@ class RealCamera: NSObject, CameraProtocol, AVCaptureMetadataOutputObjectsDelega
|
||||
|
||||
if session.canAddInput(videoDeviceInput) {
|
||||
session.addInput(videoDeviceInput)
|
||||
videoDevice.videoZoomFactor = wideAngleZoomFactor(for: videoDevice)
|
||||
let zoomForDevice = wideAngleZoomFactor(for: videoDevice)
|
||||
if self.zoom == nil {
|
||||
videoDevice.videoZoomFactor = zoomForDevice
|
||||
}
|
||||
self.onZoom?(["zoom": zoomForDevice])
|
||||
self.videoDeviceInput = videoDeviceInput
|
||||
} else {
|
||||
return .sessionConfigurationFailed
|
||||
|
||||
@ -11,6 +11,12 @@ import UIKit
|
||||
*/
|
||||
class SimulatorCamera: CameraProtocol {
|
||||
private var onOrientationChange: RCTDirectEventBlock?
|
||||
private var onZoom: RCTDirectEventBlock?
|
||||
private var videoDeviceZoomFactor: Double = 1.0
|
||||
private var videoDeviceMaxAvailableVideoZoomFactor: Double = 150.0
|
||||
private var wideAngleZoomFactor: Double = 2.0
|
||||
private var zoom: Double?
|
||||
private var maxZoom: Double?
|
||||
|
||||
var previewView: UIView { mockPreview }
|
||||
|
||||
@ -54,9 +60,42 @@ class SimulatorCamera: CameraProtocol {
|
||||
self.onOrientationChange = onOrientationChange
|
||||
}
|
||||
|
||||
func update(pinchScale: CGFloat) {
|
||||
func update(onZoom: RCTDirectEventBlock?) {
|
||||
self.onZoom = onZoom
|
||||
}
|
||||
|
||||
func setVideoDevice(zoomFactor: Double) {
|
||||
self.videoDeviceZoomFactor = zoomFactor
|
||||
self.mockPreview.zoomLabel.text = "Zoom: \(zoomFactor)"
|
||||
}
|
||||
|
||||
private var zoomStartedAt: Double = 1.0
|
||||
func zoomPinchStart() {
|
||||
DispatchQueue.main.async {
|
||||
self.mockPreview.zoomVelocityLabel.text = "Zoom Scale: \(pinchScale)"
|
||||
self.zoomStartedAt = self.videoDeviceZoomFactor
|
||||
self.mockPreview.zoomLabel.text = "Zoom start"
|
||||
}
|
||||
}
|
||||
|
||||
func zoomPinchChange(pinchScale: CGFloat) {
|
||||
guard !pinchScale.isNaN else { return }
|
||||
|
||||
DispatchQueue.main.async {
|
||||
let desiredZoomFactor = self.zoomStartedAt * pinchScale
|
||||
var maxZoomFactor = self.videoDeviceMaxAvailableVideoZoomFactor
|
||||
if let maxZoom = self.maxZoom {
|
||||
maxZoomFactor = min(maxZoom, maxZoomFactor)
|
||||
}
|
||||
let zoomForDevice = max(1.0, min(desiredZoomFactor, maxZoomFactor))
|
||||
|
||||
if zoomForDevice != self.videoDeviceZoomFactor {
|
||||
// Only trigger zoom changes if it's an uncontrolled component (zoom isn't manually set)
|
||||
// otherwise it's likely to cause issues inf. loops
|
||||
if self.zoom == nil {
|
||||
self.setVideoDevice(zoomFactor: zoomForDevice)
|
||||
}
|
||||
self.onZoom?(["zoom": zoomForDevice])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -93,6 +132,36 @@ class SimulatorCamera: CameraProtocol {
|
||||
self.mockPreview.randomize()
|
||||
}
|
||||
}
|
||||
|
||||
func update(maxZoom: Double?) {
|
||||
self.maxZoom = maxZoom
|
||||
}
|
||||
|
||||
func update(zoom: Double?) {
|
||||
self.zoom = zoom
|
||||
|
||||
DispatchQueue.main.async {
|
||||
var zoomOrDefault = zoom ?? 0
|
||||
// -1 will reset to zoom default (which is not 1 on modern cameras)
|
||||
if zoomOrDefault == 0 {
|
||||
zoomOrDefault = self.wideAngleZoomFactor
|
||||
}
|
||||
|
||||
var maxZoomFactor = self.videoDeviceMaxAvailableVideoZoomFactor
|
||||
if let maxZoom = self.maxZoom {
|
||||
maxZoomFactor = min(maxZoom, maxZoomFactor)
|
||||
}
|
||||
let zoomForDevice = max(1.0, min(zoomOrDefault, maxZoomFactor))
|
||||
self.setVideoDevice(zoomFactor: zoomForDevice)
|
||||
|
||||
// If they wanted to reset, tell them what the default zoom turned out to be
|
||||
// regardless if it's controlled
|
||||
if self.zoom == nil || zoom == 0 {
|
||||
self.onZoom?(["zoom": zoomForDevice])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func isBarcodeScannerEnabled(_ isEnabled: Bool,
|
||||
supportedBarcodeType: [AVMetadataObject.ObjectType],
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
import UIKit
|
||||
|
||||
class SimulatorPreviewView: UIView {
|
||||
let zoomVelocityLabel = UILabel()
|
||||
let zoomLabel = UILabel()
|
||||
let focusAtLabel = UILabel()
|
||||
let torchModeLabel = UILabel()
|
||||
let flashModeLabel = UILabel()
|
||||
@ -30,7 +30,7 @@ class SimulatorPreviewView: UIView {
|
||||
stackView.translatesAutoresizingMaskIntoConstraints = false
|
||||
stackView.topAnchor.constraint(equalTo: safeAreaLayoutGuide.topAnchor).isActive = true
|
||||
stackView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 10).isActive = true
|
||||
[zoomVelocityLabel, focusAtLabel, torchModeLabel, flashModeLabel, cameraTypeLabel].forEach {
|
||||
[zoomLabel, focusAtLabel, torchModeLabel, flashModeLabel, cameraTypeLabel].forEach {
|
||||
$0.numberOfLines = 0
|
||||
stackView.addArrangedSubview($0)
|
||||
}
|
||||
|
||||
@ -32,8 +32,8 @@ const Camera = React.forwardRef((props: CameraProps, ref) => {
|
||||
return (
|
||||
<NativeCamera
|
||||
style={{ minWidth: 100, minHeight: 100 }}
|
||||
flashMode={props.flashMode}
|
||||
ref={nativeRef}
|
||||
maxZoom={props.maxZoom ?? 20}
|
||||
{...transformedProps}
|
||||
/>
|
||||
);
|
||||
|
||||
56
src/Camera.d.ts
vendored
56
src/Camera.d.ts
vendored
@ -13,16 +13,72 @@ export type OnOrientationChangeData = {
|
||||
};
|
||||
};
|
||||
|
||||
export type OnZoom = {
|
||||
nativeEvent: {
|
||||
zoom: number;
|
||||
};
|
||||
}
|
||||
|
||||
export interface CameraProps {
|
||||
ref?: LegacyRef<Component<CameraApi, {}, any>>;
|
||||
style?: StyleProp<ViewStyle>;
|
||||
// Behavior
|
||||
flashMode?: FlashMode;
|
||||
focusMode?: FocusMode;
|
||||
/**
|
||||
* Enable or disable the pinch gesture handler
|
||||
* Example:
|
||||
* ```
|
||||
* <Camera zoom="on" />
|
||||
* ```
|
||||
*/
|
||||
zoomMode?: ZoomMode;
|
||||
/**
|
||||
* **iOS only.**
|
||||
* Control zoom. `0` is resets zoom. `1` is the widest zoom possible. Higher values zooms in.
|
||||
* Example:
|
||||
* ```
|
||||
* const [zoom, setZoom] = useState(0);
|
||||
* <Button onPress={() => setZoom(0)} title="Reset" />
|
||||
* <Camera
|
||||
* zoom={zoom}
|
||||
* onZoom={(e) => {
|
||||
* setZoom(e.nativeEvent.zoom);
|
||||
* console.log('zoom', e.nativeEvent.zoom);
|
||||
* }}
|
||||
* />
|
||||
* ```
|
||||
*/
|
||||
zoom?: number;
|
||||
/** Maximum zoom factor. Default 20.
|
||||
* Should be at least 1.0 (no zoom, widest angle).
|
||||
* Modern iPhones will otherwise have a maximum zoom factor of >150
|
||||
* Example:
|
||||
* ```
|
||||
* <Camera
|
||||
* maxZoom={15}
|
||||
* />
|
||||
* ```
|
||||
*/
|
||||
maxZoom?: number;
|
||||
torchMode?: TorchMode;
|
||||
cameraType?: CameraType;
|
||||
onOrientationChange?: (event: OnOrientationChangeData) => void;
|
||||
/**
|
||||
* **iOS only.**
|
||||
* Triggered when:
|
||||
* - User pinches to zoom, or
|
||||
* - 'zoom={0}' prop is set to 0, which resets zoom for the camera
|
||||
* Example:
|
||||
* ```
|
||||
* <Camera
|
||||
* onZoom={(e) => {
|
||||
* console.log('zoom', e.nativeEvent.zoom);
|
||||
* }}
|
||||
* />
|
||||
* ```
|
||||
*/
|
||||
onZoom?: (event: OnZoom) => void;
|
||||
// Barcode only
|
||||
scanBarcode?: boolean;
|
||||
showFrame?: boolean;
|
||||
|
||||
@ -21,7 +21,9 @@ const Camera = React.forwardRef((props: CameraProps, ref: any) => {
|
||||
},
|
||||
}));
|
||||
|
||||
return <NativeCamera style={{ minWidth: 100, minHeight: 100 }} ref={nativeRef} {...props} />;
|
||||
return (
|
||||
<NativeCamera maxZoom={props.maxZoom ?? 20} style={{ minWidth: 100, minHeight: 100 }} ref={nativeRef} {...props} />
|
||||
);
|
||||
});
|
||||
|
||||
Camera.defaultProps = {
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { NativeModules } from 'react-native';
|
||||
|
||||
import Camera from './Camera';
|
||||
import type { CameraApi, CameraType, CaptureData, FlashMode, FocusMode, TorchMode, ZoomMode } from './types';
|
||||
import { CameraApi, CameraType, CaptureData, FlashMode, FocusMode, TorchMode, ZoomMode } from './types';
|
||||
|
||||
const { CameraKit } = NativeModules;
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user