mirror of
https://github.com/status-im/react-native-camera.git
synced 2025-02-23 17:28:08 +00:00
add onZoomChanged, onFocusChanged, set new default behavior,
This commit is contained in:
parent
be090ec70a
commit
4456ce4a80
@ -51,7 +51,10 @@ var Camera = React.createClass({
|
||||
torchMode: PropTypes.oneOfType([
|
||||
PropTypes.string,
|
||||
PropTypes.number
|
||||
])
|
||||
]),
|
||||
defaultTouchToFocus: PropTypes.bool,
|
||||
onFocusChanged: PropTypes.func,
|
||||
onZoomChanged: PropTypes.func
|
||||
},
|
||||
|
||||
mixins: [NativeMethodsMixin],
|
||||
@ -205,7 +208,10 @@ var RCTCamera = createReactNativeComponentClass({
|
||||
type: true,
|
||||
orientation: true,
|
||||
flashMode: true,
|
||||
torchMode: true
|
||||
torchMode: true,
|
||||
onFocusChanged: true,
|
||||
onZoomChanged: true,
|
||||
defaultTouchToFocus: true
|
||||
}),
|
||||
uiViewClassName: 'RCTCamera',
|
||||
});
|
||||
|
@ -7,9 +7,9 @@
|
||||
@interface RCTCamera : UIView
|
||||
|
||||
@property (nonatomic) RCTCameraManager *manager;
|
||||
@property (nonatomic) RCTBridge *bridge;
|
||||
@property (nonatomic) RCTCameraFocusSquare *camFocus;
|
||||
@property (nonatomic) BOOL multipleTouches;
|
||||
|
||||
- (id)initWithManager:(RCTCameraManager*)manager;
|
||||
- (id)initWithManager:(RCTCameraManager*)manager bridge:(RCTBridge *)bridge;
|
||||
|
||||
@end
|
||||
|
61
RCTCamera.m
61
RCTCamera.m
@ -3,11 +3,20 @@
|
||||
#import "RCTCameraManager.h"
|
||||
#import "RCTLog.h"
|
||||
#import "RCTUtils.h"
|
||||
#import "RCTEventDispatcher.h"
|
||||
|
||||
#import "UIView+React.h"
|
||||
|
||||
#import <AVFoundation/AVFoundation.h>
|
||||
#import "CameraFocusSquare.h"
|
||||
|
||||
@implementation RCTCamera
|
||||
{
|
||||
BOOL _multipleTouches;
|
||||
BOOL _onFocusChanged;
|
||||
BOOL _defaultTouchToFocus;
|
||||
BOOL _onZoomChanged;
|
||||
}
|
||||
|
||||
- (void)setAspect:(NSInteger)aspect
|
||||
{
|
||||
@ -60,16 +69,41 @@
|
||||
[self.manager changeTorchMode:torchMode];
|
||||
}
|
||||
|
||||
- (id)initWithManager:(RCTCameraManager*)manager
|
||||
- (void)setOnFocusChanged:(BOOL)enabled
|
||||
{
|
||||
if (_onFocusChanged != enabled) {
|
||||
_onFocusChanged = enabled;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setDefaultTouchToFocus:(BOOL)enabled
|
||||
{
|
||||
if (_defaultTouchToFocus != enabled) {
|
||||
_defaultTouchToFocus = enabled;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setOnZoomChanged:(BOOL)enabled
|
||||
{
|
||||
if (_onZoomChanged != enabled) {
|
||||
_onZoomChanged = enabled;
|
||||
}
|
||||
}
|
||||
|
||||
- (id)initWithManager:(RCTCameraManager*)manager bridge:(RCTBridge *)bridge
|
||||
{
|
||||
|
||||
if ((self = [super init])) {
|
||||
self.manager = manager;
|
||||
self.bridge = bridge;
|
||||
UIPinchGestureRecognizer *pinchGesture = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(handlePinchToZoomRecognizer:)];
|
||||
[self addGestureRecognizer:pinchGesture];
|
||||
[self.manager initializeCaptureSessionInput:AVMediaTypeVideo];
|
||||
[self.manager startSession];
|
||||
self.multipleTouches = NO;
|
||||
_multipleTouches = NO;
|
||||
_onFocusChanged = NO;
|
||||
_defaultTouchToFocus = YES;
|
||||
_onZoomChanged = NO;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
@ -111,17 +145,19 @@
|
||||
{
|
||||
// Update the touch state.
|
||||
if ([[event touchesForView:self] count] > 1) {
|
||||
self.multipleTouches = YES;
|
||||
_multipleTouches = YES;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
|
||||
{
|
||||
if (!_onFocusChanged) return;
|
||||
|
||||
BOOL allTouchesEnded = ([touches count] == [[event touchesForView:self] count]);
|
||||
|
||||
// Do not conflict with zooming and etc.
|
||||
if (allTouchesEnded && !self.multipleTouches) {
|
||||
if (allTouchesEnded && !_multipleTouches) {
|
||||
UITouch *touch = [[event allTouches] anyObject];
|
||||
CGPoint touchPoint = [touch locationInView:touch.view];
|
||||
// Focus camera on this point
|
||||
@ -131,7 +167,17 @@
|
||||
{
|
||||
[self.camFocus removeFromSuperview];
|
||||
}
|
||||
NSDictionary *event = @{
|
||||
@"target": self.reactTag,
|
||||
@"touchPoint": @{
|
||||
@"x": [NSNumber numberWithDouble:touchPoint.x],
|
||||
@"y": [NSNumber numberWithDouble:touchPoint.y]
|
||||
}
|
||||
};
|
||||
[self.bridge.eventDispatcher sendInputEventWithName:@"focusChanged" body:event];
|
||||
|
||||
// Show animated rectangle on the touched area
|
||||
if (_defaultTouchToFocus) {
|
||||
self.camFocus = [[RCTCameraFocusSquare alloc]initWithFrame:CGRectMake(touchPoint.x-40, touchPoint.y-40, 80, 80)];
|
||||
[self.camFocus setBackgroundColor:[UIColor clearColor]];
|
||||
[self addSubview:self.camFocus];
|
||||
@ -142,17 +188,20 @@
|
||||
[self.camFocus setAlpha:0.0];
|
||||
[UIView commitAnimations];
|
||||
}
|
||||
}
|
||||
|
||||
if (allTouchesEnded) {
|
||||
self.multipleTouches = NO;
|
||||
_multipleTouches = NO;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
-(void) handlePinchToZoomRecognizer:(UIPinchGestureRecognizer*)pinchRecognizer {
|
||||
if (!_onZoomChanged) return;
|
||||
|
||||
if (pinchRecognizer.state == UIGestureRecognizerStateChanged) {
|
||||
[self.manager zoom:pinchRecognizer.velocity];
|
||||
[self.manager zoom:pinchRecognizer.velocity reactTag:self.reactTag];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -73,7 +73,7 @@ typedef NS_ENUM(NSInteger, RCTCameraTorchMode) {
|
||||
- (void)startSession;
|
||||
- (void)stopSession;
|
||||
- (void)focusAtThePoint:(CGPoint) atPoint;
|
||||
- (void)zoom:(CGFloat)velocity;
|
||||
- (void)zoom:(CGFloat)velocity reactTag:(NSNumber *)reactTag;
|
||||
|
||||
|
||||
@end
|
||||
|
@ -16,7 +16,7 @@ RCT_EXPORT_MODULE();
|
||||
|
||||
- (UIView *)view
|
||||
{
|
||||
return [[RCTCamera alloc] initWithManager:self];
|
||||
return [[RCTCamera alloc] initWithManager:self bridge:self.bridge];
|
||||
}
|
||||
|
||||
RCT_EXPORT_VIEW_PROPERTY(aspect, NSInteger);
|
||||
@ -93,6 +93,18 @@ RCT_EXPORT_VIEW_PROPERTY(torchMode, NSInteger);
|
||||
];
|
||||
}
|
||||
|
||||
RCT_EXPORT_VIEW_PROPERTY(defaultTouchToFocus, BOOL);
|
||||
RCT_EXPORT_VIEW_PROPERTY(onFocusChanged, BOOL)
|
||||
RCT_EXPORT_VIEW_PROPERTY(onZoomChanged, BOOL)
|
||||
|
||||
- (NSDictionary *)customDirectEventTypes
|
||||
{
|
||||
return @{
|
||||
@"focusChanged": @{ @"registrationName": @"onFocusChanged" },
|
||||
@"zoomChanged": @{ @"registrationName": @"onZoomChanged" },
|
||||
};
|
||||
}
|
||||
|
||||
- (id)init {
|
||||
|
||||
if ((self = [super init])) {
|
||||
@ -688,12 +700,19 @@ didFinishRecordingToOutputFileAtURL:(NSURL *)outputFileURL
|
||||
}
|
||||
}
|
||||
|
||||
- (void) zoom:(CGFloat)velocity {
|
||||
- (void) zoom:(CGFloat)velocity reactTag:(NSNumber *)reactTag{
|
||||
const CGFloat pinchVelocityDividerFactor = 20.0f; // TODO: calibrate or make this component's property
|
||||
NSError *error = nil;
|
||||
AVCaptureDevice *device = [[self videoCaptureDeviceInput] device];
|
||||
if ([device lockForConfiguration:&error]) {
|
||||
CGFloat zoomFactor = device.videoZoomFactor + atan(velocity / pinchVelocityDividerFactor);
|
||||
NSDictionary *event = @{
|
||||
@"target": reactTag,
|
||||
@"zoomFactor": [NSNumber numberWithDouble:zoomFactor],
|
||||
@"velocity": [NSNumber numberWithDouble:velocity]
|
||||
};
|
||||
[self.bridge.eventDispatcher sendInputEventWithName:@"zoomChanged" body:event];
|
||||
|
||||
device.videoZoomFactor = zoomFactor >= 1.0f ? zoomFactor : 1.0f;
|
||||
[device unlockForConfiguration];
|
||||
} else {
|
||||
|
Loading…
x
Reference in New Issue
Block a user