iOS Animation: CAKeyframeAnimation

Network Core Animation class inheritance diagram of
 
 
 

Properties Introduction

@interface CAKeyframeAnimation : CAPropertyAnimation
/* 提供关键帧数据的数组,数组中的每一个值都对应一个关键帧。根据动画类型(keyPath)的不同 , 值的类型不同*/ @property(nullable, copy) NSArray *values; /*基于点的属性的路径,即动画属性类型为CGPoint。如: position、anchorPoint、transform.translation等 如果为此属性指定非空值,则会忽略values属性*/ @property(nullable) CGPathRef path; /* keyTimes的值与values中的值一一对应指定关键帧在动画中的时间点,取值范围为[0,1]。当keyTimes没有设置的时候, 各个关键帧的时间是平分的*/ @property(nullable, copy) NSArray*keyTimes; /*指定每个关键帧之间的动画缓冲效果,timingFunctions.count = keyTimes.count-1*/ @property(nullable, copy) NSArray*timingFunctions; /*关键帧间插值计算模式*/ @property(copy) NSString *calculationMode; /*针对cubic 计算模式的动画,这些属性提供对插值方案的控制。每个*关键帧都可以具有与之相关的 张力、连续性和偏差值,这些值的范围在[-1,1]内(这定义了Kochanek-*Bartels样条,见http://en.wikipedia.org/wiki/Kochanek-Bartels_spline)。 *tensionValues控制曲线的“紧密度”(正值更紧,负值更圆)。 *continuityValues控制段的连接方式(正值表示锐角,负值表示倒角)。 *biasValues定义曲线发生的位置(正值在控制点之前移动曲线,负值在控制点之后移动它)。 *每个数组中的第一个值定义第一个控制点的切线的行为,第二个值控*制第二个点的切线,依此类推。任何未指定的值都默认为零 *(如果未指定,则给出Catmull-Rom样条曲线)。 */ @property(nullable, copy) NSArray*tensionValues; @property(nullable, copy) NSArray*continuityValues; @property(nullable, copy) NSArray *biasValues; /*定义沿路径动画的对象是否旋转以匹配路径切线*/ @property(nullable, copy) NSString *rotationMode; @end 

Keyframe animation fact by a set of values ​​(or a specified path) and a transition animation type manner corresponding to these times and the node value of each node in time to control the animation display. Keyframe animation may be set by keyframe animation path attributes and attribute values.

Animated with path

1.1 path can only control CGPoint type of animation properties. Such as position, anchorPoint, transform.translation etc.
1.2 When you create a path for all of MoveTo, LineTo, CurveTo methods are given points up the key frame of the animation. May be controlled by the time point keyframe keyTimes attribute assignment, by controlling the animation key frames timingFunctions property
to control the display of the animation.
1.3 path is higher than the priority attribute values of attributes priority. When the path is assigned a non-null value, the value of the property values will be ignored.
1.4 Bezier visual tool:
http://yisibl.github.io/cubic-bezier/#.99,.01,1,.49

