00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 @import <Foundation/CPObject.j>
00024
00025 @import "CAMediaTimingFunction.j"
00026
00027
00028
00029
00030
00031
00032 CPAnimationEaseInOut = 0;
00033
00034
00035
00036
00037 CPAnimationEaseIn = 1;
00038
00039
00040
00041
00042 CPAnimationEaseOut = 2;
00043
00044
00045
00046
00047 CPAnimationLinear = 3;
00048
00049 ACTUAL_FRAME_RATE = 0;
00050
00077 @implementation CPAnimation : CPObject
00078 {
00079 CPTimeInterval _startTime;
00080 CPTimeInterval _duration;
00081
00082 CPAnimationCurve _animationCurve;
00083 CAMediaTimingFunction _timingFunction;
00084
00085 float _frameRate;
00086 float _progress;
00087
00088 id _delegate;
00089 CPTimer _timer;
00090 }
00091
00098 - (id)initWithDuration:(float)aDuration animationCurve:(CPAnimationCurve)anAnimationCurve
00099 {
00100 self = [super init];
00101
00102 if (self)
00103 {
00104 _duration = MAX(0.0, aDuration);
00105 _animationCurve = anAnimationCurve;
00106 _frameRate = 60.0;
00107 }
00108
00109 return self;
00110 }
00111
00117 - (void)setAnimationCurve:(CPAnimationCurve)anAnimationCurve
00118 {
00119 _animationCurve = anAnimationCurve;
00120
00121 var timingFunctionName = kCAMediaTimingFunctionLinear;
00122
00123 switch (_animationCurve)
00124 {
00125 case CPAnimationEaseInOut: timingFunctionName = kCAMediaTimingFunctionEaseInEaseOut;
00126 break;
00127
00128 case CPAnimationEaseIn: timingFunctionName = kCAMediaTimingFunctionEaseIn;
00129 break;
00130
00131 case CPAnimationEaseOut: timingFunctionName = kCAMediaTimingFunctionEaseOut;
00132 break;
00133
00134 default: [CPException raise:CPInvalidArgumentException
00135 reason:"Invalid value provided for animation curve"];
00136 break;
00137 }
00138
00139 _timingFunction = [CAMediaTimingFunction functionWithName:timingFunctionName];
00140 }
00141
00145 - (CPAnimationCurve)animationCurve
00146 {
00147 return _animationCurve;
00148 }
00149
00155 - (void)setDuration:(CPTimeInterval)aDuration
00156 {
00157 if (aDuration < 0)
00158 [CPException raise:CPInvalidArgumentException reason:"aDuration can't be negative"];
00159
00160 _duration = aDuration;
00161 }
00162
00166 - (CPTimeInterval)duration
00167 {
00168 return _duration;
00169 }
00170
00176 - (void)setFrameRate:(float)frameRate
00177 {
00178 if (frameRate < 0)
00179 [CPException raise:CPInvalidArgumentException reason:"frameRate can't be negative"];
00180
00181 _frameRate = frameRate;
00182 }
00183
00187 - (float)frameRate
00188 {
00189 return _frameRate;
00190 }
00191
00195 - (id)delegate
00196 {
00197 return _delegate;
00198 }
00199
00204 - (void)setDelegate:(id)aDelegate
00205 {
00206 _delegate = aDelegate;
00207 }
00208
00214 - (void)startAnimation
00215 {
00216
00217 if (_timer || _delegate && [_delegate respondsToSelector:@selector(animationShouldStart)] && ![_delegate animationShouldStart:self])
00218 return;
00219
00220 _progress = 0.0;
00221 ACTUAL_FRAME_RATE = 0;
00222 _startTime = new Date();
00223
00224 _timer = [CPTimer scheduledTimerWithTimeInterval:0.0 target:self selector:@selector(animationTimerDidFire:) userInfo:nil repeats:YES];
00225 }
00226
00227
00228
00229
00230 - (void)animationTimerDidFire:(CPTimer)aTimer
00231 {
00232 var elapsed = new Date() - _startTime,
00233 progress = MIN(1.0, 1.0 - (_duration - elapsed / 1000.0) / _duration);
00234
00235 ++ACTUAL_FRAME_RATE;
00236
00237 [self setCurrentProgress:progress];
00238
00239 if (progress === 1.0)
00240 {
00241 [_timer invalidate];
00242 _timer = nil;
00243
00244 if ([_delegate respondsToSelector:@selector(animationDidEnd:)])
00245 [_delegate animationDidEnd:self];
00246 }
00247
00248 }
00249
00253 - (void)stopAnimation
00254 {
00255 if (!_timer)
00256 return;
00257
00258 [_timer invalidate];
00259 _timer = nil;
00260
00261 if ([_delegate respondsToSelector:@selector(animationDidStop:)])
00262 [_delegate animationDidStop:self];
00263 }
00264
00269 - (BOOL)isAnimating
00270 {
00271 return _timer;
00272 }
00273
00278 - (void)setCurrentProgress:(float)aProgress
00279 {
00280 _progress = aProgress;
00281 }
00282
00286 - (float)currentProgress
00287 {
00288 return _progress;
00289 }
00290
00294 - (float)currentValue
00295 {
00296 if ([_delegate respondsToSelector:@selector(animation:valueForProgress:)])
00297 return [_delegate animation:self valueForProgress:_progress];
00298
00299 if (_animationCurve == CPAnimationLinear)
00300 return _progress;
00301
00302 alert("IMPLEMENT ANIMATION CURVES!!!");
00303 }
00304
00305 @end