Created
August 31, 2015 14:18
-
-
Save AlexanderBollbach/6f8dbc2635a1e610c10d to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#import "OrbView.h" | |
#import "UIViewController+JASidePanel.h" | |
#import "JASidePanelController.h" | |
#import "OrbManager.h" | |
#import "OrbMaster.h" | |
#import <math.h> | |
#import "OrbitViewController.h" | |
#import "SettingsViewController.h" | |
#import "OrbLayerBase.h" | |
#import "OrbLayerBaseOverlay.h" | |
#import <AVFoundation/AVFoundation.h> | |
#define degreesToRadians(x) ((x) * M_PI / 180.0) | |
@class OrbitViewController; | |
@class OrbView; | |
@class JASidePanelController; | |
@class OrbMaster; | |
@class OrbManager; | |
@interface OrbView() | |
@property(nonatomic,strong) CAShapeLayer* connectLayer; | |
@property(nonatomic,weak)CAShapeLayer* orbLayerBase; | |
@property(nonatomic,weak)OrbLayerBaseOverlay* orbLayerBaseOverlay; | |
@property(nonatomic) CGMutablePathRef connectPath; | |
@property(nonatomic) UIColor *color; | |
@property(nonatomic,weak) OrbManager* orbSingleton; | |
@property(nonatomic,weak) OrbMaster* orbMasterRef; | |
@property(nonatomic,weak)OrbitViewController* orbVCRef; | |
@property(nonatomic,strong) AVAudioPlayer* player; | |
@end | |
@implementation OrbView { | |
float centerOrbX; | |
float centerOrbY; | |
float selfX; | |
float selfY; | |
int tickCounter; | |
int tickCounter2; | |
} | |
-(instancetype)initWithFrame:(CGRect)frame ofSuperView:(UIView*)superView andName:(NSString*)name ofVC:(OrbitViewController*)vc { | |
if (self = [super initWithFrame:frame]) { | |
NSString *path = [NSString stringWithFormat:@"%@/cowBell.wav", [[NSBundle mainBundle] resourcePath]]; | |
NSURL *cowBellURL = [NSURL fileURLWithPath:path]; | |
self.player = [[AVAudioPlayer alloc] initWithContentsOfURL:cowBellURL error:nil]; | |
self.player.enableRate = YES; | |
self.orbLayerBase = [OrbLayerBase layer]; | |
[self.layer addSublayer:self.orbLayerBase]; | |
self.orbLayerBaseOverlay = [OrbLayerBaseOverlay layer]; | |
[self.layer addSublayer:self.orbLayerBaseOverlay]; | |
tickCounter = 1; tickCounter2 = 1; | |
// give orb ref to superView | |
self.theSuperView = superView; | |
[superView addSubview:self]; | |
// CONFIGURE ORB IN MANAGER | |
self.orbSingleton = [OrbManager sharedManager]; | |
[self.orbSingleton.managedOrbs addObject:self]; | |
self.orbMasterRef = [OrbMaster orbMaster]; | |
self.orbVCRef = vc; | |
// look/style | |
self.color = [UIColor clearColor]; | |
self.name = name; | |
self.connectLayer = [[CAShapeLayer alloc] init]; | |
[self.theSuperView.layer addSublayer:self.connectLayer]; | |
UITapGestureRecognizer* tap2 = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapTwice)]; | |
tap2.numberOfTapsRequired = 2; | |
[self addGestureRecognizer:tap2]; | |
self.quantization = kQuantizationOff; | |
} | |
return self; | |
} | |
-(void)dealloc { | |
NSLog(@"dealloc"); | |
} | |
-(void)tickBaseWithNoteOn:(BOOL)noteOn andValue:(int)value { | |
if (noteOn) { | |
if (tickCounter2 > 4) tickCounter2 = 1; | |
if (tickCounter2 == 1) { | |
self.player.currentTime = 0; [self.player play]; | |
} else if (tickCounter2 == 2) { | |
self.player.currentTime = 0; [self.player play]; | |
} else if (tickCounter2 == 3) { | |
self.player.currentTime = 0; [self.player play]; | |
} else if (tickCounter2 == 4) { | |
self.player.currentTime = 0; [self.player play]; | |
} | |
tickCounter2++; | |
} | |
} | |
-(void)tickWithCount:(int)tickCount { | |
switch (self.quantization) { | |
case kQuantizationOff: break; | |
case kQuantizationHalf: | |
if (tickCount % 16 == 0) { | |
[self.orbLayerBaseOverlay updateDrawingWithCount:tickCounter]; | |
[self tickBaseWithNoteOn:YES andValue:tickCounter]; | |
} else { | |
[self tickBaseWithNoteOn:NO andValue:tickCounter]; | |
} break; | |
case kQuantizationQuarter: | |
if (tickCount % 4 == 0) { | |
[self.orbLayerBaseOverlay updateDrawingWithCount:tickCounter]; | |
[self tickBaseWithNoteOn:YES andValue:tickCounter]; | |
} else { | |
[self tickBaseWithNoteOn:NO andValue:tickCounter]; | |
} break; | |
case kQuantizationEighth: | |
if (tickCount % 2 == 0) { | |
[self.orbLayerBaseOverlay updateDrawingWithCount:tickCounter]; | |
[self tickBaseWithNoteOn:YES andValue:tickCounter]; | |
} else { | |
[self tickBaseWithNoteOn:NO andValue:tickCounter]; | |
} break; | |
case kQuantizationSixteenth: | |
if (tickCount % 1 == 0) { | |
[self.orbLayerBaseOverlay updateDrawingWithCount:tickCounter]; | |
[self tickBaseWithNoteOn:YES andValue:tickCounter]; | |
} else { | |
[self tickBaseWithNoteOn:NO andValue:tickCounter]; | |
} | |
break; | |
default: break; | |
} | |
} | |
-(void)tapTwice { // bring up settings menu | |
JASidePanelController* sidePanelController = self.orbVCRef.sidePanelController; | |
SettingsViewController* settings = (SettingsViewController*)sidePanelController.leftPanel; | |
settings.orb = self; | |
[sidePanelController showLeftPanelAnimated:YES]; | |
[settings updateSettings]; | |
} | |
-(void)checkDistance:(NSMutableArray*)managedOrbs { | |
selfX = [[self.layer presentationLayer]frame].origin.x + self.frame.size.width/2; | |
selfY = [[self.layer presentationLayer]frame].origin.y + self.frame.size.height/2; | |
centerOrbX = self.orbMasterRef.center.x; | |
centerOrbY = self.orbMasterRef.center.y; | |
float dx = (centerOrbX - selfX); | |
float dy = (centerOrbY - selfY); | |
float dist = sqrt(dx*dx + dy*dy); | |
double theta = atan2((selfX - centerOrbX), (selfY - centerOrbY)); | |
self.player.rate = interpolate(-3, 3, 0., 2, theta, 1); | |
self.player.volume = interpolate(0, 500, 1, 0, dist, 1); | |
[self connectWithLineWithDistance:dist]; | |
[self setNeedsDisplay]; | |
} | |
-(void)connectWithLineWithDistance:(float)dist { | |
self.connectPath = CGPathCreateMutable(); | |
CGPathMoveToPoint(self.connectPath, NULL, selfX, selfY); | |
CGPathAddLineToPoint(self.connectPath, NULL,centerOrbX,centerOrbY); | |
CGPathCloseSubpath(self.connectPath); | |
[self.connectLayer setPath:self.connectPath]; | |
float normalizedDist1 = interpolate(0, 500, 0, 1, dist, 1); | |
float normalizedDist2 = interpolate(0, 500, 0, 6, dist, 1); | |
self.connectLayer.strokeColor = [UIColor whiteColor].CGColor; | |
self.connectLayer.lineWidth = normalizedDist2; | |
self.connectLayer.opacity = normalizedDist1; | |
} | |
float interpolate(float originalMin,float originalMax,float newBegin,float newEnd,float inputValue,float curve) { | |
float OriginalRange = 0; float NewRange = 0;float zeroRefCurVal = 0; | |
float normalizedCurVal = 0;float rangedValue = 0;float invFlag = 0; float result = 0; | |
if (curve > 10) curve = 10; | |
if (curve < -10) curve = -10; | |
curve = (curve * -.1) ; curve = pow(10, curve); | |
if (inputValue < originalMin) inputValue = originalMin; | |
if (inputValue > originalMax) inputValue = originalMax; | |
OriginalRange = originalMax - originalMin; | |
if (newEnd > newBegin)NewRange = newEnd - newBegin; | |
else { | |
NewRange = newBegin - newEnd; | |
invFlag = 1; | |
} | |
zeroRefCurVal = inputValue - originalMin; normalizedCurVal = zeroRefCurVal / OriginalRange; | |
if (originalMin > originalMax ) { | |
result = 0; | |
return result; | |
} | |
if (invFlag == 0) { | |
rangedValue = (pow(normalizedCurVal, curve) * NewRange) + newBegin; | |
}else{ | |
rangedValue = newBegin - (pow(normalizedCurVal, curve) * NewRange); | |
} | |
result = rangedValue; | |
return result; | |
} | |
@end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment