Skip to content

Instantly share code, notes, and snippets.

@AlexanderBollbach
Created August 31, 2015 14:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save AlexanderBollbach/6f8dbc2635a1e610c10d to your computer and use it in GitHub Desktop.
Save AlexanderBollbach/6f8dbc2635a1e610c10d to your computer and use it in GitHub Desktop.
#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