diff --git a/ios/RCT/CameraFocusSquare.m b/ios/RCT/CameraFocusSquare.m index b7d2073..3166f3c 100644 --- a/ios/RCT/CameraFocusSquare.m +++ b/ios/RCT/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/RCT/RCTCamera.h b/ios/RCT/RCTCamera.h index 3986880..acdf792 100644 --- a/ios/RCT/RCTCamera.h +++ b/ios/RCT/RCTCamera.h @@ -8,4 +8,5 @@ - (id)initWithManager:(RCTCameraManager*)manager bridge:(RCTBridge *)bridge; +@property (nonatomic, strong) RCTCameraFocusSquare *camFocus; @end diff --git a/ios/RCT/RCTCamera.m b/ios/RCT/RCTCamera.m index 6b84ec1..c55b1fe 100644 --- a/ios/RCT/RCTCamera.m +++ b/ios/RCT/RCTCamera.m @@ -14,7 +14,6 @@ @property (nonatomic, weak) RCTCameraManager *manager; @property (nonatomic, weak) RCTBridge *bridge; -@property (nonatomic, strong) RCTCameraFocusSquare *camFocus; @end @@ -148,7 +147,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) { diff --git a/ios/RCT/RCTCameraManager.m b/ios/RCT/RCTCameraManager.m index 3991b36..dda5b10 100644 --- a/ios/RCT/RCTCameraManager.m +++ b/ios/RCT/RCTCameraManager.m @@ -228,7 +228,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]; @@ -546,6 +545,8 @@ RCT_EXPORT_METHOD(setZoom:(CGFloat)zoomFactor) { [self.session beginConfiguration]; NSError *error = nil; + + AVCaptureDevice *currentCaptureDevice = [self.videoCaptureDeviceInput device]; AVCaptureDevice *captureDevice; if (type == AVMediaTypeAudio) { @@ -577,6 +578,9 @@ RCT_EXPORT_METHOD(setZoom:(CGFloat)zoomFactor) { 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]; } @@ -1014,6 +1018,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 @@ -1064,6 +1082,7 @@ didFinishRecordingToOutputFileAtURL:(NSURL *)outputFileURL [device setExposureMode:AVCaptureExposureModeAutoExpose]; [device setExposurePointOfInterest:cameraViewPoint]; } + [device setSubjectAreaChangeMonitoringEnabled:true]; [device unlockForConfiguration]; } } @@ -1092,7 +1111,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]; diff --git a/src/Camera.js b/src/Camera.js index ffe3003..c261715 100644 --- a/src/Camera.js +++ b/src/Camera.js @@ -187,6 +187,8 @@ export default class Camera extends Component { async componentWillMount() { this._addOnBarCodeReadListener(); + this._addOnFocusChanged(); + this._addOnZoomChanged(); let { captureMode } = convertNativeProps({ captureMode: this.props.captureMode }); let hasVideoAndAudio = @@ -198,17 +200,24 @@ export default class Camera extends Component { componentWillUnmount() { this._removeOnBarCodeReadListener(); - + this._removeOnFocusChanged(); + this._removeOnZoomChanged(); if (this.state.isRecording) { this.stopCapture(); } } componentWillReceiveProps(newProps) { - const { onBarCodeRead } = 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) { @@ -221,12 +230,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', onZoomChanged) + } + } _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() + } + } _setReference = ref => { if (ref) {