dojo:animation

  • 为元素的自定义动画创建和组合动画效果。
  • 利用dojo提供的动画工具创建、调整自定义动画,以满足UI需要。

效果概述

就像下面的代码所展示的,可以向函数传递节点参数,指明需要哪个对象使用动画。

require(["dojo/fx", "dojo/dom", "dojo/domReady!"], function(fx, dom) {
    fx.wipeIn({
        node: dom.byId("wipeTarget")
    }).play();
});

    但是,元素有许多拥有单元值的属性,我们可能要实现这些值的动画效果。假如需要让背景具有闪烁的动画效果或者让节点在屏幕四周移动,我们就要用到dojo的常规动画功能-dojo/_base/fx的animateProperty.

动画属性

如何对节点的边框执行动画效果?

    下面是要执行动画的HTML标记:

<button id="startButton">Grow Borders</button>
<button id="reverseButton">Shrink Borders</button>

<div id="anim8target" class="box" style="border-style:outset">
    <div class="innerBox">A box</div>
</div>
    animateProperty方法指定我们要执行动画的border-width属性,调用animateProperty的形式如下:

require(["dojo/_base/fx", "dojo/dom", "dojo/domReady!"], function(baseFx, dom) {
    baseFx.animateProperty({
        node: dom.byId("anim8target"),
        properties: { borderWidth: 100 }
    }).play();
});
    注意:我们使用的是javascript 遵循骆驼拼写法的borderWidth属性,而不是带有连接符的css border-width属性。这里仍然传递一个节点属性,但是这次使用了一个新的“properties”键表示要执行的动画。

    同样的规则适用于具有数值类型值的所有属性。下面的例子对top、left和opacity同时使用动画效果,使元素拖拽出来,并且向左边逐渐消失。分别为top、left和opacity指定start、end属性,我们可以生成特定的、可重复的动画效果。

baseFx.animateProperty({
    node: anim8target,
    properties: {
        top: { start: 25, end: 150 },
        left: 0,
        opacity: { start: 1, end: 0 }
    },
    duration: 800
}).play();
上面使用了duration属性,以毫秒为单位。

Easing(缓和效果)

  关于easing curve可以查阅 给用户界面添加缓和效果(Easing Curves)

   如果要将动画产生的值以图表的形式绘制出来,需要一个曲线来表示从开始到结束的值。这个曲线的形状参考”easing(贝塞尔曲线)"。最简单的曲线是直线。例如,以恒定的速度从x:0移动到y:100。在移动过程中,如果开始时缓慢移动、然后加速,最后减速移动到末尾,那么整个过程看起来就比较自然了。dojo提供了一个用途较多的的easing函数实现理想的移动效果和

require(["dojo/_base/fx", "dojo/dom", "dojo/fx/easing", "dojo/window", "dojo/on", "dojo/domReady!"], function(baseFx, dom, easing, win, on) {
    var dropButton = dom.byId("dropButton"),
        ariseSirButton = dom.byId("ariseSirButton"),
        anim8target = dom.byId("anim8target");

    // Set up a couple of click handlers to run our animations
    on(dropButton, "click", function(evt){
        // get the dimensions of our viewport
        var viewport = win.getBox(win.doc);
        baseFx.animateProperty({
            // use the bounceOut easing routine to have the box accelerate
            // and then bounce back a little before stopping
            easing: easing.bounceOut,
            duration: 500,
            node: anim8target,
            properties: {
                // calculate the 'floor'
                // and subtract the height of the node to get the distance from top we need
                top: { start: 0, end:viewport.h - anim8target.offsetHeight }
            }
        }).play();
    });
    on(ariseSirButton, "click", function(evt){
        baseFx.animateProperty({
            node: anim8target,
            properties: { top: 0 }
        }).play();
    });
});
完整代码:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title></title>
    <script src="../Scripts/dojo/dojo/dojo.js" data-dojo-config="async:true"></script>
    <style type="text/css">
        .box {
            background-color: #ddd;
            border: 1px none #eee;
            height: 200px;
            padding: 5px;
            position: absolute;
            width: 200px;
        }

        .innerBox {
            background-color: white;
            margin: 5%;
            padding: 5px;
        }

        #container {
            height: 300px;
            padding: 10px;
            position: relative;
            width: 450px;
        }

        .contentBox {
            background-color: white;
            border: 1px solid #99c;
            box-shadow: 10px 10px 5px #888;
            margin: 5px;
            position: absolute;
            width: 200px;
        }
    </style>
