ifish/Ifish/ZLRocker/ELPCircleConsoleView.m

494 lines
20 KiB
Objective-C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//
// ELPCircleConsoleView.m
// ELPCircleConsoleViewTest
//
// Created by ElsonPeng on 2018/3/2.
// Copyright © 2018年 ElsonPeng. All rights reserved.
//
#import "ELPCircleConsoleView.h"
#import "UIView+Sizes.h"
@interface ELPCircleConsoleView ()
@property (nonatomic, strong) UIImageView *consoleBGImageView;
@property (nonatomic, strong) UIButton *rotateButton; // 旋转按钮
@property (nonatomic, strong) UIView *traceView; // 旋转轨迹
@property (nonatomic, assign) ELPCircleConsoleMoveDirection direction;
@property (nonatomic, assign) ELPCircleConsoleMoveDirection preDirection;
@property (nonatomic, assign) CGPoint tempPoint;
@property (nonatomic, assign) CGFloat deltaRadius;
//图片相关
@property (nonatomic, strong) UIImage *rotateBackgroundImage_normal;
@property (nonatomic, strong) UIImage *rotateBackgroundImage_active_up;
@property (nonatomic, strong) UIImage *rotateBackgroundImage_active_down;
@property (nonatomic, strong) UIImage *rotateBackgroundImage_active_left;
@property (nonatomic, strong) UIImage *rotateBackgroundImage_active_right;
@property (nonatomic, strong) UIImage *rotateCenterButtonImage_normal;
@property (nonatomic, strong) UIImage *rotateCenterButtonImage_active;
@end
@implementation ELPCircleConsoleView{
ELPCircleConsoleMoveDirection currentDirection;
CGPoint currentPoint;
NSOperationQueue *queue;
CGFloat centerViewX;
CGFloat centerViewY;
NSInteger xAxisSpeed;
NSInteger yAxisSpeed;
NSInteger initxAxisSpeed;
NSInteger inityAxisSpeed;
CGFloat timeInterval;
//判断当前是不是正在发送stop指令
BOOL isSendOnlyStopCmd;
}
-(instancetype)init{
return [self initWithOritention:YES];
}
-(instancetype)initWithOritention:(BOOL)isProtrait {
self = [super init];
if (self) {
self.isPortrait = isProtrait;
self.consoleBGImageView = [[UIImageView alloc] init];
self.consoleBGImageView.userInteractionEnabled = YES;
[self addSubview:self.consoleBGImageView];
self.rotateButton = [[UIButton alloc] init];
self.rotateButton.adjustsImageWhenHighlighted = NO;
[self.rotateButton addTarget:self action:@selector(rotateButtonImgChange) forControlEvents:UIControlEventTouchDown];
[self addSubview:self.rotateButton];
// 运动轨迹view
self.traceView = [[UIView alloc] init];
[self addSubview:self.traceView];
self.consoleBGImageView.image = self.rotateBackgroundImage_normal;
[self.rotateButton setImage:self.rotateCenterButtonImage_normal forState:UIControlStateNormal];
[self.rotateButton setImage:_rotateCenterButtonImage_active forState:UIControlStateHighlighted];
self.rotateButton.size = self.rotateCenterButtonImage_normal.size;
// 添加拖动手势
UIPanGestureRecognizer *panPressGes = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(moveInCircle:)];
panPressGes.minimumNumberOfTouches = 0.1;
[self.rotateButton addGestureRecognizer:panPressGes];
}
return self;
}
-(void) rotateButtonImgChange {
}
- (void)layoutSubviews {
[super layoutSubviews];
_preDirection =ELPCircleConsoleMoveDirectionNone;
self.consoleBGImageView.left = 0;
self.consoleBGImageView.top = 0;
self.rotateButton.centerX = self.consoleBGImageView.centerX;
self.rotateButton.centerY = self.consoleBGImageView.centerY;
self.traceView.centerX = self.consoleBGImageView.centerX;
self.traceView.centerY = self.consoleBGImageView.centerY;
CGFloat radiusBig = ( self.consoleBGImageView.width + self.consoleBGImageView.height ) * 0.5 * 0.5;
CGFloat radiusSmall = (self.rotateButton.width + self.rotateButton.height) * 0.5 * 0.5;
self.deltaRadius = (radiusBig - radiusSmall) * (radiusBig - radiusSmall);
centerViewX = self.rotateButton.centerX;
centerViewY = self.rotateButton.centerY;
xAxisSpeed = 50;
yAxisSpeed = 20;
timeInterval = 0.3;
}
#pragma mark - 在触摸方面开发时只针对touches进行处理
#pragma mark - 触摸开始 在一次触摸事件中 只会执行一次
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
CGPoint currentP = [touch locationInView:self];
_tempPoint = currentP;
[UIView animateWithDuration:0.3 animations:^{
[self rotateLocation:currentP];
}];
}
#pragma mark - 触摸移动  在一次触摸事件中会执行多次
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
//要知道手指触摸的位置
CGPoint pLocation = [touch locationInView:self];
//对位置进行修正
[self rotateLocation:pLocation];
}
-(void)rotateLocation:(CGPoint)pLocation {
if([self IfYuntaiViewIsIntheBigView:pLocation]){
self.rotateButton.center = CGPointMake(pLocation.x, pLocation.y);
CGPoint tranPoint = CGPointMake(pLocation.x - centerViewX, pLocation.y - centerViewY);
ELPCircleConsoleMoveDirection direction = [self determineCameraDirection:tranPoint];
currentDirection = direction;
} else {
CGFloat radius = self.traceView.size.width * 0.5;
CGPoint pointc = self.consoleBGImageView.center;
CGPoint changePoint = [self CirclePoint:radius withCenterCircle:pointc withCurrentPoint:pLocation];
self.rotateButton.center = CGPointMake(changePoint.x, changePoint.y);
CGPoint tranPoint = CGPointMake(changePoint.x - centerViewX, changePoint.y - centerViewY);
ELPCircleConsoleMoveDirection direction = [self determineCameraDirection:tranPoint];
currentDirection = direction;
}
CGFloat xValue = fabs(self.rotateButton.centerX - centerViewX);
CGFloat yValue = fabs(self.rotateButton.centerY - centerViewY);
CGFloat currentRadiusValue = xValue * xValue + yValue * yValue;
CGFloat bgImgRadiusWith = self.consoleBGImageView.width * 0.5 * 0.5;
if(currentRadiusValue > bgImgRadiusWith * bgImgRadiusWith * 0.6) {
[self sendRotateButtonRotateCmd];
} else {
[self resumBackgroundImgToNormal];
}
}
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
[self.consoleBGImageView setImage:self.rotateBackgroundImage_normal];
[UIView animateWithDuration:0.1f delay:0.1f options:UIViewAnimationOptionAllowUserInteraction animations:^{
self.rotateButton.center = CGPointMake(self.consoleBGImageView.centerX, self.consoleBGImageView.centerY);
} completion:nil];
[self.rotateButton setImage:self.rotateCenterButtonImage_normal forState:UIControlStateNormal];
self.rotateButton.highlighted = NO;
_preDirection =ELPCircleConsoleMoveDirectionNone;
if (self.delegate && [self.delegate respondsToSelector:@selector(rotateCircleView:didRotateWithValueX:valueY:stop:moveDirection:)]) {
[self.delegate rotateCircleView:self didRotateWithValueX:nil valueY:nil stop:YES moveDirection:ELPCircleConsoleMoveDirectionStop];
}
isSendOnlyStopCmd = YES;
}
- (void)rotateButtonClickedCancel {
_preDirection =ELPCircleConsoleMoveDirectionNone;
if (self.delegate && [self.delegate respondsToSelector:@selector(rotateCircleView:didRotateWithValueX:valueY:stop:moveDirection:)]) {
[self.delegate rotateCircleView:self didRotateWithValueX:nil valueY:nil stop:YES moveDirection:ELPCircleConsoleMoveDirectionStop];
}
isSendOnlyStopCmd = YES;
[self.rotateButton setImage:self.rotateCenterButtonImage_normal forState:UIControlStateNormal];
[self.consoleBGImageView setImage:self.rotateBackgroundImage_normal];
self.rotateButton.centerX = self.consoleBGImageView.centerX;
self.rotateButton.centerY = self.consoleBGImageView.centerY;
}
- (void)moveInCircle:(UIPanGestureRecognizer *)gesture {
if (gesture.state == UIGestureRecognizerStateEnded) {
[self rotateButtonClickedCancel];
} else if (gesture.state == UIGestureRecognizerStateChanged) {
CGPoint translation = [gesture translationInView:self];
CGPoint locationP = [gesture locationInView:self];
ELPCircleConsoleMoveDirection direction = [self determineCameraDirection:translation];
currentPoint = translation;
currentDirection = direction;
//判断当前内部 云台 旋转 是否在大圆范围内
if([self IfYuntaiViewIsIntheBigView:locationP]) {
self.rotateButton.centerX = locationP.x;
self.rotateButton.centerY = locationP.y;
} else {
CGFloat radius = self.traceView.size.width * 0.5;
CGPoint pointc = self.consoleBGImageView.center;
CGPoint changePoint = [self CirclePoint:radius withCenterCircle:pointc withCurrentPoint:locationP];
self.rotateButton.centerX = changePoint.x;
self.rotateButton.centerY = changePoint.y;
}
CGFloat xValue = fabs(self.rotateButton.centerX - centerViewX);
CGFloat yValue = fabs(self.rotateButton.centerY - centerViewY);
CGFloat currentRadiusValue = xValue * xValue + yValue * yValue;
CGFloat bgImgRadiusWith = self.consoleBGImageView.width * 0.5 * 0.5;
if(currentRadiusValue > bgImgRadiusWith * bgImgRadiusWith * 0.6) {
[self sendRotateButtonRotateCmd];
} else {
[self resumBackgroundImgToNormal];
}
} else if (gesture.state == UIGestureRecognizerStateBegan) {
[self.rotateButton setImage:self.rotateCenterButtonImage_active forState:UIControlStateNormal];
}
}
-(void)setConsoleBackgroundImage {
if(currentDirection ==ELPCircleConsoleMoveDirectionUp) {
[self.consoleBGImageView setImage:self.rotateBackgroundImage_active_up];
} else if(currentDirection ==ELPCircleConsoleMoveDirectionDown) {
[self.consoleBGImageView setImage:self.rotateBackgroundImage_active_down];
} else if(currentDirection ==ELPCircleConsoleMoveDirectionLeft) {
[self.consoleBGImageView setImage:self.rotateBackgroundImage_active_left];
} else if(currentDirection ==ELPCircleConsoleMoveDirectionRight) {
[self.consoleBGImageView setImage:self.rotateBackgroundImage_active_right];
}
}
-(BOOL)IfYuntaiViewIsIntheBigView:(CGPoint)mPoint {
CGFloat delX = fabs(mPoint.x - centerViewX);
CGFloat delY = fabs(mPoint.y - centerViewY);
if((delX * delX + delY * delY) < self.deltaRadius) {
return YES;
}
return NO;
}
-(void)sendRotateButtonRotateCmd {
[self setConsoleBackgroundImage];
xAxisSpeed = initxAxisSpeed;
yAxisSpeed = inityAxisSpeed;
NSString *xPositive = [NSString stringWithFormat:@"%ld",(long)xAxisSpeed];
NSString *xNegative = [NSString stringWithFormat:@"%ld",-(long)xAxisSpeed];
NSString *yPositive = [NSString stringWithFormat:@"%ld",(long)yAxisSpeed];
NSString *yNegative = [NSString stringWithFormat:@"%ld",-(long)yAxisSpeed];
isSendOnlyStopCmd = NO;
if(currentDirection ==ELPCircleConsoleMoveDirectionRight) {
//直接向右转动
if(_preDirection == currentDirection || _preDirection ==ELPCircleConsoleMoveDirectionNone) {
if (self.delegate != nil && [self.delegate respondsToSelector:@selector(rotateCircleView:didRotateWithValueX:valueY:stop:moveDirection:)]) {
[self.delegate rotateCircleView:self didRotateWithValueX:xPositive valueY:@"0" stop:NO moveDirection:ELPCircleConsoleMoveDirectionRight];
}
}
//前一个方向停止,向右转动
else {
if (self.delegate != nil && [self.delegate respondsToSelector:@selector(rotateCircleView:didRotateWithValueX:valueY:stop:moveDirection:)]) {
[self.delegate rotateCircleView:self didRotateWithValueX:xPositive valueY:@"0" stop:YES moveDirection:ELPCircleConsoleMoveDirectionRightStop];
}
}
} else if(currentDirection ==ELPCircleConsoleMoveDirectionUp) {
if(_preDirection == currentDirection || _preDirection ==ELPCircleConsoleMoveDirectionNone) {
if (self.delegate && [self.delegate respondsToSelector:@selector(rotateCircleView:didRotateWithValueX:valueY:stop:moveDirection:)]) {
[self.delegate rotateCircleView:self didRotateWithValueX:@"0" valueY:yPositive stop:NO moveDirection:ELPCircleConsoleMoveDirectionUp];
}
} else {
if (self.delegate && [self.delegate respondsToSelector:@selector(rotateCircleView:didRotateWithValueX:valueY:stop:moveDirection:)]) {
[self.delegate rotateCircleView:self didRotateWithValueX:@"0" valueY:yPositive stop:YES moveDirection:ELPCircleConsoleMoveDirectionUpStop];
}
}
} else if(currentDirection ==ELPCircleConsoleMoveDirectionLeft) {
if(_preDirection == currentDirection || _preDirection ==ELPCircleConsoleMoveDirectionNone) {
if (self.delegate && [self.delegate respondsToSelector:@selector(rotateCircleView:didRotateWithValueX:valueY:stop:moveDirection:)]) {
[self.delegate rotateCircleView:self didRotateWithValueX:xNegative valueY:@"0" stop:NO moveDirection:ELPCircleConsoleMoveDirectionLeft];
}
} else {
if (self.delegate && [self.delegate respondsToSelector:@selector(rotateCircleView:didRotateWithValueX:valueY:stop:moveDirection:)]) {
[self.delegate rotateCircleView:self didRotateWithValueX:xNegative valueY:@"0" stop:YES moveDirection:ELPCircleConsoleMoveDirectionLeftStop];
}
}
} else if(currentDirection ==ELPCircleConsoleMoveDirectionDown) {
if(_preDirection == currentDirection || _preDirection ==ELPCircleConsoleMoveDirectionNone) {
if (self.delegate && [self.delegate respondsToSelector:@selector(rotateCircleView:didRotateWithValueX:valueY:stop:moveDirection:)]) {
[self.delegate rotateCircleView:self didRotateWithValueX:@"0" valueY:yNegative stop:NO moveDirection:ELPCircleConsoleMoveDirectionDown];
}
} else {
if (self.delegate && [self.delegate respondsToSelector:@selector(rotateCircleView:didRotateWithValueX:valueY:stop:moveDirection:)]) {
[self.delegate rotateCircleView:self didRotateWithValueX:@"0" valueY:yNegative stop:YES moveDirection:ELPCircleConsoleMoveDirectionDownStop];
}
}
}
_preDirection = currentDirection;
}
-(void)resumBackgroundImgToNormal {
[self.consoleBGImageView setImage:self.rotateBackgroundImage_normal];
}
// 获取 当前拖动的点于圆心构成的直线 和运动轨迹圆的相交点
- (CGPoint)CirclePoint:(CGFloat)radius withCenterCircle:(CGPoint)centerCircle withCurrentPoint:(CGPoint)curPoint {
CGPoint cPoint;
CGFloat x = curPoint.x;
CGFloat y = curPoint.y;
//圆的X坐标轨迹
CGFloat cX ;
//圆的Y坐标轨迹
CGFloat cY ;
// 圆心到转动按钮的距离的平方
CGFloat daX;
// 圆心到转动按钮的距离
CGFloat aX;
// 圆心水平方向与转动按钮形成的夹角的cos值
CGFloat cosX;
// 圆心与触控点的距离的平方(勾股定理)
daX = (x - centerCircle.x)*(x - centerCircle.x) + (y - centerCircle.y)*(y - centerCircle.y);
aX = sqrt(daX); //开根号 //圆心与触控点的距离
cosX = fabs(x - centerCircle.x)/aX; //绝对值
cX = cosX * radius; // x =R * cosX; 圆心到触控点在水平坐标的X的值
cY = sqrt(radius * radius - cX * cX);
if(x < centerCircle.x){ //如果X所在的点小于圆心 在圆心的左边
cX = centerCircle.x - cX;
}else{
cX = centerCircle.x + cX;
}
if(y < centerCircle.y){
cY = centerCircle.y - cY;
}else{
cY = centerCircle.y + cY;
}
cPoint.x = cX;
cPoint.y = cY;
return cPoint;
}
// 根据拖动时候的偏移确定摄像头的移动方向
- (ELPCircleConsoleMoveDirection)determineCameraDirection:(CGPoint)translation {
if (translation.y == 0.0 || fabs(translation.x / translation.y) >= 1.0){
if (translation.x > 0.0 ){
_direction =ELPCircleConsoleMoveDirectionRight;
}else{
_direction =ELPCircleConsoleMoveDirectionLeft;
}
} else if (translation.x == 0.0 || fabs(translation.y / translation.x) >= 1.0){
if (translation.y > 0.0 ){
_direction =ELPCircleConsoleMoveDirectionDown;
}else{
_direction =ELPCircleConsoleMoveDirectionUp;
}
}
return _direction;
}
-(void)dealloc{
NSLog(@"ELPCircleConsole dealloc");
}
-(UIImage *)imageByInchesWithName:(NSString *)imageName{
if (!imageName) {
return [UIImage new];
}
return [UIImage imageNamed:[NSString stringWithFormat:@"%@",imageName]];
}
#pragma mark - setter & getter
-(void)setFrame:(CGRect)frame{
[super setFrame:frame];
self.consoleBGImageView.frame = self.bounds;
self.consoleBGImageView.size = self.size;
self.rotateButton.size = self.rotateCenterButtonImage_normal.size;
self.traceView.size = (CGSize){self.consoleBGImageView.width - self.rotateButton.width-10,self.consoleBGImageView.height - self.rotateButton.height-10};
}
-(void)setIsPortrait:(BOOL)isPortrait{
_isPortrait = isPortrait;
if (self.consoleBGImageView) {
self.consoleBGImageView.image = self.rotateBackgroundImage_normal;
}
if (self.rotateButton) {
[self.rotateButton setImage:self.rotateCenterButtonImage_normal forState:UIControlStateNormal];
[self.rotateButton setImage:_rotateCenterButtonImage_active forState:UIControlStateHighlighted];
self.rotateButton.size = self.rotateCenterButtonImage_normal.size;
}
if (self.traceView) {
self.traceView.size = (CGSize){self.consoleBGImageView.width - self.rotateButton.width,self.consoleBGImageView.height - self.rotateButton.height};
}
}
//中间操作台控制背景图片
-(UIImage *)rotateBackgroundImage_normal {
if (!_rotateBackgroundImage_normal) {
return [self imageByInchesWithName:self.isPortrait?@"equipment_iocn_joystick.png":@"equipment_iocn_joystick.png"];
}
return _rotateBackgroundImage_normal;
}
-(UIImage *)rotateBackgroundImage_active_up {
if (!_rotateBackgroundImage_active_up) {
return [self imageByInchesWithName:self.isPortrait?@"equipment_iocn_joystick":@"equipment_iocn_joystick"];
}
return _rotateBackgroundImage_active_up;
}
-(UIImage *)rotateBackgroundImage_active_down {
if (!_rotateBackgroundImage_active_down) {
return [self imageByInchesWithName:self.isPortrait?@"equipment_iocn_joystick":@"equipment_iocn_joystick"];
}
return _rotateBackgroundImage_active_down;
}
-(UIImage *)rotateBackgroundImage_active_left {
if (!_rotateBackgroundImage_active_left) {
return [self imageByInchesWithName:self.isPortrait?@"equipment_iocn_joystick":@"equipment_iocn_joystick"];
}
return _rotateBackgroundImage_active_left;
}
-(UIImage *)rotateBackgroundImage_active_right {
if (!_rotateBackgroundImage_active_right) {
return [self imageByInchesWithName:self.isPortrait?@"equipment_iocn_joystick":@"equipment_iocn_joystick"];
}
return _rotateBackgroundImage_active_right;
}
-(UIImage *)rotateCenterButtonImage_normal {
if (!_rotateCenterButtonImage_normal) {
return [self imageByInchesWithName:self.isPortrait?@"roundBall":@"roundBall"];
}
return _rotateCenterButtonImage_normal;
}
-(UIImage *)rotateCenterButtonImage_active {
if (!_rotateCenterButtonImage_active) {
return [self imageByInchesWithName:self.isPortrait?@"roundBall":@"roundBall"];
}
return _rotateCenterButtonImage_active;
}
+(UIImage *)colorizeImage:(UIImage *)baseImage withColor:(UIColor *)theColor {
if (theColor == nil) {
theColor = [UIColor whiteColor];
}
CGRect rect = CGRectMake(0, 0, baseImage.size.width* baseImage.scale, baseImage.size.height* baseImage.scale);
UIGraphicsBeginImageContext(rect.size);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextClipToMask(context, rect, baseImage.CGImage);
CGContextSetFillColorWithColor(context, [theColor CGColor]);
CGContextFillRect(context, rect);
UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImage *flippedImage = [UIImage imageWithCGImage:img.CGImage scale:baseImage.scale orientation: UIImageOrientationDownMirrored];
return flippedImage;
}
@end