Core Animation-CAKeyframeAnimation
任何动画要表象出运动或者变化,至少需要两个不同的关键状态,而中间的状态的变化可以通过插值计算完成,从而形成补间动画,表示关键状态的帧叫做关键帧。
CABasicAnimation其实可以看做一种特殊的关键帧动画,只有头尾两个关键帧。CAKeyframeAnimation则可以支持任意多个关键帧,关键帧有两种方式来指定:使用path或者使用values。其中,path是一个CGPathRef的值,且path只能对CALayer的anchorPoint和position属性起作用,且设置了path之后values就不起作用了。而values更灵活。
keyTimes这个可选参数可以为对应的关键帧指定对应的时间点,其取值为0~1.0。keyTimes中的每一个时间值都对应values中的每一帧。当keyTimes没有设置的时候,各个关键帧的时间是平分的。
还可以通过设置可选参数timingFunction(CAKeyframeAnimation中timingFunction中timingFunction是无效的)为关键帧之间的过渡设置timingFunction,如果values有n个元素,那么timingFunction则应该是n-1个。但是很多时候并不需要timingFunctions,因为已经设置了足够多的关键帧了,比如每1/60秒就设置了一个关键帧,那么帧率将达到60FPS,完全不需要相邻两帧的效果(当然也有可能某两帧值相距较大,可以使用均匀变化或者增加帧率,比如每0.01秒设置一个关键帧)。
在关键帧动画中还有一个非常重要的参数,那便是calculationMode,计算模式。其主要针对的是每一帧的内容为一个坐标点的情况,也就是对anchorPoint和position进行的动画。当在平面坐标系中有多个离散的点的时候,可以是离散的,也可以是直线相连后进行插值计算,也可以使用圆滑的曲线将他们相连后进行插值计算。calculationMode目前提供如下几种模式:kCAAnimationLinear,kCAAnimationDiscrete, kCAAnimationPaced,kCAAnimationCubic, kCAAnimationCubicPaced分别表示直线相连、离散、均匀、圆滑曲线相连、圆滑曲线上均匀。
补充:当calculationMode的值为kCAAnimationCubic或者kCAAnimationCubicPaced时,对于曲线的形状还可以通过tensionValues,continuityValues,biasValues来进行调整自定义。这里的数学原理是Kochanek-Bartels spline,这里的主要目的是使得运行的轨迹变得圆滑。
简单例子:
一个view抖动的动画
- (void)viewDidLoad
{
[super viewDidLoad];
self.animationView = [[UIViewalloc] initWithFrame:CGRectMake(50, 50, 100, 100)];
self.animationView.backgroundColor = [UIColorredColor];
[self.viewaddSubview:self.animationView];
//晃动动画
[selfshakeAnimation];
}
- (void)shakeAnimation
{
CAKeyframeAnimation *animation = [CAKeyframeAnimationanimationWithKeyPath:@"position"];
animation.values = @[[NSValuevalueWithCGPoint:CGPointMake(100, 100)],
[NSValue valueWithCGPoint:CGPointMake(95, 100)],
[NSValue valueWithCGPoint:CGPointMake(105, 100)],
[NSValue valueWithCGPoint:CGPointMake(95, 100)],
[NSValue valueWithCGPoint:CGPointMake(105, 100)],
[NSValue valueWithCGPoint:CGPointMake(95, 100)],
[NSValue valueWithCGPoint:CGPointMake(105, 100)],
[NSValue valueWithCGPoint:CGPointMake(100, 100)]];
animation.timingFunction = [CAMediaTimingFunctionfunctionWithName:kCAMediaTimingFunctionEaseInEaseOut];
animation.duration = 0.5f;
[self.animationView.layeraddAnimation:animation forKey:nil];
}