CABasicAnimation,CAKeyframeAnimation,CATransition,CAAnimationGroup,UIBezierPath之间做动画的不同点和各自的使用范围。
CABasicAnimation:
定义:通过设定起始点,终点,时间,动画会沿着你这设定点进行移动。可以看做特殊的CAKeyFrameAnimation,它是与CAKeyFrameAnimation结合使用才能看到他的强大效果。
CABasicAnimation类的使用方式就是基本的关键帧动画。
所谓关键帧动画,就是将Layer的属性作为KeyPath来注册,指定动画的起始帧和结束帧,然后自动计算和实现中间的过渡动画的一种动画方式。
CABasicAnimation设定动画的几个属性:
属性 | 说明 |
duration | 动画时长(秒为单位)(注:此处与原文有出入) |
repeatCount | 重复次数。永久重复的话设置为HUGE_VALF。 |
beginTime | 指定动画开始时间。从开始指定延迟几秒执行的话,请设置为 |
timingFunction | 设定动画的速度变化 |
autoreverses | 动画结束时是否执行逆动画 |
设定动画开始和结束帧时的状态:
属性 | 说明 |
fromValue | 开始值 |
toValue | 终了值(絶対値) |
byValue | 终了值(相对值) |
动画样式:
移动动画:根据我们给定坐标点进行运动。@"position"
1. /* 移动 */
2. CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"position"];
3.
4. // 动画选项的设定
5. animation.duration = 2.5; // 持续时间
6. animation.repeatCount = 1; // 重复次数
7.
8. // 起始帧和终了帧的设定
9. animation.fromValue = [NSValue valueWithCGPoint:myView.layer.position]; // 起始帧
10.animation.toValue = [NSValue valueWithCGPoint:CGPointMake(320, 480)]; // 终了帧
11.
12.// 添加动画
13.[myView.layer addAnimation:animation forKey:@"move-layer"];
旋转动画:根据我们给定的角度沿着设定的点旋转,@"transform.rotation.y"这是设定沿着y轴旋转。
1. /* 旋转 */
2.
3. // 对Y轴进行旋转(指定Z轴的话,就和UIView的动画一样绕中心旋转)
4. CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.y"];
5.
6. // 设定动画选项
7. animation.duration = 2.5; // 持续时间
8. animation.repeatCount = 1; // 重复次数
9.
10.// 设定旋转角度
11.animation.fromValue = [NSNumber numberWithFloat:0.0]; // 起始角度
12.animation.toValue = [NSNumber numberWithFloat:22 * M_PI]; // 终止角度
13.
14.// 添加动画
15. [myView.layer addAnimation:animation forKey:@"rotate-layer"];
缩放动画:根据我们给定的缩放比例进行缩放,@"transform.scale"这是缩放格式
1. // 设定为缩放
2. CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
3.
4. // 动画选项设定
5. animation.duration = 2.5; // 动画持续时间
6. animation.repeatCount = 1; // 重复次数
7. animation.autoreverses = YES; // 动画结束时执行逆动画
8.
9. // 缩放倍数
10.animation.fromValue = [NSNumber numberWithFloat:1.0]; // 开始时的倍率
11.animation.toValue = [NSNumber numberWithFloat:2.0]; // 结束时的倍率
12.
13.// 添加动画
14. [myView.layer addAnimation:animation forKey:@"scale-layer"];
CAKeyframeAnimation:
之所以叫做关键帧动画是因为,这个类可以实现,某一属性按照一串的数值进行动画,就好像制作动画的时候一帧一帧的制作一样。跟CABasicAnimation的区别是:CABasicAnimation只能从一个数值(fromValue)变到另一个数值(toValue),而CAKeyframeAnimation会使用一个NSArray保存这些数值
CAKeyframeAnimation 的一些比较重要的属性:
1. path
这是一个 CGPathRef 对象,默认是空的,当我们创建好CAKeyframeAnimation的实例的时候,可以通过制定一个自己定义的path来让 某一个物体按照这个路径进行动画。这个值默认是nil 当其被设定的时候 values 这个属性就被覆盖
2. values
一个数组,提供了一组关键帧的值, 当使用path的 时候values的值自动被忽略。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | CGMutablePathRef path = CGPathCreateMutable(); //将路径的起点定位到 (50 120) CGPathMoveToPoint(path,NULL,50.0,120.0); //下面5行添加5条直线的路径到path中 CGPathAddLineToPoint(path, NULL, 60, 130); CGPathAddLineToPoint(path, NULL, 70, 140); CGPathAddLineToPoint(path, NULL, 80, 150); CGPathAddLineToPoint(path, NULL, 90, 160); CGPathAddLineToPoint(path, NULL, 100, 170); //下面四行添加四条曲线路径到path CGPathAddCurveToPoint(path,NULL,50.0,275.0,150.0,275.0,70.0,120.0); CGPathAddCurveToPoint(path,NULL,150.0,275.0,250.0,275.0,90.0,120.0); CGPathAddCurveToPoint(path,NULL,250.0,275.0,350.0,275.0,110.0,120.0); CGPathAddCurveToPoint(path,NULL,350.0,275.0,450.0,275.0,130.0,120.0); //以“position”为关键字 创建 实例 CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"position"]; //设置path属性 [animation setPath:path]; [animation setDuration:3.0]; //这句代码 表示 是否动画回到原位 // [animation setAutoreverses:YES]; CFRelease(path); //开始运行block动画 [self.block.layer addAnimation:animation forKey:NULL]; |
下面一个例子是利用values制作的动画:
1 2 3 4 5 6 7 8 9 10 11 | CGPoint p1=CGPointMake(50, 120); CGPoint p2=CGPointMake(80, 170); CGPoint p3=CGPointMake(30, 100); CGPoint p4=CGPointMake(100, 190); CGPoint p5=CGPointMake(200, 10); NSArray *values=[NSArray arrayWithObjects:[NSValue valueWithCGPoint:p1],[NSValue valueWithCGPoint:p2],[NSValue valueWithCGPoint:p3],[NSValue valueWithCGPoint:p4],[NSValue valueWithCGPoint:p5], nil]; CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"position"]; [animation setValues:values]; [animation setDuration:3.0]; [animation setAutoreverses:YES]; [self.block.layer addAnimation:animation forKey:NULL]; |
- keyPath可以使用的key:
transform.rotation.x 围绕x轴翻转 参数:角度 angle2Radian(4)
transform.rotation.y 围绕y轴翻转 参数:同上
transform.rotation.z 围绕z轴翻转 参数:同上
transform.rotation 默认围绕z轴
transform.scale.x x方向缩放 参数:缩放比例 1.5
transform.scale.y y方向缩放 参数:同上
transform.scale.z z方向缩放 参数:同上
transform.scale 所有方向缩放 参数:同上
transform.translation.xx方向移动 参数:x轴上的坐标 100
transform.translation.yx方向移动 参数:y轴上的坐标
transform.translation.zx方向移动 参数:z轴上的坐标
transform.translation 移动 参数:移动到的点 (100,100)
CATransition:
CAAnimation的子类,用于做转场动画,能够为层提供移出屏幕和移入屏幕的动画效果。
几个比较重要的属性:
filter:为动画添加一个可选的滤镜。
如果指定,那么指定的filter必须同时支持x和y,否则该filter将不起作用。
默认值为nil。
如果设置了filter,那么,为layer设置的type和subtype属性将被忽略。
该属性只在iOS 5.0以及以后版本被支持。
type:动画过渡类型
指定预定义的过渡效果。
默认为kCATransitionFade
如果指定了filter,那么该属性无效。
subtype:动画过渡方向
指定预定义的过渡方向。
默认为nil。
如果指定了filter,那么该属性无效。
预定义的过渡方向为:
kCATransitionFromRight;
kCATransitionFromLeft;
kCATransitionFromTop;
kCATransitionFromBottom;
分别表示:过渡从右边、左边、顶部、底部开始。
startProgress:动画起点(在整体动画的百分比)
定义过度的开始点
开始点的值必须小于或者等于结束点。
默认值为0.0。
这两个属性是float类型的。
可以控制动画进行的过程,可以让动画停留在某个动画点上,值在0.0到1.0之间。endProgress要大于等于startProgress。
比如:立方体转,可以设置endProgress=0.5,让动画停留在整个动画的特定位置(停止在旋转一般的状态)
endProgress:动画终点(在整体动画的百分比)
定义过度的结束点。
结束点的值必须大于或者等于开始点。
默认值为1.0。
翻页效果:
fade //交叉淡化过渡(不支持过渡方向)
push //新视图把旧视图推出去
moveIn //新视图移到旧视图上面
reveal //将旧视图移开,显示下面的新视图
cube //立方体翻滚效果
oglFlip //上下左右翻转效果
suckEffect //收缩效果,如一块布被抽走(不支持过渡方向)
rippleEffect//滴水效果(不支持过渡方向)
pageCurl //向上翻页效果
pageUnCurl //向下翻页效果
cameraIrisHollowOpen //相机镜头打开效果(不支持过渡方向)
cameraIrisHollowClose//相机镜头关上效果(不支持过渡方向)
CATransition *animation = [CATransitionanimation];
//动画时间
animation.duration =1.0f;
//display mode, slow atbeginning and end
animation.timingFunction =UIViewAnimationCurveEaseInOut;
//在动画执行完时是否被移除
animation.removedOnCompletion= NO;
//过渡效果
animation.type =@"pageCurl";
//过渡方向
animation.subtype =kCATransitionFromRight;
//暂时不知,感觉与Progress一起用的,如果不加,Progress好像没有效果
animation.fillMode =kCAFillModeForwards;
//动画停止(在整体动画的百分比).
animation.endProgress =0.7;
[imageView.layeraddAnimation:animation forKey:nil];
CAAnimationGroup——动画组动画,是CAAnimation的子类,可以保存一组动画对象,将CAAnimationGroup对象加入层后,组中所有动画对象可以同时并发运行属性说明:–animations:用来保存一组动画对象的NSArray默认情况下,一组动画对象是同时运行的,也可以通过设置动画对象的beginTime属性来更改动画的开始时间具体的实例如下:
-(void)labelinAnimation{
//position为指定的keypath。 即layer中的可动画属性(animatable property)这行代码就是指定我要对控件的position这个属性进行动画.
//除了CABasicAnimation ,还有CAKeyframeAnimation 以及CAAnimationGroup.
CABasicAnimation *basic = [CABasicAnimation animationWithKeyPath:@"position"];
//设置动画的持续时间
basic.duration = 3.0f;
//对应之前的position .fromValue 为:position的起始位置,需要使用NSValue basic.fromValue = [NSValue valueWithCGPoint:CGPointMake(self.label.center.x, self.view.bounds.size.height+10)];
//.toValue:position动画的结束位置.
basic.toValue = [NSValue valueWithCGPoint:CGPointMake(self.label.center.x,100)];
[self.label.layer addAnimation:basic forKey:@"posit"]; //动画添加至layer层.完成
//组合动画,初始化第二个动画,此次的keypath 是透明度
CABasicAnimation *basic1 = [CABasicAnimation animationWithKeyPath:@"opacity"];
basic1.duration = 3.0f;
//从无到有
basic1.fromValue = @(0);
basic1.toValue = @(1);
//将上述两个动画组合成一个动画。
CAAnimationGroup *group = [CAAnimationGroup animation];
//组合两个动画
[group setAnimations:@[basic,basic1]];
//当使用组合动画之后,持续时间等信息以group的为主
group.duration = 3.0f;
//使动画停留在执行后的位置,最好与group.fillMode=kCAFillModeForwards ;同用
group.removedOnCompletion = NO;
//重复次数
group.repeatCount = 0;
//使动画停留在执行后的位置,最好与removeOnCompletion同用
group.fillMode=kCAFillModeForwards ;
[self.label.layer addAnimation:group forKey:@"posit"];}
CABasicAnimation *animation31 =[CABasicAnimation
animationWithKeyPath: @"position.x" ];
[animation31 setToValue:[NSNumber numberWithFloat:470]];
animation31.cumulative=YES;
animation31.duration = .1;
[animation31 setFillMode:kCAFillModeForwards];
animation31.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
[animation31 setRemovedOnCompletion:NO];
CAAnimationGroup *group = [CAAnimationGroup animation];
group.animations = [NSArray arrayWithObjects:animation31, nil];
group.duration = .1;
group.timingFunction = [CAMediaTimingFunctionfunctionWithName:kCAMediaTimingFunctionEaseInEaseOut];
group.autoreverses = YES;
group.repeatCount = 2;
[garbagebutton.layer addAnimation:group forKey:nil];
UIBezierPath:
使用UIBezierPath类可以创建基于矢量的路径,这个类在UIKit中。此类是Core Graphics框架关于path的一个封装。使用此类可以定义简单的形状,如椭圆或者矩形,或者有多个直线和曲线段组成的形状。
UIBezierPath对象是CGPathRef数据类型的封装。path如果是基于矢量形状的,都用直线和曲线段去创建。我们使用直线段去创建矩形和多边形,使用曲线段去创建弧(arc),圆或者其他复杂的曲线形状。每一段都包括一个或者多个点,绘图命令定义如何去诠释这些点。每一个直线段或者曲线段的结束的地方是下一个的开始的地方。每一个连接的直线或者曲线段的集合成为subpath。一个UIBezierPath对象定义一个完整的路径包括一个或者多个subpaths。
创建和使用一个path对象的过程是分开的。创建path是第一步,包含一下步骤:
(1)创建一个Bezier path对象。
(2)使用方法moveToPoint:去设置初始线段的起点。
(3)添加line或者curve去定义一个或者多个subpaths。
(4)改变UIBezierPath对象跟绘图相关的属性。
例如,我们可以设置stroked path的属性lineWidth和lineJoinStyle。也可以设置filled path的属性usesEvenOddFillRule。
当创建path,我们应该管理path上面的点相对于原点(0,0),这样我们在随后就可以很容易的移动path了。为了绘制path对象,我们要用到stroke和fill方法。这些方法在currentgraphic context下渲染path的line和curve段。
创建一个多边形用直线连接(五边形):
1. - (void)drawRect:(CGRect)rect
2. {
3. UIColor *color = [UIColor redColor];
4. [color set]; //设置线条颜色
5. //创建UIBezierPath
6. UIBezierPath* aPath = [UIBezierPath bezierPath];
7. aPath.lineWidth = 5.0;
8.
9. aPath.lineCapStyle = kCGLineCapRound; //线条拐角
10. aPath.lineJoinStyle = kCGLineCapRound; //终点处理
11.
12. // 设置原点,所有的点都是围绕原点作图形
13. [aPath moveToPoint:CGPointMake(100.0, 0.0)];
14.
15. // 设置剩余的4个点
16. [aPath addLineToPoint:CGPointMake(200.0, 40.0)];
17. [aPath addLineToPoint:CGPointMake(160, 140)];
18. [aPath addLineToPoint:CGPointMake(40.0, 140)];
19. [aPath addLineToPoint:CGPointMake(0.0, 40.0)];
20. [aPath closePath];//第五条线通过调用closePath方法得到的
21.
22. [aPath stroke];//Draws line 根据坐标点连线 (这是空心连线)
// [aPath fill];//实心无边形
23.
24. }
根据圆半径、圆起点角度、圆终点角度、创建一整圆或半圆:
1. - (void)drawRect:(CGRect)rect
2. {
3. UIColor *color = [UIColor redColor];
4. [color set]; //设置线条颜色
5. /*
center:弧线中心点的坐标
radius:弧线所在圆的半径
startAngle:弧线开始的角度值
endAngle:弧线结束的角度值
1. clockwise:是否顺时针画弧线
2. */
3. UIBezierPath* aPath = [UIBezierPath bezierPathWithArcCenter:CGPointMake(150, 150)
4. radius:75
5. startAngle:0
6. endAngle:DEGREES_TO_RADIANS(135)
7. clockwise:YES];
8.
9. aPath.lineWidth = 5.0; //设置线宽
10. aPath.lineCapStyle = kCGLineCapRound; //线条拐角
11. aPath.lineJoinStyle = kCGLineCapRound; //终点处理
12. [aPath stroke];
13.}
通过2个点来设置一条曲线(起点为原点)
1. - (void)drawRect:(CGRect)rect
2. {
3. UIColor *color = [UIColor redColor];
4. [color set]; //设置线条颜色
5.
6. UIBezierPath* aPath = [UIBezierPath bezierPath];
7.
8. aPath.lineWidth = 5.0;
9. aPath.lineCapStyle = kCGLineCapRound; //线条拐角
10. aPath.lineJoinStyle = kCGLineCapRound; //终点处理
11. //原点(起点)
12. [aPath moveToPoint:CGPointMake(20, 100)];
13. //CurveToPoint:为曲线终点 controlPoint:通过这个点来确定曲线的弯曲度
14. [aPath addQuadCurveToPoint:CGPointMake(120, 100) controlPoint:CGPointMake(70, 0)];
15.
16. [aPath stroke];
17.}
通过三个点来确定一条曲线:
1. - (void)drawRect:(CGRect)rect
2. {
3. UIColor *color = [UIColor redColor];
4. [color set]; //设置线条颜色
5.
6. UIBezierPath* aPath = [UIBezierPath bezierPath];
7.
8. aPath.lineWidth = 5.0;
9. aPath.lineCapStyle = kCGLineCapRound; //线条拐角
10. aPath.lineJoinStyle = kCGLineCapRound; //终点处理
11. //起点
12. [aPath moveToPoint:CGPointMake(20, 50)];
13. // CurveToPoint: 终点 controlPoint1:第一点 controlPoint2:第二点
14. [aPath addCurveToPoint:CGPointMake(200, 50) controlPoint1:CGPointMake(110, 0) controlPoint2:CGPointMake(110, 100)];
15.
16. [aPath stroke];
17.}