当前位置 : 主页 > 网页制作 > Dojo >

Dojo1.7动画特效详解

来源:互联网 收集:自由互联 发布时间:2021-06-15
在本教程中我们将会探索Dojo1.7工具包提供的JavaScript特效,这些特效将给你的页面和网站创造酷炫的效果! 本文由Oliver翻译自: Dojo Effects 本文是对dojo1.6同名教程的更新,并使用了1.7版
在本教程中我们将会探索Dojo1.7工具包提供的JavaScript特效,这些特效将给你的页面和网站创造酷炫的效果!
本文由Oliver翻译自: Dojo Effects 本文是对dojo1.6同名教程的更新,并使用了1.7版中最新的写法。 在翻译过程中参考了1.6版的译文:dojo 1.6 官方教程: 手把手教你创建HTML5 JavaScript 动画特效

引言

在前面的一系列教程中,我们已经学习了如何使用并操作DOM节点,处理DOM事件。但是当我们在对DOM节点进行操作时,有些转换会显得突兀:例如删除一个节点,在用户看来它就会在页面上突然消失,有时这种突然变化可能会误导用户。使用Dojo提供的标准特效工具,我们可以构建出更加连贯的用户体验,并且让我们的应用程序显得更加精致和完美。如果进一步使用dojo/_base/fx和dojo/fx包里的更多功能,我们就能够把一系列特效串联起来,创造出非常酷的动态用户体验。 注:Dojo1.7包含了两个fx模块:dojo/_base/fx 和 dojo/fx
  • dojo/_base/fx 提供了一些最基本的特效方法,包括:animateProperty, anim, fadeIn,和fadeOut。
  • dojo/fx 提供了更多高级特效,包括:chain, combine, wipeIn, wipeOut和slideTo
(译者注:Dojo1.7的新写法要求明确地导入每个模块,包括Dojo base中的基本模块,而这些模块在之前的版本中都是默认加载的,因此在使用时要特别注意)



淡入淡出特效 Fading

最常见的一种特效就是DOM节点的淡入与淡出。这个效果在网页上会经常用到,因此dojo把它包含在Dojo的基础包中。我们可以使用这个效果让节点在页面的出现和消失显得连续和平滑。 下面是使用dojo创建淡入淡出效果的示例代码:
<button id="fadeOutButton">Fade block out</button>
<button id="fadeInButton">Fade block in</button>
 
<div id="fadeTarget" class="red-block">
    A red block
</div>
<script>
    require(["dojo/_base/fx", "dojo/on", "dojo/dom", "dojo/domReady!"], function(fx, on, dom) {
        var fadeOutButton = dom.byId("fadeOutButton"),
            fadeInButton = dom.byId("fadeInButton"),
            fadeTarget = dom.byId("fadeTarget");
 
        on(fadeOutButton, "click", function(evt){
            fx.fadeOut({ node: fadeTarget }).play();
        });
        on(fadeInButton, "click", function(evt){
            fx.fadeIn({ node: fadeTarget }).play();
        });
    });
</script>
Dojo里所有的动画特效函数都只接受一个参数对象,该参数对象包含了一系列属性来设定所需动画效果。其中 最重要的属性之一就是 node。 node属性值是一个DOM节点或者是一个DOM 节点的ID (字符串)。 另一个参数 duration,则指定了这个效果的播放要持续的时间,单位是毫秒。如果不指定duration,则默认的播放时间是350毫秒。当然不同的动画效果有不同的参数,不过对于淡入淡出特效而言,这两个参数就足够了。  Dojo的动画特效函数返回值是一个dojo.Animation 对象。这个对象有几个方法: play, pause, stop, status 和gotoPercent 从名字可以看出这几个方法是用来控制动画效果的播放的。 动画对象刚创建时并不会立即播放,需要调用play方法才开始播放。 查看示例


擦除特效 Wiping

另一种常见特效是擦除效果: 它实际上是指改变一个节点的高度,而让其内容逐渐显示或者消失。效果有点类似与雨刷在挡风玻璃上划过留下的痕迹。擦除特效可以用于创建页面的下拉效果,尤其是当页面上有一些不常用的内容时。当然你也可能仅仅是觉得擦除比淡出好看。

请看下面的示例代码:

<button id="wipeOutButton">Wipe block out</button>
<button id="wipeInButton">Wipe block in</button>
 
<div id="wipeTarget" class="red-block wipe">
    A red block
