Dojo精解(三)

Posted by admin | 翻译, JavaScript, 原创, 好书 | 星期三 10 9月 2008 9:11 下午

作者:Matthew Russell 原文链接
2008年3月18日,星期二,3:38PM

应用程序中的动画效果通常会具有额外的吸引力,而且特别适合需要给顾客、女士们、先生们,或者其他什么人留下美好印象的场合。为此,我想现在就给大家展示一些Dojo在动画方面的本领肯定会大受欢迎。

假如您刚刚从其他地方转到这个页面,可以单击我的头像或这个链接,在那里可以找到我正在连载的“Dojo精解”的另外两篇文章。“Dojo精解”系列文章是为介绍我的新书Dojo: The Definitive Guide而写的,读者朋友可以在AmazonO’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()方法才能启动该动画。这样一来,我们不仅可以更好地控制动画,而且也会使连缀和组合动画效果变得更加简单(稍后就会看到)。最后,来看一看代码:

  1. //fade some nodes!
  2. dojo.fadeOut({node : 'someNodeId'}).play();
  3. //then sometime later...
  4. dojo.fadeIn({node : 'someNodeId'}).play();

顾名思义,animateProperty函数的用途就是动态变换任意CSS属性。在下面的例子中,我们将使用该函数动态修改一个方块元素的高度和宽度,以便在屏幕中呈现出内缩(implode)和外爆(explode)的效果——代码如下:

  1. //create an implode animation
  2. var implode = dojo.animateProperty({
  3.    node : 'someNodeId',
  4.    properties : {
  5.        height : {end : 0},
  6.        width  : {end : 0}
  7.    }
  8. });
  9.  
  10. //create an explode animation (assumes width and height are both 0 when it is run)
  11. var explode = dojo.animateProperty({
  12.    node : 'someNodeId',
  13.    properties : {
  14.        height : {end : 300}, //fill in whatever height/width you need...
  15.        width  : {end : 300}
  16.    }
  17. });

不过,等等——这还不是全部。简单的动画效果的确很酷,但是,把它们连缀和组合起来则更加有趣;估计读者已经猜到了,要做到这一点也非常简单。以下代码展示的是连缀操作,除了把动画对象传递给dojo.fx.chain函数之外,一点也不复杂:

  1. //chain together two fade animations
  2. dojo.fx.chain([
  3.    dojo.fadeOut({node : 'someNodeId'}),
  4.    dojo.fadeIn({node : 'someNodeId'})
  5. ]).play();

组合的实现方式与此非常类似。假如要组合fadeOut和自定义的内缩动画,可以像下面这样:

  1. //combine two animations
  2. dojo.fx.combine([
  3.    dojo.fadeOut({node : 'someNodeId'}),
  4.    implode //the same one we created a few moments ago
  5. ]).play();

以上就是我们这一节要展示的动画。不过,为了让读者能够控制所有这些特效,我们还要使用几个dijit的Button部件,以便于执行JavaScript代码。在这个例子当中,我们要使用dojo/method SCRIPT标签来截取Button部件的onClick扩展点(extension point,疑为事件。——译者注),并完全通过标记来启动动画!通用的模式如下所示:

  1. <div dojoType="dijit.form.Button">Do Something!
  2.     <script type="dojo/method" event="onClick" args="evt">
  3.         //you can inspect the W3C standardized event object, evt, or do something else like...
  4.         someAnimation.play();
  5.         //other sweet JavaScript code goes here...
  6.     </script>
  7. </div>

