对我们的弹性球来说,我们可以使用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 }