</div>
<script>
    require(["dojo/fx", "dojo/on", "dojo/dom", "dojo/domReady!"], function(fx, on, dom) {
        var wipeOutButton = dom.byId("wipeOutButton"),
            wipeInButton = dom.byId("wipeInButton"),
            wipeTarget = dom.byId("wipeTarget");
 
        on(wipeOutButton, "click", function(evt){
            fx.wipeOut({ node: wipeTarget }).play();
        });
        on(wipeInButton, "click", function(evt){
            fx.wipeIn({ node: wipeTarget }).play();
        });
    });
</script>
和fadeIn/fadeOut不同,使用擦除函数需要引用的是dojo/fx包。另一个需要注意的是我们在这个例子里给目标节点“wipeTarget" 增加了一个css类wipe, 这个类设定了节点的height:auto, 这是因为wipeIn函数的效果是从节点的现有高度变化到其自然高度(即height:auto)。 查看示例


滑动特效 Sliding

前面我们看到了淡入淡出和擦除效果,这两个特效都不能改变节点在页面上的位置。如果想要节点滑动起来,那么就要使用fx.slideTo 。滑动效果可以创造一种动态感,有时也用来表示某种加载进度。dojo.fx.slideTo函数可以在参数指定节点的目标位置(页面上的left和top位置,以像素px为单位) 并把这个节点滑动到目标位置。
<button id="slideAwayButton">Slide block away</button>
<button id="slideBackButton">Slide block back</button>
 
<div id="slideTarget" class="red-block slide">
    A red block
</div>
<script>
    require(["dojo/fx", "dojo/on", "dojo/dom", "dojo/domReady!"], function(fx, on, dom) {
        var slideAwayButton = dom.byId("slideAwayButton"),
            slideBackButton = dom.byId("slideBackButton"),
            slideTarget = dom.byId("slideTarget");
 
        on(slideAwayButton, "click", function(evt){
            fx.slideTo({ node: slideTarget, left: "200", top: "200" }).play();
        });
        on(slideBackButton, "click", function(evt){
            fx.slideTo({ node: slideTarget, left: "0", top: "100" }).play();
        });
    });
</script>

查看示例


动画事件 Animation Events

前面我们提到过,Dojo里的所有的动画特效函数都会返回一个dojo.Animation对象。这个对象不仅提供了方法控制动画的播放暂停,同时还提供了一系列的事件供我们监听,从而使我们可以在动画播放前,播放中,播放后做出不同的响应动作。最重要也是最常用的两个事件是:beforeBegin 和 onEnd。
下面我们看一段使用动画事件的示例代码:
<button id="slideAwayButton">Slide block away</button>
<button id="slideBackButton">Slide block back</button>
 
<div id="slideTarget" class="red-block slide">
    A red block
</div>
<script>
    require(["dojo/fx", "dojo/on", "dojo/dom-style", "dojo/dom", "dojo/domReady!"], function(fx, on, style, dom) {
         
        var slideAwayButton = dom.byId("slideAwayButton"),
            slideBackButton = dom.byId("slideBackButton"),
            slideTarget = dom.byId("slideTarget");
             
            on(slideAwayButton, "click", function(evt){
                // 注意beforeBegin是作为Animation对象的参数直接传给slideTo函数的,
                // 而不是使用connect连接。这保证了我们的逻辑在其他beforeBegin逻辑之前执行。
                var anim = fx.slideTo({
                    node: slideTarget,
                    left: "200",
                    top: "200",
                    beforeBegin: function(){
                         
                        console.warn("slide target is: ", slideTarget);
                         
                        style.set(slideTarget, {
                            left: "0px",
                            top: "100px"
                        });
                    }
                });
 
                // 当然我们也可以像beforeBegin一样把这个处理逻辑以onEnd的名字传给slideTo函数,
                // 但既然一个简单的connect连接就能解决问题,所以……     
                //(译者注:这种做法更符合事件的特点,即当事件触发之后才执行用户逻辑)
                on(anim, "End", function(){
                    style.set(slideTarget, {
                        backgroundColor: "blue"
                    });
                }, true);
 
                // 千万别忘了启动这个动画特效!
                anim.play();
            });
 
            on(slideBackButton, "click", function(evt){
                var anim = fx.slideTo({
                    node: slideTarget,
                    left: "0",
                    top: "100",
                    beforeBegin: function(){
                         
                        style.set(slideTarget, {
                            left: "200px",
                            top: "200px"
                        });
                    }
                });
 
                on(anim, "End", function(){
                    style.set(slideTarget, {
                        backgroundColor: "red"
                    });
                }, true);
 
                anim.play();
            });
    });