</head>
<body>
    <h1>Demo: Animation Easing</h1>
    <button id="dropButton">Drop block</button>
    <button id="ariseSirButton">Return block</button>
    <div id="anim8target" class="box" style="top: 0; left: 50%; background-color: #fc9">
        <div class="innerBox">A box</div>
    </div>
    <script>
        require(["dojo/_base/fx", "dojo/dom", "dojo/fx/easing", "dojo/window", "dojo/on", "dojo/domReady!"], function (baseFx, dom, easing, window, on) {
            var dropButton = dom.byId("dropButton"),
                ariseSirButton = dom.byId("ariseSirButton"),
                anim8target = dom.byId("anim8target");
            // Set up a couple of click handlers to run our animations
            on(dropButton, "click", function (evt) {
                //get the dimensions of our viewport
                var viewport = window.getBox(window.doc);
                baseFx.animateProperty({
                    // use the bounceOut easing routine to have the box accelerate
                    // and then bounce back a little before stopping

                    node: anim8target,
                    easing: easing.bounceOut,
                    druation: 500,
                    properties: {
                        top: { start: 0, end: viewport.h - anim8target.offsetHeight }
                    }
                }).play();
            });

            on(ariseSirButton, "click", function (evt) {
                baseFx.animateProperty({
                    node: anim8target,
                    properties: { top: 0 }
                }).play();
            });

        });
    </script>
</body>
</html>

   在这个例子中,我们计算了整个视窗的高度让盒子可以到达底部。使用bounceOut函数让盒子到达底部值,在到达最终值前向上反弹一点。需要注意的是:top属性是一个具有start和end属性的对象,用于限定动画范围。
   几乎所有easing都以In或Out结尾或以InOut结尾,名称隐含了动画效果。关于easing的详细使用说明参考 dojo/fx/easing

Putting it Together


  传统的动画软件经常为模型添加一个时间轴让物体可以一个接一个地连接移动。dojo提供了fx.combine和fx.chain把单独的动画片段组合起来或连接起来。

  在下面的例子中,开始时有两个包含交换内容的盒子。为了突出变化,褪去背景色。下面是HTML标记:

<button id="swapButton">Swap</button>

<div class="container" id="container">
    <div id="content1" class="contentBox" style="top: 0; left: 0">
        <div class="innerBox">1: Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident.</div>
    </div>
    <div id="content2" class="contentBox" style="top: 0; left: 250px">
        <div class="innerBox">2: Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.</div>
    </div>
</div>

下面是脚本代码:

<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js"
        data-dojo-config="isDebug: true, async: true">
<script>

require(["dojo/_base/fx", "dojo/fx", "dojo/fx/easing", "dojo/dom-style", "dojo/dom", "dojo/on", "dojo/aspect", "dojo/domReady!"], function(baseFx, fx, easing, domStyle, dom, on, aspect) {

    function swapAnim(node1, node2) {
        // create & return animation which swaps the positions of 2 nodes
    }

    var originalOrder = true; // track which order our content nodes are in

    var swapButton = dom.byId("swapButton"),
        c1 = originalOrder ? dom.byId("content1") : dom.byId("content2"),
        c2 = originalOrder ? dom.byId("content2") : dom.byId("content1"),
        container = dom.byId("container");

        // Set up a click handler to run our animations
        on(swapButton, "click", function(evt){
            // pass the content nodes into swapAnim to create the node-swapping effect
            // and chain it with a background-color fade on the container
            // ensure the originalOrder bool gets togged properly for next time
        });
});
</script>

在这里,把动画分成多个步骤,这样就可以将位置变换的代码变得可以通用、重用。swapAnim函数代码如下:

function swapAnim(node1, node2) {
    var posn1 = parseInt(domStyle.get(node1, "left")),
        posn2 = parseInt(domStyle.get(node2, "left"));

    return moveNodes = fx.combine([
        fx.slideTo({
            duration: 1200,
            node: node2,
            left: posn1
        }),
        fx.slideTo({
            duration: 1200,
            node: node1,
            left: posn2
        })
    ]);
}
   slideTo方法使用left样式属性移动各个节点,也可以使用animateProperty实现相同的效果。两个相互独立的动画应该同时播放,这样两个节点可以一起移动。

  fx.combine方法将两个动画合并为一个,返回的动画对象和animateProperty及其它dojo方法类似。当需要播放时,执行play()方法。

