ParentAnimation,顾名思义,是一组Animation的父亲,是所有需要包含其它Animation的父类,我们熟悉的 ParallelAnimation(并行动画)和SequenceAnimation(顺序动画)都是它的子类。从这个概念上来说,这也是个非常经典的 Composit模式应用。ParentAnimation相关的UML类图如下:
构造函数:
属性:
方法:
-
add:添加一个子Animation对象。
-
clear:清除并销毁所有子Animation对象。
-
dispose:销毁当前ParentAnimation对象。
-
initialize:初始化当前ParentAnimation对象。
-
remove:删除并销毁指定的子Animation对象。
-
removeAt:删除并销毁指定下标的子Animaion对象。
ParentAnimation在Animation基础上添加了一些集合操作的方法。
在ParentAnimation的构造函 数中,会得到一个数组,存放了初始情况下所有的子Animation对象,它们会被依次调用add方法添加到ParentAnimation自己维护的数 组中。而在ParentAnimation的initialize方法中,会确定每个子Animation有没有被初始化,如果没有,则调用它的 initialize方法。
值得注意的是,像remove, removeAt和clear这些删除子Animation的方法中(也包括dispose方法,它调用了clear方法),除了从 ParentAnimation维护的数组中去除子Animation对象之外,还会将其销毁(调用其dispose方法),因此您再也无法使用这个子 Animation对象了。
在ParentAnimation的add方法有个特别的地方,它是这样的实现的:
ParentAnimation的add方法
add : function(animation) {
if (this._animations) {
if (animation) {
animation._parentAnimation = this;
}
Array.add(this._animations, animation);
this.raisePropertyChanged('animations');
}
}
可以看到,add方法在传入的animation对象中添加了一个_parentAnimation引用指向自己。那么_parentAnimation的作用是什么呢?这就要细化到我们在上一篇文章中的Animation模型了。
关键在于Animation类的target属性,这是它的实现:
Animation类的target属性
get_target : function() {
if (!this._target && this._parentAnimation) {
return this._parentAnimation.get_target();
}
return this._target;
}
在target属性的getter中,如果 发现当前Animation没有指定target,它则会设法通过_parentAnimation引用来寻找父Animation,并使用父 Animation的target属性指定的对象。因此,我们可以仅仅在父Animation中指定target,它的所有子Animation就能统一 对同一个对象进行操作了。
ParentAnimation是一种比较 特别的Animation对象,因为它的作用是“组织和管理”子Animation,因此它使用的是其实是子Animation的功能,而它本身并不提供 动画效果。因此它会覆盖Animation类的一些特别的方法,比如onStart、onStep和onEnd,而像SequenceAnimation 甚至覆盖play,pause和stop方法。
作为示例,我们来开发一个RandomExecutionAnimation,它的作用是随机从子Animation中选择一个,并播放它的动画效果。RandomExecutionAnimation的代码如下:
RandomExecutionAnimation
Type.registerNamespace("Jeffz");
Jeffz.RandomExecutionAnimation = function(target, duration, fps, animations)
{
Jeffz.RandomExecutionAnimation.initializeBase(this, arguments);
this._executingAnimation = null;
}
Jeffz.RandomExecutionAnimation.prototype =
{
dispose : function()
{
Jeffz.RandomExecutionAnimation.callBaseMethod(this, "dispose");
delete this._executingAnimation;
},
onStart : function()
{
Jeffz.RandomExecutionAnimation.callBaseMethod(this, "onStart");
var animations = this.get_animations();
var index = Math.floor(animations.length * Math.random());
this._executingAnimation = animations[index];
this._executingAnimation.onStart();
},
onStep : function(percentage)
{
this._executingAnimation.onStep(percentage);
},
onEnd : function(percentage)
{
this._executingAnimation.onEnd();
}
}
Jeffz.RandomExecutionAnimation.registerClass(
"Jeffz.RandomExecutionAnimation", $AA.ParentAnimation);
在 RandomExecutionAnimation中,我们覆盖了onStart、onStep和onEnd方法,将功能完全委托给随机选择的子 Animation。因此,在子Animation中设置的duration和fps属性的效果将被忽略,它们将会完全使用 RandomExecutionAnimation对象中设置的duration和fps。ParallelAnimation也使用了这种做法,因为它 所有的子Animaion需要同时播放,所以ParallelAnimation就提供了一个同步调配的作用。
RandomExecutionAnimation的使用效果如下:
Hello World
Duration:
Fps:
在这个示例中,我在RandomExecutionAnimation中放置了3个ColorAnimation,分别用于变化元素的边框,背景和前景的颜色。大家可以多次点击Play按钮察看效果。
本文出自 “赵��” 博客,转载请与作者联系!