layer 动画解释笔记

一个个Layer通过tree的结构组织起来,在Display的过程中实际上有3种Layer tree。

  1. model layer tree (模型层树)

    我们通常意义说的Layer。当我们修改layer中的属性时,就会立刻修改model layer tree。

  2. presentation tree (表示层树)

    Layer在屏幕中的真实位置,或者说在动画的过程中,layer 的位置

  3. render tree (渲染树)

    apple的render server进程中,是真正处理动画的地方。而且线程的优先级也比我们主线程优先级高。所以有时候即使我们的App主线程busy,依然不会影响到手机屏幕的绘制工作

基本动画


CABasicAnimation 简单的为图层的属性提供修改。

场景,简单的位移动画

     
     
1
2
3
4
5
6
7
8
     
     
CABasicAnimation * animation = [CABasicAnimation animation];
animation. keyPath = @ "position.x";
animation. fromValue = @ 77;
animation. toValue = @ 200;
animation. duration = 3;
[self.v.layer addAnimation:animation forKey:@ "basic"];
self.v.layer. position = CGPointMake( 200, 25);

多步动画


CAKeyframeAnimation 支持关键帧动画,你可以指定的图层属性的关键路径
动画,包括动画的每个阶段的价值,以及关键帧时间和计时功能的一系列值。在 动画运行是,每个值被特定的插入值替代。

场景 动画定义超过两个步骤。

     
     
1
2
3
4
5
6
7
8
9
     
     
CAKeyframeAnimation *animation = [ CAKeyframeAnimation animation];
animation.keyPath = @ "position.x";
animation.values = @[ @0, @10, @- 10, @10, @0 ];
animation.keyTimes = @[ @0, @( 1 / 6.0), @( 3 / 6.0), @( 5 / 6.0), @1 ];
animation.duration = 0. 4;
animation.additive = YES;
[form.layer addAnimation:animation forKey:@ "shake"];
  1. values 数组定义了表单应该到哪些位置。
  2. 设置 keyTimes 属性让我们能够指定关键帧动画发生的时间。它们被指定为关键帧动画总持续时间的一个分数。我们看到是要去 5 个位置,就是 6 步操作,为了保证恒速,我们每 10pt 用 1/6 的keytime
  3. 设置 additive 属性为 YES 使 Core Animation 在更新presentation layer 之前将动画的值添加到 model layer 中去。这使我们能够对所有形式的需要更新的元素重用相同的动画,且无需提前知道它们的位置。因为这个属性从 CAPropertyAnimation 继承,所以你也可以在使用 CABasicAnimation 时使用它。 additive ,动画被设置成相对的。

沿路径动画

虽然用代码实现一个简单的水平晃动并不难,但是沿着复杂路径的动画就需要我们在关键帧的 values 数组中存储大量 box 化的 CGPoint。 值得庆幸的是,CAKeyframeAnimation 提供了更加便利的 path 属性作为代替。

     
     
1
2
3
4
5
6
7
8
9
10
11
12
     
     
CGRect boundingRect = CGRectMake(- 150, - 150, 300, 300);
CAKeyframeAnimation * orbit = [CAKeyframeAnimation animation];
orbit. keyPath = @ "position";
orbit. path = CFAutorelease(CGPathCreateWithEllipseInRect(boundingRect, NULL));
orbit. duration = 4;
orbit. additive = YES;
orbit. repeatCount = HUGE_VALF;
orbit. calculationMode = kCAAnimationPaced;
orbit. rotationMode = kCAAnimationRotateAuto;
[satellite.layer addAnimation:orbit forKey:@ "orbit"];
  1. CGPathCreateWithEllipseInRect(),创建一个椭圆形的不可改变的路径,我们创建一个圆形的 CGPath 作为我们的关键帧动画的 path。
  2. calculationMode 是控制关键帧动画时间的另一种方法。我们通过将其设置为 kCAAnimationPaced,让 Core Animation 向被驱动的对象施加一个恒定速度,不管路径的各个线段有多长。将其设置为 kCAAnimationPaced 将无视所有我们已经设置的 keyTimes。
  3. rotationMode 属性为 kCAAnimationRotateAuto 确保飞船沿着路径旋转。作为对比,如果我们将该属性设置为 nil 那动画会是什么样的呢

