Skip to content

Instantly share code, notes, and snippets.

@CastIrony
Created July 24, 2010 05:19
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 CastIrony/488429 to your computer and use it in GitHub Desktop.
Save CastIrony/488429 to your computer and use it in GitHub Desktop.
#import "Common.h"
@interface AnimatedFloat : NSObject
@property (nonatomic, assign) GLfloat startValue;
@property (nonatomic, assign) NSTimeInterval startTime;
@property (nonatomic, assign) GLfloat endValue;
@property (nonatomic, assign) NSTimeInterval endTime;
@property (nonatomic, assign) AnimationCurve curve;
@property (nonatomic, readonly) GLfloat value;
@property (nonatomic, readonly) BOOL hasEnded;
+(id)withValue:(GLfloat)value;
-(void)setValue:(GLfloat)value forTime:(NSTimeInterval)time andThen:(simpleBlock)work;
-(void)setValue:(GLfloat)value withSpeed:(GLfloat)time andThen:(simpleBlock)work;
-(void)registerEvent:(simpleBlock)work;
-(NSString*)description;
@end
#import "AnimatedFloat.h"
@implementation AnimatedFloat
@synthesize startValue = _startValue;
@synthesize startTime = _startTime;
@synthesize endValue = _endValue;
@synthesize endTime = _endTime;
@synthesize curve = _curve;
@dynamic value;
@dynamic hasEnded;
-(id)initWithStartValue:(GLfloat)startValue endValue:(GLfloat)endValue startTime:(NSTimeInterval)startTime endTime:(NSTimeInterval)endTime
{
self = [super init];
if(self)
{
_startValue = startValue;
_startTime = startTime;
_endValue = endValue;
_endTime = startTime + (endTime - startTime);
_curve = AnimationEaseInOut;
}
return self;
}
+(id)withValue:(GLfloat)value
{
NSTimeInterval now = CFAbsoluteTimeGetCurrent();
return [[[AnimatedFloat alloc] initWithStartValue:value endValue:value startTime:now endTime:now] autorelease];
}
-(void)setValue:(GLfloat)value forTime:(NSTimeInterval)time andThen:(simpleBlock)work
{
NSTimeInterval now = CFAbsoluteTimeGetCurrent();
self.startValue = self.value;
self.endValue = value;
self.startTime = now;
self.endTime = now + time;
[self registerEvent:work];
}
-(void)setValue:(GLfloat)value withSpeed:(GLfloat)speed andThen:(simpleBlock)work
{
NSTimeInterval time = speed == 0 ? 0 : absf(self.value, value) / speed;
NSTimeInterval now = CFAbsoluteTimeGetCurrent();
runAfterDelay(time, work);
self.startValue = self.value;
self.endValue = value;
self.startTime = now;
self.endTime = now + time;
[self registerEvent:work];
}
-(void)registerEvent:(simpleBlock)work
{
NSTimeInterval now = CFAbsoluteTimeGetCurrent();
if(now > self.endTime)
{
runLater(work);
}
else
{
runAfterDelay(self.endTime - now, work);
}
}
-(NSString*)description
{
return [NSString stringWithFormat:@"[%f5] -> [%f5] (Duration:%f5)", _startValue, _endValue, _endTime - _startTime];
}
-(void)dealloc
{
[super dealloc];
}
-(GLfloat)value
{
NSTimeInterval now = CFAbsoluteTimeGetCurrent();
if(now < self.startTime) { return self.startValue; }
if(now > self.endTime) { return self.endValue; }
GLfloat delta = (now - self.startTime) / (self.endTime - self.startTime);
GLfloat delta2 = delta * delta;
GLfloat delta3 = delta * delta2;
if(self.curve == AnimationEaseIn) { delta = (3 * delta - delta3) / 2; }
if(self.curve == AnimationEaseOut) { delta = (3 * delta2 - delta3) / 2; }
if(self.curve == AnimationEaseInOut) { delta = (3 * delta2 - 2 * delta3); }
return (1.0 - delta) * self.startValue + (delta) * self.endValue;
}
-(BOOL)hasEnded
{
return self.endTime < CFAbsoluteTimeGetCurrent();
}
@end
#import "NSObject+Blocks.h"
typedef void(^simpleBlock)(void);
static inline void runAfterDelay(NSTimeInterval delay, simpleBlock work)
{
[[[work copy] autorelease] performSelector:@selector(my_callBlock) withObject:nil afterDelay:delay * TIMESCALE * animate];
}
static inline void runLater(simpleBlock work)
{
[[[work copy] autorelease] performSelector:@selector(my_callBlock) withObject:nil afterDelay:0];
}
@interface NSObject (BlocksAdditions)
-(void)my_callBlock;
@end
#import "NSObject+Blocks.h"
@implementation NSObject (BlocksAdditions)
-(void)my_callBlock
{
void (^block)(void) = (id)self;
block();
}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment