代码编织梦想

CALayer和CAAnimation都实现了CAMediaTiming协议。CAMediaTiming协议中有一个beginTime属性。这里记录一些对beginTime属性的理解。

1、全局时间。Core Animation使用一个所谓的全局时间坐标系。这个全局时间坐标系的原点为设备重启完成的那个时刻,当前时间为“现在”距离“起始点”的秒数。CACurrentMediaTime函数即可返回这个秒数。

2、层级和局部时间。layer和animation之间存在父子关系,从而形成层级。另一方面,每个layer或animation都有一个属于自己的局部时间坐标系。beginTime即表示自己的时间坐标系的原点相对于父的时间坐标系的原点的偏移值。这里的父与子的时间坐标系的关系(通过beginTime表示偏移)类似与父与子的空间坐标系的关系(通过frame.origin表示偏移)。

例如,当存在这个层级关系时:layer1 -> layer2 -> animation1 -> animaiton2。

- layer1为根layer,layer1.beginTime表示layer1的局部时间坐标系的原点与全局时间坐标系的原点的偏移。

- layer2为layer1的子layer,layer2.beginTime表示layer2的局部时间坐标系的原点与layer1的局部时间坐标系的原点的偏移。

- animation1为layer2的animation,animation1.beginTime表示animation1的局部时间坐标系的原点与layer2的局部时间坐标系的原点的偏移。

- animation2为animation1的子animation,animation2.beginTime表示animation2的局部时间坐标系的原点与animation1的局部时间坐标系的原点的偏移。

3、几个重要的点。

- 根layer。上面已经提到过,对于根layer,其beginTime表示其局部时间坐标系的原点与全局时间坐标系的原点的偏移。

- “根animation”(这里指的是直接添加到layer的动画,即上面例子里的animation1的情况;而animation2不属于这个情况)。当其beginTime为0时,Core Animation会有一个特别的操作:当layer被commited时,如果layer的直接animation的beginTime为0,那么会将这个animation的beginTime设置为CACurrentMediaTime(),即设置为当前时间。再次强调,仅对“根animation”有这个操作,其他animation不会有这个操作。

== 另一方面,为什么要有这个操作呢?应该就是为了方面开发人员。因为,通常来说,我们为layer加入动画,是需要马上开始执行这个动画的。

== 当我们不想要这个特别的操作,但又想“根animation”的局部时间坐标系的原点与父layer的局部时间坐标系的原点的偏移为0时,只需要将“根animation”的beginTime设置为一个“不为0而且很小很小的数”即可。AVCoreAnimationBeginTimeAtZero就是用来这个用途的。

- 其他layer和其他animation。没有什么特别操作,其beginTime即表示其局部时间坐标系的原点与父的局部时间坐标系的原点的偏移。

4、layer的局部时间的转换。layer提供converTime方法将时间从layer的局部时间坐标系之间转换。特别地,想将一个全局时间转换到某个layer的局部时间,可以这样获得:[layer convertTime:time fromLayer:nil](可以这样理解,当fromLayer参数为nil是,即表示time参数为全局时间)。

5、Core Animation使用全局时间与layer、animation的局部时间的方式。有几个重要的点:

- 全局时间和animation的局部时间。Core Animation通过使用全局时间的当前时间在animation的局部时间坐标系的位置来决定对animation的操作的。

== 当前时间在animation的局部时间坐标系为负数,表示动画还未开始。

== 当前时间在animation的局部时间坐标系为正数,而且在duration范围内,就会根据在animation的局部时间坐标系的位置来得到animation property的插值,然后用这个新的值去更新渲染树。

== 当前时间在animation的局部时间坐标系为正数,而且在duration范围外,表示动画已经结束了。

== layer的speed为0时,layer的动画全部暂停。

6、“相对”的强大之处。当父的beginTime改变时,所有的子的局部时间坐标系也就相应改变了(坐标系的原点改变了)。这个“相对”机制,再加上对Core Animation使用全局时间与layer、animation的局部时间的方式的了解,我们就可以很好的理解“动画的暂停与继续的实现原理”和“AVSynchronizedLayer的实现原理“等。关键点就是:通过更改layer的beginTime,从而使layer的动画的局部坐标系改变,从而使得“当前时间”处于animation的局部时间坐标系的合适的位置!!

7、举例说明。

- layer1(beginTime=0) -> animation1(beginTime=0,duration=5)。

animation1在layer1被commited后,其beginTime=CACurrentMediaTime()。因此,animation1马上开始执行。

- layer1(beginTime=0) -> animation1(beginTime=0,duration=5) -> animation2(beginTime=0, duration=2)。

animation1在layer1被commited后,其beginTime=CACurrentMediaTime()。因此,animation1马上开始执行;animation2的beginTime为0,但animation2不是“根animation”,beginTime还是为0,对animation1的局部时间坐标系偏移为0,因此,animation2与animation1同时开始执行。

- layer1(beginTime=0) -> animation1(beginTime=0,duration=5) -> animation2(beginTime=1, duration=2)。

animation1在layer1被commited后,其beginTime=CACurrentMediaTime()。因此,animation1马上开始执行;animation2的beginTime为1,对animation1的局部时间坐标系偏移为1,因此,animation2比animation1晚1秒开始执行。

- layer1(beginTime=0) -> animation1(beginTime=CACurrentMediaTime()+2,duration=5)

animation1在layer1被commited后,animation1会在2秒后开始执行。

- layer1(beginTime=0) -> animation1(beginTime=CACurrentMediaTime()-2,duration=5)

animation1在layer1被commited后,animation1会以其2秒处的状态开始执行(相当与已经运行了2秒),并且运行3秒后完成动画。

- layer1(beginTime=0) -> animation1(beginTime=AVCoreAnimationBeginTimeAtZero,duration=5) -> animation2(beginTime=1, duration=2)。

layer1被commited后,animation1和animation2都不会执行。因为对于当前时间,animation1和animation2已经结束了。因为,一般来说,当前时间CACurrentMediaTime()是一个很大的值。

- layer1(beginTime=0) -> layer2(beginTime=10) 

CFTimeInterval currentTime = CACurrentMediaTime();

CFTimeInterval timeLayer1 = [layer1 convertTime:currentTime fromLayer:nil]; // timeLayer1 == currentTime

CFTimeInterval timeLayer2 = [layer2 convertTime:currentTime fromLayer:nil]; // timeLayer2 == (currentTime - 10)

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 本文链接: https://blog.csdn.net/jordanxinwang/article/details/108939486

ios caanimation(四)控制动画过程_coder.l的博客-爱代码爱编程

Timing is an important part of animations, and with Core Animation you specify precise timing information for your animations through the methods and properties of the CAMediaT

ios caanimation(三)核心动画基础_coder.l的博客-爱代码爱编程_caanimation动画不改变位置

layer在核心动画中的地位: 先看一下这个经典的结构图,Core Animation的位置在UIKit/AppKit层之下。 Core Animation is a graphics rendering and animation infrastructure available on both iOS and OS X that you

动画总结 core animation 贝赛尔曲线 显式动画 隐式动画_行者zzz的博客-爱代码爱编程

  Core Animation   接下来详细介绍下动画的各个属性及作用 fromValue: 动画的开始值(Any类型, 根据动画不同可以是CGPoint、NSNumber等)toValue: 动画的结束值, 和fromValue类似beginTime: 动画的开始时间duration : 动画的持续时间repeatCount : 动画的重复

iOS CALayer的理解与简单使用-爱代码爱编程

1. 概述 在iOS APP开发过程中,能看得见的控件都是基于UIView,比如UILabel,UIButton,UITextView等等,这些控件的属性及方法能满足大部分的开发需求,但是仍有些需求,比如圆角,阴影,边框等等,UIView是做不到的,而CALayer就可以满足这些特殊的需求了,那么CALayer又是什么呢?本文将对CALayer做一些简单

iOS CALayer CABasicAnimation以及CATransaction-爱代码爱编程

1. 概述 上文简单讲述了CALayer的概念以及一些属性,针对于Layer,除了其展示样式,我们更注重它的动画,本篇文章及本专栏的后续文章将围绕Layer的核心动画进行探究。 本文首先看一下CALayer的基础动画类CABasicAnimation以及CATransaction的使用。 2.  CALayer基础动画 CALayer基础动画类为C

iOS CALayer仿射变换与3D变换(CGAffineTransform、 CATransform3D)-爱代码爱编程

1. 前言 上一篇文章主要讲解了CALayer的一些基础动画,本篇文章将要研究一下有关图层旋转、放缩以及平移或倾斜所用的CGAffineTransform,还有可以将扁平物体转换成三维空间对象的CATransform3D。 2. CGAffineTransform An affine transformation matrix for use