class rkuk implements ActionScript

我的ActionScript小路

« TweenLite源码剖析2TweenLite源码剖析4 »

TweenLite源码剖析3

Ok,接着上一篇从TweenCore构造函数中返回后,就来到了TweenLite自身的构造函数中:

TweenLite的构造函数 [复制代码]
  1. this.target = target;
  2. if (this.target is TweenCore && "timeScale" in this.vars) {
  3.     this.cachedTimeScale = 1;
  4. }
  5. propTweenLookup = {};
  6. _ease = defaultEase;
  7. _overwrite = (!("overwrite" in vars) || (!overwriteManager.enabled && vars.overwrite > 1)) ? overwriteManager.mode : int(vars.overwrite);
  8. var a:Array = masterList[target];
  9. if (!a) {
  10.     masterList[target] = [this];
  11. } else {
  12.     if (_overwrite == 1) {
  13.         for each (var sibling:TweenLite in a) {
  14.             if (!sibling.gc) {
  15.                 sibling.setEnabled(false, false);
  16.             }
  17.         }
  18.         masterList[target] = [this];
  19.     } else {
  20.         a[a.length] = this;
  21.     }
  22. }
  23. if (this.active || this.vars.immediateRender) {
  24.     renderTime(0, false, true);
  25. }

这个过程中完成的操作有如下部分:
1  记录被TweenLite操作的target。

2  创建propTweenLookup对象,在后面会具体说明这个对象用于根据操作的属性,查找到实际操作这个属性的PropTween对象,例如查找操作MovieClip对象x属性的PropTween,这样便于实现TweenLite.killVars方法。解释一下这个方法的作用:一个TweenLite对象可以同时对对象的多个属性执行Tween,例如同时让MovieClip的x和y都增大,但是如果用户在Tween的过程中不想让TweenLite再改变MovieClip的x属性,但同时又要保留这个TweenLite对象继续增加y,那么就可以通过killVars取消操作某个属性。

3  设置TweenLite对象的默认ease。ease的作用是控制Tween过程是加速还是减速,或者实现弹性等效果,默认的ease是匀减速的。

4  设置TweenLite对象的_overwrite模式,也就是设定当前TweenLite如何处理与其它也作用在同一个target上的TweenLite或者TweenMax之间的关系。参见OverwriteManager的说明,有6中模式,这里先说明_overwrite=1的情况,其它的到OverwriteManager中说明。在TweenLite的构造函数设置完_overwrite之后,会从masterList中检查是否已经有作用在target上的其它TweenLite,如果没有那么当前创建的TweenLite就是第一个,就记录到masterList中;如果检测到有其它TweenLite,并且当前创建的TweenLite的_overwrite=1的时候,就禁用其它TweenLite并且从masterList删除被禁用的TweenLite。这个过程说明了三点:第一点是所有TweenLite创建时都会记录在TweenLite.masterList静态属性引用的Dictionary中,这样可以实现从被作用的对象查找到相应的TweenLite,其实TweenMax创建时也会记录到masterList中,因为TweenMax是TweenLite的子类,而TimelineLite和TimelineMax则不会记录到masterList中。第二点是如果当前创建的TweenLite的overwrite=1,那么它会在创建时(注意不是在第一次渲染时)禁止其它已经创建并作用在同一个target上的TweenLite,而不论其它TweenLite是否开始真正开始发挥作用,当然此刻还没有创建的TweenLite当然不会被禁止。第三点是如果当前创建的TweenLite的overwrite不是1,那么就只记录到masterList中,其它作用在同一个target上的TweenLite不受在此时影响。

