信息化 频道

选购ERP “上对花轿嫁对郎”


七、 创建高级复合动画效果
    很显然,仅从字面上,读者就能够猜出,这种类型的动画是用于创建更复杂动画的“包装物”(或“容器”)。的确如此。现在,让我们首先来观察一下文件PreviewGlitz.js内复合动画CompositeAnimation相应的源码(因为相当精简):
Sys.Preview.UI.Effects.CompositeAnimation=function(){ 
Sys.Preview.UI.Effects.CompositeAnimation.initializeBase(this);
this._animations=Sys.Component.createCollection(this)
};
Sys.Preview.UI.Effects.CompositeAnimation.prototype={
get_animations:function(){
return this._animations},
getAnimatedValue:function(){
throw Error.invalidOperation()},
dispose:function(){
this._animations.dispose();
this._animations=null;
Sys.Preview.UI.Effects.CompositeAnimation.callBaseMethod(this,"dispose")},
onEnd:function(){
for(var a=0;a<this._animations.length;a++)
this._animations[a].onEnd() },
onStart:function(){
for(var a=0;a<this._animations.length;a++)
this._animations[a].onStart()},
onStep:function(b){
for(var a=0;a<this._animations.length;a++)
this._animations[a].onStep(b)
}
};
Sys.Preview.UI.Effects.CompositeAnimation.descriptor={
properties:[{
name:"animations",type:Array,readOnly:true}]
};
Sys.Preview.UI.Effects.CompositeAnimation.registerClass
("Sys.Preview.UI.Effects.CompositeAnimation",Sys.Preview.UI.Effects.Animation);

    请注意,乍一看,CompositeAnimation动画似乎没有提供什么功能,除了一个空空的壳子来容纳子动画!的确如此。但是,这里真正重要的部分正在于这样一个“壳子”—一个封装各种类型子动画的容器!所以,方法get_animations就变得特别重要;我们可以使用它来取得其下各个子动画控件的“句柄”并进而控制每一个子动画。千言莫如一例,还是让我们动手构造一个展示复合动画强大威力的例子吧。

    如前面一样,右击工程GlitzTest来添加一个新网页CompositeAnimation2.aspx。下面的图8给出了设计时刻页面CompositeAnimation2.aspx的相应屏幕快照。 
    

    图8—复合动画演示网页设计时刻快照。

    怎么还是那幅女孩照片!是的。不过,在这个例子中,我们要使这幅照片爆炸开来,直至全部从屏幕上消失。首先,让我们来观察一下页面CompositeAnimation2.aspx相应的HTML编码部分,如下所示:
<div class="h1">CompositeAnimation Demo</div><br/>
<hr/>
<div id='imageArea' class='demosample' style="width: 162px; height: 236px">
<img id="i" src="img/girl1.jpg" onclick="Explode('i');"
style="position: absolute; left: 16px; top: 131px; width: 157px; height: 234px; cursor: hand;" />
</div>
<hr/>
<div id='labelArea' class='demosample1' style="width: 265px; height: 21px">
<label id="Label1" >Click the girl to see what happens!</label>
</div>

实在没有什么特别的内容,对不对?我们首先创建了一个<img>标签,然后是一个使用<div>标签包围的<label>元素……但是,聪明的读者可能已经猜出,其中的秘密一定在那个图像的click事件处理器Explode('i')中。不错,正是这样!下面,让我们来剖析一下相应的编码实现部分:
<script type="text/javascript"> 
//修改此数字可以更改缩放因子
var _scaleFactor = 6;
var _image, _animation;