</script>
这段示例代码里我们注意到添加beforeBegin 和onEnd (译者注:在使用1.7的新函数on时需要省略事件名前缀的"on",这和addEventListener的用法保持了一致)这两个事件的回调方法的方式不太一样。beforeBegin 的处理方法直接作为参数传递给了slideTo函数。这是因为对某些动画特效beforeBegin处理函数是在对象创建时连接的,如果我们通过on来连接我们的beforeBegin处理函数,则我们的处理函数会在该动画自己的beforeBegin处理函数之后被调用。因此作为参数传入的方法保证了我们的处理函数可以被最先执行。 查看示例


串联动画 Chaining

如果我们想要连续播放多个动画效果该怎么做呢?我们可以利用刚才提到的End事件,在一个特效结束时来启动另一个新效果,但是这样显然不太方便。好在dojo/fx模块为这一类常见的需求提供了一组非常方便的函数,使多个特效能连续播放或者同时播放。这些方法中的每一个都返回一个新的dojo.Animation对象,其中包含一组能描述整个动画序列的事件和方法。我们先来看一下fx.chain是如何让动画特效一个接一个(串联)播放的:
<button id="slideAwayButton">Slide block away</button>
<button id="slideBackButton">Slide block back</button>
 
<div id="slideTarget" class="red-block slide chain">
    A red block
</div>
<script>
    require(["dojo/_base/fx", "dojo/fx", "dojo/on", "dojo/dom", "dojo/domReady!"], function(baseFx, fx, on, dom) {
         
        var slideAwayButton = dom.byId("slideAwayButton"),
            slideBackButton = dom.byId("slideBackButton"),
            slideTarget = dom.byId("slideTarget");
             
        // 设置一些click事件处理函数来播放我们的串联动画
        on(slideAwayButton, "click", function(evt){
            fx.chain([
                baseFx.fadeIn({ node: slideTarget }),
                fx.slideTo({ node: slideTarget, left: "200", top: "200" }),
                baseFx.fadeOut({ node: slideTarget })
            ]).play();
        });
        on(slideBackButton, "click", function(evt){
            fx.chain([
                baseFx.fadeIn({ node: slideTarget }),
                fx.slideTo({ node: slideTarget, left: "0", top: "100" }),
                baseFx.fadeOut({ node: slideTarget })
            ]).play();
        });
         
    });
</script>
如您所见,我们在调用fx.chain的时候直接传入了一个特效数组,并对该方法所返回的dojo.Animation对象调用了play方法来启动整个特效链。现在我们不需要逐个启动特效了,fx.chain已经为我们解决了问题。 查看示例


组合动画 Combining

dojo/fx提供的另一个方便的方法combine能够同时启动多个动画特效。其返回的dojo.Animation对象将在耗时最长的动画特效结束后触发onEnd事件。让我们来看另一个例子:
<button id="slideAwayButton">Slide block away</button>
<button id="slideBackButton">Slide block back</button>
 
<div id="slideTarget" class="red-block slide chain">
    A red block
</div>
<script>
    require(["dojo/_base/fx", "dojo/fx", "dojo/on", "dojo/dom", "dojo/domReady!"], function(baseFx, fx, on, dom) {
         
        var slideAwayButton = dom.byId("slideAwayButton"),
            slideBackButton = dom.byId("slideBackButton"),
            slideTarget = dom.byId("slideTarget");
 
        // 设置一些click事件处理函数来播放我们的组合动画
        on(slideAwayButton, "click", function(evt){
            fx.combine([
                baseFx.fadeIn({ node: slideTarget }),
                fx.slideTo({ node: slideTarget, left: "200", top: "200" })
            ]).play();
        });
        on(slideBackButton, "click", function(evt){
            fx.combine([
                fx.slideTo({ node: slideTarget, left: "0", top: "100" }),
                baseFx.fadeOut({ node: slideTarget })
            ]).play();
        });
         
    });
</script>
在这个例子中,淡入和滑动特效并不是依次播放,而是同时发生的。 通过使用chain和combine,我们可以用几种简单效果组合出很不错的动画特效。同时chain和combine的返回值仍然是一个animation对象,也就是说它们还可以被进一步地串联、组合,从而可以创造出非常精巧复杂的效果。 查看示例


结语

使用Dojo的特效方法,你可以快速的给页面加上有趣的动画效果。dojo/_base/fx模块中包含了淡入淡出方法fadeIn和fadeOut,而通过dojo/fx模块你还可以使用擦除和滑动等许多功能强大的特效。另外,有了chain和combine 这两个方法,就能方便快捷地构建出更复杂、更高级的动画效果。
当然如果你还想更进一步的控制动画的效果,例如,像wipeOut一样调整某个DOM节点的高度,但是又不把它完全缩减到0(完全擦除),或者通过动画来调整背景色的渐变? Dojo提供了一个更加通用和强大的dojo.animateProperty对象来实现。 我们会在未来的教程中详细介绍。 
网友评论