对我们的弹性球来说,我们可以使用bounceEaseOut函数:

 1 float bounceEaseOut(float t)
2 {
3 if (t < 4/11.0) {
4 return (121 * t * t)/16.0;
5 } else if (t < 8/11.0) {
6 return (363/40.0 * t * t) - (99/10.0 * t) + 17/5.0;
7 } else if (t < 9/10.0) {
8 return (4356/361.0 * t * t) - (35442/1805.0 * t) + 16061/1805.0;
9 }
10 return (54/5.0 * t * t) - (513/25.0 * t) + 268/25.0;
11 }

 

如果修改清单10.7的代码来引入bounceEaseOut方法,我们的任务就是仅仅交换缓冲函数,现在就可以选择任意的缓冲类型创建动画了(见清单10.8)。

清单10.8 用关键帧实现自定义的缓冲函数

 1 - (void)animate
2 {
3 //reset ball to top of screen
4 self.ballView.center = CGPointMake(150, 32);
5 //set up animation parameters
6 NSValue *fromValue = [NSValue valueWithCGPoint:CGPointMake(150, 32)];
7 NSValue *toValue = [NSValue valueWithCGPoint:CGPointMake(150, 268)];
8 CFTimeInterval duration = 1.0;
9 //generate keyframes
10 NSInteger numFrames = duration * 60;
11 NSMutableArray *frames = [NSMutableArray array];
12 for (int i = 0; i < numFrames; i++) {
13 float time = 1/(float)numFrames * i;
14 //apply easing
15 time = bounceEaseOut(time);
16 //add keyframe
17 [frames addObject:[self interpolateFromValue:fromValue toValue:toValue time:time]];
18 }
19 //create keyframe animation
20 CAKeyframeAnimation *animation = [CAKeyframeAnimation animation];
21 animation.keyPath = @"position";
22 animation.duration = 1.0;
23 animation.delegate = self;
24 animation.values = frames;
25 //apply animation
26 [self.ballView.layer addAnimation:animation forKey:nil];
27 }