我个人更建议这么写

     
     
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
     
     
CGPoint arcCenter=CGPointMake( 100, 100); // 中心锚点
int radius = 100; // 半径
UIBezierPath * circlePath = [UIBezierPath bezierPathWithArcCenter:arcCenter
radius:radius startAngle:DEGREES_TO_RADIANS(- 180)
endAngle:DEGREES_TO_RADIANS( 180)
clockwise:YES];
CAKeyframeAnimation * orbit = [CAKeyframeAnimation animation];
orbit. keyPath = @ "position";
orbit. path = circlePath.CGPath;
orbit. duration = 4;
orbit. additive = YES;
orbit. repeatCount = HUGE_VALF;
orbit. calculationMode = kCAAnimationPaced;
orbit. rotationMode = kCAAnimationRotateAuto;
[self.v.layer addAnimation:orbit forKey:@ "orbit"];

bezierPathWithArcCenter 方法在 api 里写的很清楚,clockwise 为 YES 为顺时针,NO 为逆时针

同样,看图

时间函数

之前的动画都是匀速的,如何让动画更生动通过引入一个 时间函数 (timing function) (有时也被称为 easing 函数)来实现这个目标。该函数通过修改持续时间的分数来控制动画的速度。
最简单的 easing 函数是 linear。它在整个动画上维持一个恒定的速度。在 Core Animation 中,这个功能由 CAMediaTimingFunction 类表示。

     
     
1
2
3
4
5
6
7
8
9
10
11
     
     
CABasicAnimation * animation = [CABasicAnimation animation];
animation. keyPath = @ "position.x";
animation. fromValue = @ 50;
animation. toValue = @ 150;
animation. duration = 1;
animation. timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
[rectangle.layer addAnimation:animation forKey:@ "basic"];
rectangle.layer. position = CGPointMake( 150, 0);

这部分不再细说,直接看 RBBAnimation, 它包含一个允许使用 更多复杂 easing 函数 的自定义子类 CAKeyframeAnimation

动画组

     
     
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
     
     
CABasicAnimation * zPosition = [CABasicAnimation animation];
zPosition. keyPath = @ "zPosition";
zPosition. fromValue = @- 1;
zPosition. toValue = @ 1;
zPosition. duration = 1.2;
CAKeyframeAnimation * rotation = [CAKeyframeAnimation animation];
rotation. keyPath = @ "transform.rotation";
rotation. values = @[ @ 0, @ 0.14, @ 0 ];
rotation. duration = 1.2;
rotation. timingFunctions = @[
[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut],
[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]
];
CAKeyframeAnimation * position = [CAKeyframeAnimation animation];
position. keyPath = @ "position";
position. values = @[
[NSValue valueWithCGPoint:CGPointZero],
[NSValue valueWithCGPoint:CGPointMake( 110, - 20)],
[NSValue valueWithCGPoint:CGPointZero]
];
position. timingFunctions = @[
[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut],
[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]
];
position. additive = YES;
position. duration = 1.2;
CAAnimationGroup * group = [[CAAnimationGroup alloc] init];
group. animations = @[ zPosition, rotation, position ];
group. duration = 1.2;
// group. beginTime = 0.5; 这里如果设置了会出错,原文章设置
[card.layer addAnimation:group forKey:@ "shuffle"];
card.layer. zPosition = 1;

一些属性

position

图层的 position 属性是一个 CGPoint 的值,它指定图层相当于它父图层的位置, 该值基于父图层的坐标系。
在不修改layer其他属性的情况下,layer.position = view.center
可看图

提到的其他有趣的文章

  1.  关于动画时间的一篇很棒的文章
  2.  CAShapeLayer路径动画

参考

  1. http://www.cocoachina.com/industry/20140701/8995.html

声明

  1. 这是一篇关于 http://objccn.io/issue-12-1/ 的学习笔记,概念大多copy原著,如有侵权,请联系本人删除。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值