function Explode(id)
{
//为了避免出现并发动画的冲突
if(_animation != null)
return;

_image = $get(id);
var width = parseFloat(_image.style.width);
var height = parseFloat(_image.style.height);
var x = parseFloat(_image.style.left);
var y = parseFloat(_image.style.top);

//使用一个CompositeAnimation对象实现
//通过缩放、移动和淡出效果“爆炸”目标
var NumberAnimation1 = new Sys.Preview.UI.Effects.NumberAnimation();
NumberAnimation1.set_target(_image);
NumberAnimation1.set_property('style');
NumberAnimation1.set_propertyKey('width');
NumberAnimation1.set_startValue(width);
NumberAnimation1.set_endValue(width * _scaleFactor);

var NumberAnimation2 = new Sys.Preview.UI.Effects.NumberAnimation();
NumberAnimation2.set_target(_image);
NumberAnimation2.set_property('style');
NumberAnimation2.set_propertyKey('height');
NumberAnimation2.set_startValue(height);
NumberAnimation2.set_endValue(height * _scaleFactor);

var NumberAnimation3 = new Sys.Preview.UI.Effects.NumberAnimation();
NumberAnimation3.set_target(_image);
NumberAnimation3.set_property('style');
NumberAnimation3.set_propertyKey('left');
NumberAnimation3.set_startValue(x);
NumberAnimation3.set_endValue(x - (width * (_scaleFactor - 1)) / 2);

var NumberAnimation4 = new Sys.Preview.UI.Effects.NumberAnimation();
NumberAnimation4.set_target(_image);
NumberAnimation4.set_property('style');
NumberAnimation4.set_propertyKey('top');
NumberAnimation4.set_startValue(y);
NumberAnimation4.set_endValue(y - (height * (_scaleFactor - 1)) / 2);

var FadeAnimation1 = new Sys.Preview.UI.Effects.FadeAnimation();
FadeAnimation1.set_target(new Sys.Preview.UI.Image(_image));
FadeAnimation1.set_effect (Sys.Preview.UI.Effects.FadeEffect.FadeOut);

_animation = new Sys.Preview.UI.Effects.CompositeAnimation();
_animation.get_animations().add(NumberAnimation1);
_animation.get_animations().add(NumberAnimation2);
_animation.get_animations().add(NumberAnimation3);
_animation.get_animations().add(NumberAnimation4);
_animation.get_animations().add(FadeAnimation1);
_animation.set_duration(0.3);
_animation.set_fps(35);
_animation.play();
var timer = new Sys.Preview.Timer();
timer.initialize();
timer.set_enabled(true);
timer.set_interval(500);
timer.add_tick(dispose);
}
function dispose(sender)
{
if (!_animation.get_isPlaying())
{
sender.set_enabled(false); //禁用定时器
_image.parentNode.removeChild(_image); //移除图像
_animation = null;
}
}
</script>
    在此,我们首先定义了三个全局变量:_scaleFactor指定缩放系数,_image指向<img>元素,_animation存储类Sys.Preview.UI.Effects.CompositeAnimation的实例。接下来,当你点击屏幕中的女孩照片时,将触发click事件处理器,从而调用函数Explode。注意,在此为了避免并发动画发生冲突,我们使用了一个if条件语句来避免创建类CompositeAnimation的多个实例。然后,我们取得图像相应的参数。然后,创建了类NumberAnimation的四个实例来实现同时达到缩放,移动和淡出的效果。最后,创建一个类CompositeAnimation的实例把刚才创建的所有子动画“粘合”到一起,并配置相应的播放动画要求的属性。最后,启动动画。此外,还应注意,我们定义了一个类Sys.Preview.Timer的实例来实现动画播放结束后的某种清除功能,因为文件PreviewScript.js中尽管定义了相应的end事件,却没有相应地实现之(或许因为还在Futures CTP版本中的缘故吧)。好,现在按下F5来领略一下这一消魂的爆炸效果吧!下图9是动画播放过程某一时刻的截图。 
   

图9-复合动画带来的惊人效果。

    如何?试想,如果MS AJAX也一并提供了针对二维平台内容(数字及图像)的旋转动画的话,那么,真的是太完美了!但目前这个框架还没有提供这种功能,我坚信勇敢的读者一定会作出尝试的。

【补】ASP.NET AJAX Control Toolkit包中还提供了一种扩展器控件(Extender,这是扩展ASP.NET服务器端控件功能的三大重要技术之一)—AnimationExtender。借助于它,我们可以创建极其丰富的ASP.NET网页动画或开发出自己定制的高级ASP.NET服务器端动画控件。
0
相关文章