Created
April 30, 2010 16:19
-
-
Save CastIrony/385419 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 "Common.h" | |
@interface AnimatedFloat : NSObject | |
{ | |
float _startValue; | |
NSTimeInterval _startTime; | |
BOOL _hasStarted; | |
float _endValue; | |
NSTimeInterval _endTime; | |
BOOL _hasEnded; | |
AnimationCurve _curve; | |
} | |
@property (nonatomic, assign) float startValue; | |
@property (nonatomic, assign) NSTimeInterval startTime; | |
@property (nonatomic, readonly) BOOL hasStarted; | |
@property (nonatomic, assign) float endValue; | |
@property (nonatomic, assign) NSTimeInterval endTime; | |
@property (nonatomic, readonly) BOOL hasEnded; | |
@property (nonatomic, assign) AnimationCurve curve; | |
@property (nonatomic, assign) float value; | |
+(id)withValue:(float)value; | |
+(id)withStartValue:(float)startValue endValue:(float)endValue speed:(float)speed; | |
+(id)withStartValue:(float)startValue endValue:(float)endValue forTime:(NSTimeInterval)time; | |
-(NSString*)description; | |
@end |
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 "AnimatedFloat.h" | |
@interface AnimatedFloat () | |
@property (nonatomic, assign) BOOL hasStarted; | |
@property (nonatomic, assign) BOOL hasEnded; | |
@end | |
@implementation AnimatedFloat | |
@synthesize startValue = _startValue; | |
@synthesize startTime = _startTime; | |
@synthesize hasStarted = _hasStarted; | |
@synthesize endValue = _endValue; | |
@synthesize endTime = _endTime; | |
@synthesize hasEnded = _hasEnded; | |
@synthesize curve = _curve; | |
@dynamic value; | |
-(id)initWithStartValue:(float)startValue endValue:(float)endValue startTime:(NSTimeInterval)startTime endTime:(NSTimeInterval)endTime | |
{ | |
self = [super init]; | |
if(self) | |
{ | |
_startValue = startValue; | |
_startTime = startTime; | |
_endValue = endValue; | |
_endTime = startTime + TIMESCALE * (endTime - startTime); | |
_hasStarted = NO; | |
_hasEnded = NO; | |
_curve = AnimationLinear; | |
} | |
return self; | |
} | |
+(id)withValue:(float)value | |
{ | |
NSTimeInterval now = CFAbsoluteTimeGetCurrent(); | |
return [[[AnimatedFloat alloc] initWithStartValue:value endValue:value startTime:now endTime:now] autorelease]; | |
} | |
+(id)withStartValue:(float)startValue endValue:(float)endValue speed:(float)speed | |
{ | |
NSTimeInterval now = CFAbsoluteTimeGetCurrent(); | |
if(speed == 0) | |
{ | |
return [[[AnimatedFloat alloc] initWithStartValue:startValue endValue:endValue startTime:now endTime:now] autorelease]; | |
} | |
else | |
{ | |
return [[[AnimatedFloat alloc] initWithStartValue:startValue endValue:endValue startTime:now endTime:now + absf(endValue, startValue) / speed] autorelease]; | |
} | |
} | |
+(id)withStartValue:(float)startValue endValue:(float)endValue forTime:(NSTimeInterval)timeInterval | |
{ | |
NSTimeInterval now = CFAbsoluteTimeGetCurrent(); | |
return [[[AnimatedFloat alloc] initWithStartValue:startValue endValue:endValue startTime:now endTime:now + timeInterval] autorelease]; | |
} | |
-(NSString*)description | |
{ | |
return [NSString stringWithFormat:@"[%f5] -> [%f5]", _startValue, _endValue]; | |
} | |
-(float)value | |
{ | |
NSTimeInterval now = CFAbsoluteTimeGetCurrent(); | |
if(now > self.startTime && !self.hasStarted) | |
{ | |
// You can perform some post-start action here | |
self.hasStarted = YES; | |
} | |
if(now > self.endTime && !self.hasEnded) | |
{ | |
// You can perform some post-end action here | |
self.hasEnded = YES; | |
} | |
if(now < self.startTime) { return self.startValue; } | |
if(now > self.endTime) { return self.endValue; } | |
float delta = (now - self.startTime) / (self.endTime - self.startTime); | |
float proportion = delta; | |
if(self.curve == AnimationEaseIn) { proportion = (3 * delta - delta * delta * delta) / 2; } | |
if(self.curve == AnimationEaseOut) { proportion = (3 * delta * delta - delta * delta * delta) / 2; } | |
if(self.curve == AnimationEaseInOut) { proportion = (3 * delta * delta - 2 * delta * delta * delta); } | |
return (1.0 - proportion) * self.startValue + (proportion) * self.endValue; | |
} | |
-(void)setValue:(float)value | |
{ | |
NSTimeInterval now = CFAbsoluteTimeGetCurrent(); | |
self.startTime = now; | |
self.endTime = now; | |
self.startValue = value; | |
self.endValue = value; | |
self.hasStarted = YES; | |
self.hasEnded = YES; | |
} | |
@end |
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 "Common.h" | |
@interface AnimatedVector3D : NSObject | |
{ | |
Vector3D _startValue; | |
NSTimeInterval _startTime; | |
BOOL _hasStarted; | |
Vector3D _endValue; | |
NSTimeInterval _endTime; | |
BOOL _hasEnded; | |
AnimationCurve _curve; | |
} | |
@property (nonatomic, assign) Vector3D startValue; | |
@property (nonatomic, assign) NSTimeInterval startTime; | |
@property (nonatomic, readonly) BOOL hasStarted; | |
@property (nonatomic, assign) Vector3D endValue; | |
@property (nonatomic, assign) NSTimeInterval endTime; | |
@property (nonatomic, readonly) BOOL hasEnded; | |
@property (nonatomic, assign) AnimationCurve curve; | |
@property (nonatomic, assign) Vector3D value; | |
+(id)withValue:(Vector3D)value; | |
+(id)withStartValue:(Vector3D)startValue endValue:(Vector3D)endValue speed:(float)speed; | |
+(id)withStartValue:(Vector3D)startValue endValue:(Vector3D)endValue forTime:(NSTimeInterval)time; | |
-(NSString*)description; | |
@end |
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 "AnimatedVector3D.h" | |
@interface AnimatedVector3D () | |
@property (nonatomic, assign) BOOL hasStarted; | |
@property (nonatomic, assign) BOOL hasEnded; | |
@end | |
@implementation AnimatedVector3D | |
@synthesize startValue = _startValue; | |
@synthesize startTime = _startTime; | |
@synthesize hasStarted = _hasStarted; | |
@synthesize endValue = _endValue; | |
@synthesize endTime = _endTime; | |
@synthesize hasEnded = _hasEnded; | |
@synthesize curve = _curve; | |
@dynamic value; | |
-(id)initWithStartValue:(Vector3D)startValue endValue:(Vector3D)endValue startTime:(NSTimeInterval)startTime endTime:(NSTimeInterval)endTime | |
{ | |
self = [super init]; | |
if(self) | |
{ | |
_startValue = startValue; | |
_startTime = startTime; | |
_endValue = endValue; | |
_endTime = startTime + TIMESCALE * (endTime - startTime); | |
_hasStarted = NO; | |
_hasEnded = NO; | |
_curve = AnimationLinear; | |
} | |
return self; | |
} | |
+(id)withValue:(Vector3D)value | |
{ | |
NSTimeInterval now = CFAbsoluteTimeGetCurrent(); | |
return [[[AnimatedVector3D alloc] initWithStartValue:value endValue:value startTime:now endTime:now] autorelease]; | |
} | |
+(id)withStartValue:(Vector3D)startValue endValue:(Vector3D)endValue speed:(float)speed | |
{ | |
NSTimeInterval now = CFAbsoluteTimeGetCurrent(); | |
if(speed == 0) | |
{ | |
return [[[AnimatedVector3D alloc] initWithStartValue:startValue endValue:endValue startTime:now endTime:now] autorelease]; | |
} | |
else | |
{ | |
Vector3D difference = Vector3DMakeWithStartAndEndPoints(startValue, endValue); | |
float length = Vector3DMagnitude(difference); | |
return [[[AnimatedVector3D alloc] initWithStartValue:startValue endValue:endValue startTime:now endTime:now + length / abs(speed)] autorelease]; | |
} | |
} | |
+(id)withStartValue:(Vector3D)startValue endValue:(Vector3D)endValue forTime:(NSTimeInterval)timeInterval | |
{ | |
NSTimeInterval now = CFAbsoluteTimeGetCurrent(); | |
return [[[AnimatedVector3D alloc] initWithStartValue:startValue endValue:endValue startTime:now endTime:now + timeInterval] autorelease]; | |
} | |
-(NSString*)description | |
{ | |
return [NSString stringWithFormat:@"[%f5, %f5, %f5] -> [%f5, %f5, %f5]", _startValue.x, _startValue.y, _startValue.z, _endValue.x, _endValue.y, _endValue.z]; | |
} | |
-(Vector3D)value | |
{ | |
NSTimeInterval now = CFAbsoluteTimeGetCurrent(); | |
if(now > self.startTime && !self.hasStarted) | |
{ | |
// You can perform some post-start action here | |
self.hasStarted = YES; | |
} | |
if(now > self.endTime && !self.hasEnded) | |
{ | |
// You can perform some post-end action here | |
self.hasEnded = YES; | |
} | |
if(now < self.startTime) { return self.startValue; } | |
if(now > self.endTime) { return self.endValue; } | |
float delta = (now - self.startTime) / (self.endTime - self.startTime); | |
float delta2 = delta * delta; | |
float delta3 = delta * delta2; | |
float proportion = delta; | |
if(self.curve == AnimationEaseIn) { proportion = (3 * delta - delta3) / 2; } | |
if(self.curve == AnimationEaseOut) { proportion = (3 * delta2 - delta3) / 2; } | |
if(self.curve == AnimationEaseInOut) { proportion = (3 * delta2 - 2 * delta3); } | |
return Vector3DInterpolate(self.startValue, self.endValue, proportion); | |
} | |
-(void)setValue:(Vector3D)value | |
{ | |
NSTimeInterval now = CFAbsoluteTimeGetCurrent(); | |
self.startTime = now; | |
self.endTime = now; | |
self.startValue = value; | |
self.endValue = value; | |
self.hasStarted = YES; | |
self.hasEnded = YES; | |
} | |
@end |
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
#define TIMESCALE 1 | |
enum | |
{ | |
AnimationEaseInOut, | |
AnimationEaseIn, | |
AnimationEaseOut, | |
AnimationLinear | |
} | |
typedef AnimationCurve; | |
static inline float absf(float float1, float float2) | |
{ | |
return float1 < float2 ? float2 - float1 : float1 - float2; | |
} | |
typedef struct | |
{ | |
float x; | |
float y; | |
float z; | |
} Vector3D; | |
static inline Vector3D Vector3DMake(float inX, float inY, float inZ) | |
{ | |
Vector3D ret; | |
ret.x = inX; | |
ret.y = inY; | |
ret.z = inZ; | |
return ret; | |
} | |
static inline Vector3D Vector3DInterpolate(Vector3D startValue, Vector3D endValue, float proportion) | |
{ | |
return Vector3DMake((1.0 - proportion) * startValue.x + (proportion) * endValue.x, | |
(1.0 - proportion) * startValue.y + (proportion) * endValue.y, | |
(1.0 - proportion) * startValue.z + (proportion) * endValue.z); | |
} | |
static inline float Vector3DMagnitude(Vector3D vector) | |
{ | |
return sqrtf((vector.x * vector.x) + (vector.y * vector.y) + (vector.z * vector.z)); | |
} | |
static inline Vector3D Vector3DMakeWithStartAndEndPoints(Vector3D start, Vector3D end) | |
{ | |
Vector3D ret; | |
ret.x = end.x - start.x; | |
ret.y = end.y - start.y; | |
ret.z = end.z - start.z; | |
return ret; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment