接着第1篇中开始updateAll的说明:
在updateAll中,渲染的过程是由rootTimeline.renderTime和rootFramesTimeline.renderTime发起的。这里就需要说明一下TweenLite tool的root时间线。root时间线包含rootTimeline和rootFramesTimeline,是整个Tween过程的绝对基准时间线。其中rootTimeline是所有以秒计时的TweenLite、TweenMax、TimelineLite、TimelineMax对象的时间基准;而rootFramesTimeline是所有以帧计时的TweenLite、TweenMax、TimelineLite、TimelineMax对象的时间基准(通过创建对象时在vars中设置useFrames标志,可以指定对象以秒计时还是以帧计时)。
当TweenLite、TweenMax、TimelineLite或TimelineMax对象在建立的时候(这里先以TweenLite为例吧),会调用TweenCore的构造函数,其中如果没有指定其所属的时间线,那么就会自动根据TweenLite对象的计时方式,把TweenLite对象添加到相应的root时间线上,对应TweenCore构造函数中的语句是:
| 添加TweenLite对象到timeline上 | [复制代码] |
- var tl:SimpleTimeline = (this.vars.timeline is SimpleTimeline) ? this.vars.timeline : (this.vars.useFrames) ? TweenLite.rootFramesTimeline : TweenLite.rootTimeline;
- this.cachedStartTime = tl.cachedTotalTime + _delay;
- tl.addChild(this);
可以看到,如果在构造函数的参数vars中定义timeline属性,则可以指定当前创建的TweenLite对象被添加到非root的时间线,但前提是这条指定的时间线必须在当前对象建立之前就存在。例如如下代码:
| 一个创建TweenLite时指定timeline的例子 | [复制代码] |
- var myTimeline:TimelineLite = new TimelineLite();
- var myVars:Object = {timeline:myTimeline};
- var myTween:TweenLite = new TweenLite(target,10,myVars);
其中,myTween建立时会被添加到已经建立的myTimeline时间线上。但值得注意的是,myTimeline本身也是一个TweenCore对象,它建立的时候也会被添加到某条时间线上,而它建立时不存在其它时间线,因此无法自定义myTimeline被添加到的时间线,所以myTimeline会被添加到root时间线上,由此就形成一个树形结构:myTween的在myTimeline上,而myTimeline在root时间线上。实际上TweenLite tool系统的结构就是这样嵌套的,时间线上可以套时间线或者TweenLite和TweemMax对象,嵌套的层数可以任意,但是嵌套结构的“根”始终是root时间线,而嵌套结构的最顶层(即leaf)就是TweenLite或TweemMax对象。(备注一下,leaf其实也可以是TimelineLite、TimelineMax对象,例如上面如果只创建myTimeline时,则myTimeline就是leaf,但是这样做没有实际意义,因为timeline不会直接操作我想要进行Tween变换的target,timeline是调度添加到其上的TweenLite或TweenMax对象实现间接操作Tween变换的target的。随着后面的窥视,其实能看到TweenLite tool系统中实际是上级操作直接下级的,不能跨级操作,但这样的逐级操作就实现了从root时间线驱动整个系统的运行。)
再回到TweenCore的构造函数中,注意在timeline.addChild之前,设置了当前创建的TweenLite对象的cachedStartTime属性:
| 设置TweenLite的启动时间 | [复制代码] |
- this.cachedStartTime = tl.cachedTotalTime + _delay;
这个设置非常重要,这里就标识了当前TweenLite对象的启动时间(这个时间是相对于其parent时间线而言的),其中tl.cachedTotalTime是parent时间线的播放头当前所处的时间,也就表示parent时间线当前正在播放这个时刻的内容,而_delay则是用户在创建对象时通过vars指定的延迟,这样设置就表示创建的对象会在创建时刻的_delay时间后开始启动,等到后面说明renderTime方法的时候,会再进一步说明TweenCore.cachedStartTime属性的用途。
当前TweenLite对象被添加到时间线之后,还会根据创建时的vars,设置是否反向运行(cachedReversed)和是否暂停(paused)的操作,以后再详细说明这两种机制的原理。不过这里需要指出一点,就是在创建此TweenLite对象时,通过设置vars.reversed想要让对象启动时就反向运行,在目前的TweenLite tool版本中是不可实现的。虽然TweenCore的构造函数中有如下的语句设置反向标志:
| 创建TweenLite时设置reversed标志(实际上是不可用的) | [复制代码] |
- if (this.vars.reversed) {
- this.cachedReversed = true;
- }
但实际上vars.reversed目前并没有列入TweenLite tool的关键字(参见TweenLite._reservedProps属性),设置vars.reversed的后果就是:TweenLite tool会以为用户创建这个TweenLite要去操作被Tween的对象的reversed属性,但实际上用户要操作的这个对象不一定有reversed属性,因此就会抛出异常,所以目前来说想在创建TweenLite时设置reversed属性是不可行的,因此上面设置cachedReversed标志的语句去掉也无妨,这也算是TweenLite tool的一个小bug。额外备注一下:要想修复这个问题会牵扯到一些其它东西,我想在进一步分析之后再来尝试解决,实际上TweenLite tool的reverse方法在某些情况下也会引起一些预期之外的效果,还有待进一步改进,后面在说明反向工作的原理时再详细描述吧。还要顺便指出:用reverse让TweenLite反向运行和用TweenLite.from创建反向运行的TweenLite这两者是有区别的,前者设置的是cachedReversed标志,后者设置的是runBackwards标志,在讲到renderTime的时候再具体说明。至此TweenCore的构造函数执行完毕。