From 71df1329d4113f7a788862d905db7870782d5b80 Mon Sep 17 00:00:00 2001 From: Frank Tsai Date: Sun, 8 Jan 2017 13:45:35 +0800 Subject: [PATCH 1/8] cherry-pick d9da66b6b0d2fe062e488df62a15927285363d86 inputEvent -> appEvent --- index.js | 14 +++++++++++--- ios/RCTCamera.m | 2 +- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/index.js b/index.js index f1957e9..1e0a12c 100644 --- a/index.js +++ b/index.js @@ -154,7 +154,7 @@ export default class Camera extends Component { async componentWillMount() { this._addOnBarCodeReadListener() - + this._addOnFocusChanged() let { captureMode } = convertNativeProps({ captureMode: this.props.captureMode }) let hasVideoAndAudio = this.props.captureAudio && captureMode === Camera.constants.CaptureMode.video let check = hasVideoAndAudio ? Camera.checkDeviceAuthorizationStatus : Camera.checkVideoAuthorizationStatus; @@ -167,17 +167,25 @@ export default class Camera extends Component { componentWillUnmount() { this._removeOnBarCodeReadListener() - + this._removeOnFocusChanged() if (this.state.isRecording) { this.stopCapture(); } } componentWillReceiveProps(newProps) { - const { onBarCodeRead } = this.props + const { onBarCodeRead, onFocusChanged } = this.props if (onBarCodeRead !== newProps.onBarCodeRead) { this._addOnBarCodeReadListener(newProps) } + if (onFocusChanged !== !newProps.onFocusChanged) { + this._addOnFocusChanged(newProps) + } + } + + _addOnFocusChanged(props) { + const { onFocusChanged } = props || this.props; + this.focusListener = NativeAppEventEmitter.addListener('focusChanged', onFocusChanged) } _addOnBarCodeReadListener(props) { diff --git a/ios/RCTCamera.m b/ios/RCTCamera.m index 0625b4a..f8f1420 100644 --- a/ios/RCTCamera.m +++ b/ios/RCTCamera.m @@ -148,7 +148,7 @@ @"y": [NSNumber numberWithDouble:touchPoint.y] } }; - [self.bridge.eventDispatcher sendInputEventWithName:@"focusChanged" body:event]; + [self.bridge.eventDispatcher sendAppEventWithName:@"focusChanged" body:event]; // Show animated rectangle on the touched area if (_defaultOnFocusComponent) { From 4d2ee4bdfa6bc96547c64c402d2769f74b4dfcb4 Mon Sep 17 00:00:00 2001 From: Martin Puza Date: Mon, 16 Oct 2017 13:44:08 +0200 Subject: [PATCH 2/8] _addOnZoomChanged added remove methods added --- index.js | 32 +++++++++++++++++++++++++++----- ios/RCTCameraManager.m | 2 +- 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/index.js b/index.js index 1e0a12c..b800d02 100644 --- a/index.js +++ b/index.js @@ -155,6 +155,7 @@ export default class Camera extends Component { async componentWillMount() { this._addOnBarCodeReadListener() this._addOnFocusChanged() + this._addOnZoomChanged() let { captureMode } = convertNativeProps({ captureMode: this.props.captureMode }) let hasVideoAndAudio = this.props.captureAudio && captureMode === Camera.constants.CaptureMode.video let check = hasVideoAndAudio ? Camera.checkDeviceAuthorizationStatus : Camera.checkVideoAuthorizationStatus; @@ -168,6 +169,7 @@ export default class Camera extends Component { componentWillUnmount() { this._removeOnBarCodeReadListener() this._removeOnFocusChanged() + this._removeOnZoomChanged() if (this.state.isRecording) { this.stopCapture(); } @@ -183,11 +185,6 @@ export default class Camera extends Component { } } - _addOnFocusChanged(props) { - const { onFocusChanged } = props || this.props; - this.focusListener = NativeAppEventEmitter.addListener('focusChanged', onFocusChanged) - } - _addOnBarCodeReadListener(props) { const { onBarCodeRead } = props || this.props this._removeOnBarCodeReadListener() @@ -198,12 +195,37 @@ export default class Camera extends Component { }) } } + _addOnFocusChanged(props) { + if (Platform.OS === 'ios') { + const { onFocusChanged } = props || this.props; + this.focusListener = NativeAppEventEmitter.addListener('focusChanged', onFocusChanged) + } + } + + _addOnZoomChanged(props) { + if (Platform.OS === 'ios') { + const { onZoomChanged } = props || this.props; + this.zoomListener = NativeAppEventEmitter.addListener('zoomChanged', onFocusChanged) + } + } _removeOnBarCodeReadListener() { const listener = this.cameraBarCodeReadListener if (listener) { listener.remove() } } + _removeOnFocusChanged() { + const listener = this.focusListener + if (listener) { + listener.remove() + } + } + _removeOnZoomChanged() { + const listener = this.zoomListener + if (listener) { + listener.remove() + } + } render() { const style = [styles.base, this.props.style]; diff --git a/ios/RCTCameraManager.m b/ios/RCTCameraManager.m index 2310080..4a3ff53 100644 --- a/ios/RCTCameraManager.m +++ b/ios/RCTCameraManager.m @@ -1008,7 +1008,7 @@ didFinishRecordingToOutputFileAtURL:(NSURL *)outputFileURL @"velocity": [NSNumber numberWithDouble:velocity] }; - [self.bridge.eventDispatcher sendInputEventWithName:@"zoomChanged" body:event]; + [self.bridge.eventDispatcher sendAppEventWithName:@"zoomChanged" body:event]; device.videoZoomFactor = zoomFactor; [device unlockForConfiguration]; From a38576660be3bd986d7d374cf10125646948eb28 Mon Sep 17 00:00:00 2001 From: Martin Puza Date: Mon, 16 Oct 2017 14:11:44 +0200 Subject: [PATCH 3/8] added onZoomChanged to wrp --- index.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/index.js b/index.js index b800d02..6032c30 100644 --- a/index.js +++ b/index.js @@ -176,13 +176,16 @@ export default class Camera extends Component { } componentWillReceiveProps(newProps) { - const { onBarCodeRead, onFocusChanged } = this.props + const { onBarCodeRead, onFocusChanged, onZoomChanged } = this.props if (onBarCodeRead !== newProps.onBarCodeRead) { this._addOnBarCodeReadListener(newProps) } if (onFocusChanged !== !newProps.onFocusChanged) { this._addOnFocusChanged(newProps) } + if (onZoomChanged !== !newProps.onZoomChanged) { + this._addOnZoomChanged(newProps) + } } _addOnBarCodeReadListener(props) { From defe4170c77ede4af917243d1662eebe5ea2c913 Mon Sep 17 00:00:00 2001 From: Martin Puza Date: Mon, 16 Oct 2017 14:24:01 +0200 Subject: [PATCH 4/8] enable change monitoring --- ios/RCTCameraManager.m | 1 + 1 file changed, 1 insertion(+) diff --git a/ios/RCTCameraManager.m b/ios/RCTCameraManager.m index 4a3ff53..232cfd7 100644 --- a/ios/RCTCameraManager.m +++ b/ios/RCTCameraManager.m @@ -980,6 +980,7 @@ didFinishRecordingToOutputFileAtURL:(NSURL *)outputFileURL [device setExposureMode:AVCaptureExposureModeAutoExpose]; [device setExposurePointOfInterest:cameraViewPoint]; } + [device setSubjectAreaChangeMonitoringEnabled:true] [device unlockForConfiguration]; } } From a811d697165e49a4e625d1d7091b00d7a00e695e Mon Sep 17 00:00:00 2001 From: Martin Puza Date: Mon, 16 Oct 2017 14:26:26 +0200 Subject: [PATCH 5/8] fixed c/p error --- index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.js b/index.js index 6032c30..baefe16 100644 --- a/index.js +++ b/index.js @@ -208,7 +208,7 @@ export default class Camera extends Component { _addOnZoomChanged(props) { if (Platform.OS === 'ios') { const { onZoomChanged } = props || this.props; - this.zoomListener = NativeAppEventEmitter.addListener('zoomChanged', onFocusChanged) + this.zoomListener = NativeAppEventEmitter.addListener('zoomChanged', onZoomChanged) } } _removeOnBarCodeReadListener() { From 1c616f8aaac2df5335195bdec215fedfb727efdd Mon Sep 17 00:00:00 2001 From: Martin Puza Date: Mon, 16 Oct 2017 14:29:20 +0200 Subject: [PATCH 6/8] important, indeed; --- ios/RCTCameraManager.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ios/RCTCameraManager.m b/ios/RCTCameraManager.m index 232cfd7..807faf0 100644 --- a/ios/RCTCameraManager.m +++ b/ios/RCTCameraManager.m @@ -980,7 +980,7 @@ didFinishRecordingToOutputFileAtURL:(NSURL *)outputFileURL [device setExposureMode:AVCaptureExposureModeAutoExpose]; [device setExposurePointOfInterest:cameraViewPoint]; } - [device setSubjectAreaChangeMonitoringEnabled:true] + [device setSubjectAreaChangeMonitoringEnabled:true]; [device unlockForConfiguration]; } } From e372f349cb73ea58a7416098acbb1a0dffc96c6a Mon Sep 17 00:00:00 2001 From: Martin Puza Date: Mon, 16 Oct 2017 15:15:40 +0200 Subject: [PATCH 7/8] we'll also need the observer --- ios/RCTCameraManager.m | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/ios/RCTCameraManager.m b/ios/RCTCameraManager.m index 807faf0..e76bfbf 100644 --- a/ios/RCTCameraManager.m +++ b/ios/RCTCameraManager.m @@ -218,7 +218,6 @@ RCT_CUSTOM_VIEW_PROPERTY(type, NSInteger, RCTCamera) { [self.session addInput:captureDeviceInput]; [NSNotificationCenter.defaultCenter removeObserver:self name:AVCaptureDeviceSubjectAreaDidChangeNotification object:currentCaptureDevice]; - [NSNotificationCenter.defaultCenter addObserver:self selector:@selector(subjectAreaDidChange:) name:AVCaptureDeviceSubjectAreaDidChangeNotification object:captureDevice]; self.videoCaptureDeviceInput = captureDeviceInput; [self setFlashMode]; @@ -496,6 +495,8 @@ RCT_EXPORT_METHOD(hasFlash:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRej [self.session beginConfiguration]; NSError *error = nil; + + AVCaptureDevice *currentCaptureDevice = [self.videoCaptureDeviceInput device]; AVCaptureDevice *captureDevice; if (type == AVMediaTypeAudio) { @@ -527,6 +528,9 @@ RCT_EXPORT_METHOD(hasFlash:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRej self.audioCaptureDeviceInput = captureDeviceInput; } else if (type == AVMediaTypeVideo) { + [NSNotificationCenter.defaultCenter removeObserver:self name:AVCaptureDeviceSubjectAreaDidChangeNotification object:currentCaptureDevice]; + [NSNotificationCenter.defaultCenter addObserver:self selector:@selector(subjectAreaDidChange:) name:AVCaptureDeviceSubjectAreaDidChangeNotification object:captureDevice]; + self.videoCaptureDeviceInput = captureDeviceInput; [self setFlashMode]; } From 5faf21a6f819aba2f83f230c85872f2e60e56c43 Mon Sep 17 00:00:00 2001 From: Martin Puza Date: Mon, 16 Oct 2017 17:06:26 +0200 Subject: [PATCH 8/8] improved focus square and defocus visualization --- ios/CameraFocusSquare.m | 28 ++++++++++++++++++++++++---- ios/RCTCamera.h | 1 + ios/RCTCamera.m | 1 - ios/RCTCameraManager.m | 14 ++++++++++++++ 4 files changed, 39 insertions(+), 5 deletions(-) diff --git a/ios/CameraFocusSquare.m b/ios/CameraFocusSquare.m index b7d2073..3166f3c 100644 --- a/ios/CameraFocusSquare.m +++ b/ios/CameraFocusSquare.m @@ -11,13 +11,33 @@ const float squareLength = 80.0f; // Initialization code [self setBackgroundColor:[UIColor clearColor]]; - [self.layer setBorderWidth:2.0]; - [self.layer setCornerRadius:4.0]; + [self.layer setBorderWidth:1.0]; [self.layer setBorderColor:[UIColor whiteColor].CGColor]; + + CGSize size = frame.size; + CGRect rect = CGRectMake(0, 0, size.width, size.height); + + UIBezierPath *endPath = [UIBezierPath bezierPath]; + [endPath moveToPoint:CGPointMake(CGRectGetMinX(rect) + size.width / 2.0, CGRectGetMinY(rect))]; + [endPath addLineToPoint:CGPointMake(CGRectGetMinX(rect) + size.width / 2.0, CGRectGetMinY(rect) + 5.0)]; + [endPath moveToPoint:CGPointMake(CGRectGetMaxX(rect), CGRectGetMinY(rect) + size.height / 2.0)]; + [endPath addLineToPoint:CGPointMake(CGRectGetMaxX(rect) - 5.0, CGRectGetMinY(rect) + size.height / 2.0)]; + + [endPath moveToPoint:CGPointMake(CGRectGetMinX(rect) + size.width / 2.0, CGRectGetMaxY(rect))]; + [endPath addLineToPoint:CGPointMake(CGRectGetMinX(rect) + size.width / 2.0, CGRectGetMaxY(rect) - 5.0)]; + [endPath moveToPoint:CGPointMake(CGRectGetMinX(rect), CGRectGetMinY(rect) + size.height / 2.0)]; + [endPath addLineToPoint:CGPointMake(CGRectGetMinX(rect) + 5.0, CGRectGetMinY(rect) + size.height / 2.0)]; + CAShapeLayer *extraLayer = [CAShapeLayer layer]; + extraLayer.path = endPath.CGPath; + extraLayer.fillColor = [UIColor clearColor].CGColor; + extraLayer.strokeColor = [UIColor colorWithRed:1.0 green:0.83 blue:0 alpha:0.95].CGColor; + extraLayer.lineWidth = 1.0; + [self.layer addSublayer:extraLayer]; + CABasicAnimation* selectionAnimation = [CABasicAnimation animationWithKeyPath:@"borderColor"]; - selectionAnimation.toValue = (id)[UIColor blueColor].CGColor; + selectionAnimation.toValue = (id)[UIColor colorWithRed:1.0 green:0.83 blue:0 alpha:0.95].CGColor; selectionAnimation.repeatCount = 8; [self.layer addAnimation:selectionAnimation forKey:@"selectionAnimation"]; @@ -25,4 +45,4 @@ const float squareLength = 80.0f; } return self; } -@end \ No newline at end of file +@end diff --git a/ios/RCTCamera.h b/ios/RCTCamera.h index 3986880..acdf792 100644 --- a/ios/RCTCamera.h +++ b/ios/RCTCamera.h @@ -8,4 +8,5 @@ - (id)initWithManager:(RCTCameraManager*)manager bridge:(RCTBridge *)bridge; +@property (nonatomic, strong) RCTCameraFocusSquare *camFocus; @end diff --git a/ios/RCTCamera.m b/ios/RCTCamera.m index f8f1420..a63a620 100644 --- a/ios/RCTCamera.m +++ b/ios/RCTCamera.m @@ -14,7 +14,6 @@ @property (nonatomic, weak) RCTCameraManager *manager; @property (nonatomic, weak) RCTBridge *bridge; -@property (nonatomic, strong) RCTCameraFocusSquare *camFocus; @end diff --git a/ios/RCTCameraManager.m b/ios/RCTCameraManager.m index e76bfbf..ebde256 100644 --- a/ios/RCTCameraManager.m +++ b/ios/RCTCameraManager.m @@ -934,6 +934,20 @@ didFinishRecordingToOutputFileAtURL:(NSURL *)outputFileURL { CGPoint devicePoint = CGPointMake(.5, .5); [self focusWithMode:AVCaptureFocusModeContinuousAutoFocus exposeWithMode:AVCaptureExposureModeContinuousAutoExposure atDevicePoint:devicePoint monitorSubjectAreaChange:NO]; + + if (self.camera.camFocus) + { + [self.camera.camFocus removeFromSuperview]; + } + self.camera.camFocus = [[RCTCameraFocusSquare alloc]initWithFrame:CGRectMake([self.view center].x-80, [self.view center].y-80, 160, 160)]; + [self.camera.camFocus setBackgroundColor:[UIColor clearColor]]; + [self.view addSubview:self.camera.camFocus]; + [self.camera.camFocus setNeedsDisplay]; + + [UIView beginAnimations:nil context:NULL]; + [UIView setAnimationDuration:1.0]; + [self.camera.camFocus setAlpha:0.0]; + [UIView commitAnimations]; } - (void)focusWithMode:(AVCaptureFocusMode)focusMode exposeWithMode:(AVCaptureExposureMode)exposureMode atDevicePoint:(CGPoint)point monitorSubjectAreaChange:(BOOL)monitorSubjectAreaChange