5  TweenLite构造函数的最后一步就是根据vars中是否有immediateRender设置,决定是否立即渲染Tween变化起始状态的效果。立即渲染(也就是在创建TweenLite时就执行渲染)有时很重要。区别在于:如果不执行立即渲染,那么TweenLite创建完成后,target中还保持原状,最快要等到下一个EnterFrame事件触发时,才会把target渲染成Tween的开始状态;而如果立即渲染的话,那么在TweenLite创建完成之后,target就已经被渲染成为Tween的开始状态。上述的target原状和Tween的开始状态之间最短会存在一帧时间的间隔。如果target原状和Tween的开始状态之间有明显差别的话,就会因为这一帧时间的间隔发生跳变。例如用TweenLite.from方法创建Tween的时候,target的原状和Tween的开始状态通常就是不一致的,因此TweenLite.from方法中默认就是设置immediateRender=true的,以避免产生跳变。实际上TweenLite第一次执行渲染的时候,还会有除了渲染本身之外的一些初始化工作,因此设置好是否在创建TweenLite时就执行第一次渲染是很重要的。另外,源代码中此处还存在一个小问题,也就是要检查TweenLite.active和vars.immediateRender来决定是否立即渲染,其实在TweenCore的构造函数中,active由三个标志“与”的值共同决定,其中一个标志就是immediateRender,因此这里检查active实际上是多余的,因为immediateRender=false时肯定active就是false,而immediateRender=true时,不论active怎样取值,肯定都立即渲染,因此这里可以把对active的检测去掉。

  • quote 1.zszen
  • 请问当我对一个sprite设置了alpha淡入进来, 还没有完全完成, 就激活了x/y位置属性或是scale属性 ,默认情况下alpha动作就会消失 , overwrite也无法改正效果, 我的方法只有在新的动作里面也加入alpha淡入, 才能避免, 但是我认为, 这样做可能会很浪费, 而且逻辑可能会很混乱
    rkuk 于 2009-12-3 12:09:53 回复
    我想alpha动作之所以消失是因为后创建的x、y的tween的overwrite=1,所以覆盖了alpha的tween。看来你需要先完成alpha后再开始位置或大小的tween,像这样带有“顺序”的tween可以装入一个TimelineLite中以便于控制,并且引入TimelineLite会自动把所有新创建的tween的overwrite模式都设置为2,这样就可以避免以外的覆盖。可以这样做:
    var tl:TimelineLite = new TimelineLite();
    var alphaTween:TweenLite = TweenLite.from(sp,5,{alpha:0});
    var posTween:TweenLite = TweenLite.to(sp,5,{x:100,y:100});
    tl.append(alphaTween);
    tl.append(posTween);

    由 rkuk 于 2009-12-3 12:24:16 最后编辑
  • 2009-12-3 2:52:42 回复该留言
  • quote 2.zszen
  • 这样做显然太麻烦, 发现timelite的overwrite设置为0可以实现效果,但是可能会出现混乱(前后有同样属性设置的时候), 但是用tweenmax就不存在这种情况 ,也不需要设置什么overwrite, 但总会给我耗费资源的感觉 哈
    rkuk 于 2009-12-4 19:37:46 回复
    当使用TweenMax的时候,TweenMax有个静态属性_overwriteMode的初始化会启动OverwriteManager把所有新建的Tween的overwrite模式都设置为2,这与引入TimelineLite的效果是一样的,所以可以解决覆盖冲突的问题。
    设置overwrite=0就是取消检测操作同一个对象的Tween之间的冲突,这样可以让后创建的Tween不覆盖已有的Tween,但此时如果后创建的Tween操作的属性和先创建的Tween操作的属性有冲突时,后创建的Tween对这个属性的操作是不起作用的。文章里面说过后创建的Tween会先被渲染,而起作用的是最后渲染的Tween。
    因为看到你好像是需要创建有先后顺序的的Tween,所以想到用TimelineLite。我觉得引入TweenMax只能解决你说的冲突问题,但是并不能解决先后问题,当然你可以使用delay属性来创建时序。如果你实在不想用TimelineLite,而只用delay的话,那么用TweenLite也可以设置delay,此时可以用OverwriteManager.init将overwrite设为0或者2,都可以解决冲突。
    再补充一点:TweenMax在初始化的时候会自动注册很多plugin,并且TweenMax的renderTime方法要比TweenLite复杂,这个方法会被反复调用所以会比较影响效率。相对而言TimelineLite的渲染就快速一些,而且不会注册plugin,又方便时序管理。我想并不是代码看起来多就浪费,敏捷开发的一个观点就是清晰易看懂的代码会让你的效率更高!
  • 2009-12-4 18:42:55 回复该留言
  • quote 3.zszen
  • http://zszen.com
  • 谢谢 , 其实我并不像让两次设置的属性都完全进行完毕, 我只希望出现overwrite=2/tweenmax这样的功能, 不过尝试了,还是max好用.
  • 2009-12-7 1:02:20 回复该留言
  • quote 4.gerr87
  • 如果就实用性来说,显然应该选择tweenlite,tweenmax代码简洁,代价不小
  • 2010-1-29 12:00:28 回复该留言

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

日历

最新评论及回复

最近发表

Copyright © 2008 www.rkuk.org, All Rights Reserved.

Powered By Z-Blog 1.8 Arwen Build 90619