应用程序中的动画效果通常会具有额外的吸引力,而且特别适合需要给顾客、女士们、先生们,或者其他什么人留下美好印象的场合。为此,我想现在就给大家展示一些Dojo在动画方面的本领肯定会大受欢迎。
假如您刚刚从其他地方转到这个页面,可以单击我的头像或这个链接,在那里可以找到我正在连载的“Dojo精解”的另外两篇文章。“Dojo精解”系列文章是为介绍我的新书Dojo: The Definitive Guide而写的,读者朋友可以在Amazon或O’Reilly的书目中查到它。
要想使用Dojo开发动画,首先必须知道:Dojo将最常用的一些动画函数打包在了Base中,另外,Core的fx模块也提供了不少动画功能。记住这些动画功能所在的一种方法,就是记住它们的命名空间——Base中的所有动画函数都位于基础级的dojo命名空间中,而Core中的附加功能则要通过dojo.fx命名空间来访问。在即将展示的例子中,我们会用到fadeIn和fadeOut函数以及超级灵活的animateProperty函数,它们都包含在Base中。而在介绍dojo.fx时,我们会展示将多个动画连缀(chain)和组合(combine)起来的操作。
对于上面提到的这些函数,读者通过Dojo官方的API可以全面了解它们的功能和用法。但为简单起见,本文只介绍它们最基本的用法。对于褪色(fade)函数来说,只用两行短短的代码即可实现一个节点的淡入和淡出。正如下面代码片断所暗示的,Dojo的动画API一般都会返回一个对象,开发人员必须手工调用play()方法才能启动该动画。这样一来,我们不仅可以更好地控制动画,而且也会使连缀和组合动画效果变得更加简单(稍后就会看到)。最后,来看一看代码:
//fade some nodes!
dojo.fadeOut({node : 'someNodeId'}).play();
//then sometime later...
dojo.fadeIn({node : 'someNodeId'}).play();
顾名思义,animateProperty函数的用途就是动态变换任意CSS属性。在下面的例子中,我们将使用该函数动态修改一个方块元素的高度和宽度,以便在屏幕中呈现出内缩(implode)和外爆(explode)的效果——代码如下:
//create an implode animation
var implode = dojo.animateProperty({
node : 'someNodeId',
properties : {
height : {end : 0},
width : {end : 0}
}
});
//create an explode animation (assumes width and height are both 0 when it is run)
var explode = dojo.animateProperty({
node : 'someNodeId',
properties : {
height : {end : 300}, //fill in whatever height/width you need...
width : {end : 300}
}
});
不过,等等——这还不是全部。简单的动画效果的确很酷,但是,把它们连缀和组合起来则更加有趣;估计读者已经猜到了,要做到这一点也非常简单。以下代码展示的是连缀操作,除了把动画对象传递给dojo.fx.chain函数之外,一点也不复杂:
//chain together two fade animations
dojo.fx.chain([
dojo.fadeOut({node : 'someNodeId'}),
dojo.fadeIn({node : 'someNodeId'})
]).play();
组合的实现方式与此非常类似。假如要组合fadeOut和自定义的内缩动画,可以像下面这样:
//combine two animations
dojo.fx.combine([
dojo.fadeOut({node : 'someNodeId'}),
implode //the same one we created a few moments ago
]).play();
以上就是我们这一节要展示的动画。不过,为了让读者能够控制所有这些特效,我们还要使用几个dijit的Button部件,以便于执行JavaScript代码。在这个例子当中,我们要使用dojo/method SCRIPT标签来截取Button部件的onClick扩展点(extension point,疑为事件。——译者注),并完全通过标记来启动动画!通用的模式如下所示:
<div dojoType="dijit.form.Button">Do Something!
<script type="dojo/method" event="onClick" args="evt">
//you can inspect the W3C standardized event object, evt, or do something else like...
someAnimation.play();
//other sweet JavaScript code goes here...
</script>
</div>
好,痛快一点吧,以下就是恰当地实现了上述所有功能的代码。这些代码会在屏幕中央(相对于浏览器的视口)创建一个蓝色的方块,并提供3个按钮来控制相应的动画效果。即使把这些代码直接复制粘贴到一个本地页面中,它们也能正常运行(读者如果想复制不带行号的代码,请到原文页面复制。——译者注)。
<html>
<head>
<title>Animation Station!</title>
<style type="text/css">
@import "http://o.aolcdn.com/dojo/1.0/dojo/resources/dojo.css";
@import "http://o.aolcdn.com/dojo/1.0/dijit/themes/tundra/tundra.css";
</style>
<script
type="text/javascript"
src="http://o.aolcdn.com/dojo/1.0/dojo/dojo.xd.js"
djC>
</script>
<script type="text/javascript">
dojo.require("dojo.fx"); //for dojo.fx.chain and dojo.fx.combine
dojo.require("dojo.parser");
dojo.require("dijit.form.Button");
dojo.addOnLoad(function() {
//get the dimensions of the current viewport
var viewport = dijit.getViewport();
var viewport_height = viewport.h;
var viewport_width = viewport.w;
//center a square in the viewport
var square_dimension = 300;
var e = document.createElement("div");
e.id = "square";
dojo.style(e, "width", square_dimension);
dojo.style(e, "height", square_dimension);
dojo.style(e, "background", "blue");
dojo.style(e, "position", "relative");
dojo.style(e, "left", (viewport_width-square_dimension)/2);
dojo.style(e, "top", (viewport_height-square_dimension)/2);
dojo.body().appendChild(e);
//chain together two fade animations
fadeAnim = dojo.fx.chain([
dojo.fadeOut({node : 'square'}),
dojo.fadeIn({node : 'square'})
]);
//set up an implode animation
var implode = dojo.animateProperty({node : 'square',
properties : {
height : {end : 0},
width : {end : 0}
}
});
//set up an explode animation
var explode = dojo.animateProperty({node : 'square',
properties : {
height : {end : square_dimension},
width : {end : square_dimension}
}
});
//chain together the implode/explode
implExplAnim = dojo.fx.chain([implode,explode]);
//combine the chained fades and the implode/explode
fadeImplExplAnim = dojo.fx.combine([fadeAnim, implExplAnim]);
});
</script>
</head>
<body class="tundra">
<div dojoType="dijit.form.Button">Fade In/Out
<script type="dojo/method" event="onClick" args="evt">
fadeAnim.play();
</script>
</div>
<div dojoType="dijit.form.Button">Implode/Explode
<script type="dojo/method" event="onClick" args="evt">
implExplAnim.play();
</script>
</div>
<div dojoType="dijit.form.Button">Both!
<script type="dojo/method" event="onClick" args="evt">
fadeImplExplAnim.play();
</script>
</div>
</body>
</html>
最后,再说明一下:不久即将发布的Dojo 1.1(当前为Beta3)会包含一些针对1.0版的增强,届时完成相同的例子需要输入的代码量还会减少一些。假如读者想查看在线API,可别被这些增强搞晕喽,因为本页代码使用了1.0.x的bug修正版。
在Dojo: The Definitive Guide面市之前,别忘了每周来看一篇最新的Dojo精解系列文章哟!