// Set up a click handlers to run our animations
on(swapButton, "click", function(evt){

    // chain the swap nodes animation
    // with another to fade out a background color in our container
    var anim = fx.chain([
        swapAnim(c1, c2),
        baseFx.animateProperty({
            node: container,
            properties: {
                backgroundColor: "#fff"
            }
        }),

    ]);
    // before the animation begins, set initial container background
    aspect.before(anim, "beforeBegin", function(){
        domStyle.set(container, "backgroundColor", "#eee");
    });

    // when the animation ends, toggle the originalOrder
    on(anim, "End", function(n1, n2){
        originalOrder = !originalOrder;
    });

    anim.play();
});
在执行fx.combine之前,传递给fx.chain的数组包含两个单独的动画。然后按顺序播放动画,先是node-swap,然后是background-color动画。容器的初始背景色与beforeBegin事件关联。
完整代码:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title></title>
    <script src="../Scripts/dojo/dojo/dojo.js" data-dojo-config="async:true"></script>
    <style type="text/css">
        .box {
            background-color: #ddd;
            border: 1px none #eee;
            height: 200px;
            padding: 5px;
            position: absolute;
            width: 200px;
        }

        .innerBox {
            background-color: white;
            margin: 5%;
            padding: 5px;
        }

        #container {
            height: 300px;
            padding: 10px;
            position: relative;
            width: 450px;
        }

        .contentBox {
            background-color: white;
            border: 1px solid #99c;
            box-shadow: 10px 10px 5px #888;
            margin: 5px;
            position: absolute;
            width: 200px;
        }
    </style>
</head>
<body>
    <button id="swapButton">Swap</button>

    <div class="container" id="container">
        <div id="content1" class="contentBox" style="top: 0; left: 0">
            <div class="innerBox">1: Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident.</div>
        </div>
        <div id="content2" class="contentBox" style="top: 0; left: 250px">
            <div class="innerBox">2: Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.</div>
        </div>
    </div>
    <script>
        require(["dojo/_base/fx", "dojo/fx", "dojo/fx/easing", "dojo/dom-style", "dojo/dom", "dojo/on", "dojo/aspect", "dojo/domReady!"], function (baseFx, fx, easing, domStyle, dom, on, aspect) {
            function swapAnim(node1, node2) {
                var posn1 = parseInt(domStyle.get(node1, "left")),
                    posn2 = parseInt(domStyle.get(node2, "left"));
                return moveNodes = fx.combine([
                    fx.slideTo({
                        duration: 1200,
                        node: node2,
                        left: posn1
                    }),
                     fx.slideTo({
                         duration: 1200,
                         node: node1,
                         left: posn2
                     })
                ]);
            }

            var originalOrder = true; // track which order our content nodes are in
            var swapButton = dom.byId("swapButton"),
                c1 = originalOrder ? dom.byId("content1") : dom.byId("content2"),
                c2 = originalOrder ? dom.byId("content2") : dom.byId("content1"),
                container = dom.byId("container");
            // Set up a click handler to run our animations
            on(swapButton, "click", function (evt) {
                // pass the content nodes into swapAnim to create the node-swapping effect
                // and chain it with a background-color fade on the container
                // ensure the originalOrder bool gets togged properly for next time
                // chain the swap nodes animation
                // with another to fade out a background color in our container
                var anim = fx.chain([
                    swapAnim(c1, c2),
                    baseFx.animateProperty({
                        node: container,
                        properties: {
                            backgroundColor: "#fff"

                        }
                    })
                ]);
                // before the animation begins, set initial container background
                aspect.before(anim, "beforeBegin", function () {
                    domStyle.set(container, "backgroundColor", "#eee");
                });

                // when the animation ends, toggle the originalOrder
                on(anim, "End", function (n1, n2) {
                    originalOrder = !originalOrder;
                });

                anim.play();

            });


        });
    </script>
</body>
</html>


原文地址:Animation








  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值