- (void)setPathAnimation
{
    CGMutablePathRef path = CGPathCreateMutable();
    //第一个关键帧  -100,-100
    CGPathMoveToPoint(path, NULL, -100, -100); //第二个关键帧 100,-100 CGPathAddLineToPoint(path, NULL, 100, -100); //第三个关键帧 100,100 CGPathAddLineToPoint(path, NULL, 100, 100); //第四个关键帧 -100,100 CGPathAddLineToPoint(path, NULL, -100, 100); //第五个关键帧 -100,-100 CGPathAddLineToPoint(path, NULL, -100, -100); CAKeyframeAnimation *animation = [CAKeyframeAnimation animation]; animation.keyPath = @"transform.translation"; animation.path = path; animation.duration = 4; animation.keyTimes = @[@(0),@(0.1),@(0.5),@(0.75),@(1)]; animation.timingFunctions = @[[CAMediaTimingFunction functionWithControlPoints:1 :0.5 :0.5 :0.5], [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn], [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut], [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionDefault]]; //动画结束后保持动画最后的状态,两个属性需配合使用 animation.removedOnCompletion = NO; animation.fillMode = kCAFillModeForwards; CGPathRelease(path); [self.layer addAnimation:animation forKey:@""]; } 

Animated with values

2.1 values to specify a set of discrete key frames between these keyframes need to transition by interpolation. These interpolation calculations calculationMode provided.
2.2 Internet to see, said calculationMode apply to anchorPoint and position coordinates of the points such as the type of property, the access to official documents and code testing, this argument does not hold. calculationMode interpolation calculation is equally applicable to backgroundColor, opacity and other types of non-coordinate point of animation properties

Keyword Attributes
kCAAnimationLinear Default calculationMode directly connected linearly interpolate between keyframes
kCAAnimationDiscrete 离散的,就是不进行插值计算,所有关键帧直接逐个进行显示。values数组长度比keyTimes数组长度小1,每一个keyTime对表示当前关键帧的起始时间和下一关键帧的起始时间,在keyTime对的时间内,物体停留在当前关键帧指定的位置
kCAAnimationPaced 插入线性关键帧,动画以恒定速度运行。同时忽略keyTimes和timingFunctions设置
kCAAnimationCubic 对关键帧为进行圆滑曲线相连后插值计算,对于曲线的形状还可以通过tensionValues, continuityValues, biasValues来进行自定义调整,这里的数学原理是Kochanek–Bartels spline,这里的主要目的是使得运行的轨迹变得圆滑;
kCAAnimationCubicPaced 看这个名字就知道和kCAAnimationCubic有一定联系,其实就是在kCAAnimationCubic的基础上使得动画运行变得均匀,就是系统时间内运动的距离相同,此时keyTimes以及timingFunctions也是无效的。对于曲线的形状也可以使用tensionValues,continuityValues,biasValues来进行调整
- (void)setValuesAnimation
{
    CGPoint center = self.view.center;
    
    CAKeyframeAnimation *animation = [CAKeyframeAnimation animation]; animation.keyPath = @"position"; animation.duration = 4; animation.repeatCount = CGFLOAT_MAX; animation.delegate = self; // 计算方式1: kCAAnimationLinear 直线相连进行插值计算 animation.calculationMode = kCAAnimationLinear; animation.values = @[[NSValue valueWithCGPoint:CGPointMake(center.x-100, center.y-100)], [NSValue valueWithCGPoint:CGPointMake(center.x+100, center.y-100)], [NSValue valueWithCGPoint:CGPointMake(center.x+100, center.y+100)], [NSValue valueWithCGPoint:CGPointMake(center.x-100, center.y+100)], [NSValue valueWithCGPoint:CGPointMake(center.x-100, center.y-100)]]; animation.keyTimes = @[@(0),@(0.25),@(0.5),@(0.75),@(1)]; animation.timingFunctions = @[[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear], [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn], [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut], [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionDefault]]; // 计算方式2: kCAAnimationDiscrete。 无插值计算values.count = keyTimes.count-1; // animation.calculationMode = kCAAnimationDiscrete; // animation.values = @[[NSValue valueWithCGPoint:CGPointMake(center.x-100, center.y-100)], //关键帧1开始时间0*duration=第0s // [NSValue valueWithCGPoint:CGPointMake(center.x+100, center.y-100)], //关键帧2开始时间0.25*duration=第1s // [NSValue valueWithCGPoint:CGPointMake(center.x+100, center.y+100)], //关键帧3开始时间0.5*duration=第2s // [NSValue valueWithCGPoint:CGPointMake(center.x-100, center.y+100)]]; //关键帧4开始时间0.75*duration=第3s 在第4秒动画结束 // animation.keyTimes = @[@(0),@(0.25),@(0.5),@(0.75),@(1)]; // 计算方式3: kCAAnimationPaced。 关键帧间直线相连进行插值计算,动画以恒定速度运行,忽略keyTimes、timingFunctions; // animation.calculationMode = kCAAnimationPaced; // animation.values = @[[NSValue valueWithCGPoint:CGPointMake(center.x-100, center.y-100)], // [NSValue valueWithCGPoint:CGPointMake(center.x+100, center.y-100)], // [NSValue valueWithCGPoint:CGPointMake(center.x+100, center.y+100)], // [NSValue valueWithCGPoint:CGPointMake(center.x-100, center.y+100)], // [NSValue valueWithCGPoint:CGPointMake(center.x-100, center.y-100)]]; // 计算方式4: kCAAnimationCubic。 关键帧间曲线相连进行插值计算 // animation.calculationMode = kCAAnimationCubic; // animation.values = @[[NSValue valueWithCGPoint:CGPointMake(center.x-100, center.y-100)], // [NSValue valueWithCGPoint:CGPointMake(center.x+100, center.y-100)], // [NSValue valueWithCGPoint:CGPointMake(center.x+100, center.y+100)], // [NSValue valueWithCGPoint:CGPointMake(center.x-100, center.y+100)], // [NSValue valueWithCGPoint:CGPointMake(center.x-100, center.y-100)]]; // //然而知道该如何精确操作 // animation.tensionValues = @[@(1),@(0),@(0),@(0),@(0)]; // animation.continuityValues = @[@(-1),@(1),@(-1),@(1),@(-1)]; // animation.biasValues= @[@(1),@(1),@(1),@(1),@(1)]; // 计算方式5: kCAAnimationCubic。关键帧间曲线相连进行插值计算,动画以恒定速度运行,忽略keyTimes、timingFunctions; // animation.calculationMode = kCAAnimationCubicPaced; // animation.values = @[[NSValue valueWithCGPoint:CGPointMake(center.x-100, center.y-100)], // [NSValue valueWithCGPoint:CGPointMake(center.x+100, center.y-100)], // [NSValue valueWithCGPoint:CGPointMake(center.x+100, center.y+100)], // [NSValue valueWithCGPoint:CGPointMake(center.x-100, center.y+100)], // [NSValue valueWithCGPoint:CGPointMake(center.x-100, center.y-100)]]; // animation.keyTimes = @[@(0),@(0.25),@(0.5),@(0.75),@(1)]; // animation.timingFunctions = @[[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear], // [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn], // [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut], // [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionDefault]]; // //然而知道该如何精确操作 // animation.tensionValues = @[@(1),@(0),@(0),@(0),@(0)]; // animation.continuityValues = @[@(-1),@(1),@(-1),@(1),@(-1)]; // animation.biasValues= @[@(1),@(1),@(1),@(1),@(1)]; [self.layer addAnimation:animation forKey:@""]; if (!_displayLink) { [self.displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; } } 

如有大神碰巧路过,发现问题请进行指正

demo地址:
https://gitee.com/dbmxl/KeyframeAnimation

参考文章:
http://www.iosxxx.com/blog/2015-11-01-coreanimationdong-hua-ru-men.html
https://www.jianshu.com/p/22333040616e

Guess you like

Origin www.cnblogs.com/Free-Thinker/p/11262722.html