好,痛快一点吧,以下就是恰当地实现了上述所有功能的代码。这些代码会在屏幕中央(相对于浏览器的视口)创建一个蓝色的方块,并提供3个按钮来控制相应的动画效果。即使把这些代码直接复制粘贴到一个本地页面中,它们也能正常运行(读者如果想复制不带行号的代码,请到原文页面复制。——译者注)。

  1. <html>
  2.     <head>
  3.         <title>Animation Station!</title>
  4.         <style type="text/css">
  5.             @import "http://o.aolcdn.com/dojo/1.0/dojo/resources/dojo.css";
  6.             @import "http://o.aolcdn.com/dojo/1.0/dijit/themes/tundra/tundra.css";
  7.         </style>
  8.  
  9.         <script
  10.             type="text/javascript"
  11.             src="http://o.aolcdn.com/dojo/1.0/dojo/dojo.xd.js"
  12.             djConfig="parseOnLoad:true">
  13.         </script>
  14.         <script type="text/javascript">
  15.             dojo.require("dojo.fx"); //for dojo.fx.chain and dojo.fx.combine
  16.             dojo.require("dojo.parser");
  17.             dojo.require("dijit.form.Button");
  18.  
  19.             dojo.addOnLoad(function() {
  20.  
  21.                 //get the dimensions of the current viewport
  22.                 var viewport = dijit.getViewport();
  23.                 var viewport_height = viewport.h;
  24.                 var viewport_width = viewport.w;
  25.  
  26.                 //center a square in the viewport
  27.                 var square_dimension = 300;
  28.                 var e = document.createElement("div");
  29.                 e.id = "square";
  30.                 dojo.style(e, "width", square_dimension);
  31.                 dojo.style(e, "height", square_dimension);
  32.                 dojo.style(e, "background", "blue");
  33.                 dojo.style(e, "position", "relative");
  34.                 dojo.style(e, "left", (viewport_width-square_dimension)/2);
  35.                 dojo.style(e, "top", (viewport_height-square_dimension)/2);
  36.                 dojo.body().appendChild(e);
  37.  
  38.                 //chain together two fade animations
  39.                 fadeAnim = dojo.fx.chain([
  40.                    dojo.fadeOut({node : 'square'}),
  41.                    dojo.fadeIn({node : 'square'})
  42.                 ]);
  43.  
  44.                 //set up an implode animation
  45.                 var implode = dojo.animateProperty({node : 'square',
  46.                    properties : {
  47.                        height : {end : 0},
  48.                        width  : {end : 0}
  49.                    }
  50.                 });
  51.                 //set up an explode animation
  52.                 var explode = dojo.animateProperty({node : 'square',
  53.                    properties : {
  54.                        height : {end : square_dimension},
  55.                        width  : {end : square_dimension}
  56.                    }
  57.                 });
  58.                 //chain together the implode/explode
  59.                 implExplAnim = dojo.fx.chain([implode,explode]);
  60.  
  61.                 //combine the chained fades and the implode/explode
  62.                 fadeImplExplAnim = dojo.fx.combine([fadeAnim, implExplAnim]);
  63.  
  64.             });
  65.         </script>
  66.     </head>
  67.     <body class="tundra">
  68.         <div dojoType="dijit.form.Button">Fade In/Out
  69.             <script type="dojo/method" event="onClick" args="evt">
  70.                 fadeAnim.play();
  71.             </script>
  72.         </div>
  73.  
  74.         <div dojoType="dijit.form.Button">Implode/Explode
  75.             <script type="dojo/method" event="onClick" args="evt">
  76.                 implExplAnim.play();
  77.             </script>
  78.         </div>
  79.  
  80.         <div dojoType="dijit.form.Button">Both!
  81.             <script type="dojo/method" event="onClick" args="evt">
  82.                 fadeImplExplAnim.play();
  83.             </script>
  84.         </div>
  85.     </body>
  86. </html>

最后,再说明一下:不久即将发布的Dojo 1.1(当前为Beta3)会包含一些针对1.0版的增强,届时完成相同的例子需要输入的代码量还会减少一些。假如读者想查看在线API,可别被这些增强搞晕喽,因为本页代码使用了1.0.x的bug修正版。

Dojo: The Definitive Guide面市之前,别忘了每周来看一篇最新的Dojo精解系列文章哟!

没有评论 »

还没有评论。

对这篇文章的评论的 RSS 聚合。 TrackBack URI

发表您的评论

验证码  If you cannot see the CheckCode image,please refresh the page again!