-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathDecayAnimation.m
53 lines (42 loc) · 1.94 KB
/
DecayAnimation.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#import "DecayAnimation.h"
@implementation DecayAnimation
@synthesize omega;
@synthesize zeta;
+ (id)animationWithKeyPath:(NSString *)keyPath start:(double)start end:(double)end steps:(NSUInteger)steps {
id animation = [self animationWithKeyPath:keyPath];
[((DecayAnimation*)animation) setupWithOmega:30.0 zeta:0.35 start:start end:end steps:steps];
return animation;
}
+ (id)animationWithKeyPath:(NSString *)keyPath start:(double)start end:(double)end steps:(NSUInteger)steps omega:(CGFloat)omega zeta:(CGFloat)zeta {
id animation = [self animationWithKeyPath:keyPath];
[((DecayAnimation*)animation) setupWithOmega:omega zeta:zeta start:start end:end steps:steps];
return animation;
}
- (void) setupWithOmega:(double)newOmega zeta:(double)newZeta start:(double)start end:(double)end steps:(NSUInteger)steps {
self.omega = newOmega;
self.zeta = newZeta;
[self initKeyframesForStartValue:start endValue:end steps:steps];
}
- (void) initKeyframesForStartValue:(double)startValue endValue:(double)endValue steps:(NSUInteger)steps {
NSUInteger count = steps + 2;
NSMutableArray *valueArray = [NSMutableArray array];
double progress = 0.0;
double increment = 1.0 / (double)(count - 1);
NSUInteger i;
// CALCULATE ALL ROTATION TRANSFORMATIONS FOR EACH STEP
// CREATE TRANSFORMATIONS FOR EACH FRAME
for( i = 0; i < count; i++ ) {
double currentRotationValue = startValue + [self evaluateAt:progress] * (endValue - startValue);
CATransform3D rotateTransform = CATransform3DRotate(CATransform3DIdentity, radians(currentRotationValue), 0, 0, 1);
[valueArray addObject:[NSValue valueWithCATransform3D:rotateTransform]];
progress += increment;
}
[self setValues:valueArray];
}
- (double) evaluateAt:(double)position {
double beta = sqrt(1 - zeta * zeta);
double phi = atan(beta / zeta);
double result = 1.0 + -1.0 / beta * exp(-zeta * omega * position) * sin(beta * omega * position + phi);
return result;
}
@end