dojo動畫

在這一節中,你將學習如何運用dojo創建和合並特效爲頁面上的元素定製特效。

網絡的用戶界面,像其他的圖形化用戶界面一樣,需要確保印象,所有的像素和按鈕是連接到我們可以操縱的真實對象上。我們的大腦可以被數碼產品所迷惑。隨着幻想的存在而有虛擬的體驗。當變化的過度是突兀的時候幻想將被識破。動畫的過度讓用戶界面感覺着更加的自然很直覺,可以用來巧妙或不那麼巧妙的改變頁面上的關注點。

在這一節我們將學習dojo 提供的更多的動畫。

讓你修改,建立定製動畫,以符合您的特定的用戶界面的要求。

效果翻轉

我們在前面已經討論過dojo 內置的常用的特效。我們可以淡入淡出元素使用baseFx.fadeInbaseFx.fadeOut(都在dojo/_base/fx模塊中)我們使用fx.slideTofx.wipeIndojo/fx模塊中。我們已經知道如何的向這些方法傳遞參數對象。一個節點屬性,表明我們要實施動畫的地方。

但是元素有無數的屬性伴隨着成組的值以用來設置動畫。

假設我們要閃現背景或者在屏幕上移動節點。

爲此我們需要dojo的通用動畫工具。baseFx.animateProperty

動畫屬性

如果你看了fx.wipeIn的源代碼的話,你將看到基本的樣式:高度屬性被從0增加到他到自動或者自然高度,來看我們如何爲任意的屬性設置動畫。

我們將設置節點border的動畫。

 

<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的寬度屬性,我們這樣調用animateProperty方法

require(["dojo/_base/fx", "dojo/dom", "domReady!"], function(baseFx, dom) {
    baseFx.animateProperty({
        node: dom.byId("anim8target"),
        properties: { borderWidth: 100 }
    }).play();
});

注意:我們使用JavaScript的小謝的駝峯屬性名字:borderWidth

而不是帶有鏈接好的border-width屬性名。我們也傳入了一個節點屬性。但是這次我們使用一個新的'properties'鍵來指明我們要使用動畫的對象。

同樣的原則適用於所有的元素。我們可以有數字值。我們想設置多少就設置多少。

在下面的例子中我們將同時設置距上距右和頭透明度。

逐漸消退的退出道左邊。通過爲每一個提供標準的startend屬性,我們可以創建具體的可重複的動畫。

 

<h3>Demo: animateProperty with multiple style properties</h3>
<button id="dropButton">Drop out block</button>
<button id="ariseSirButton">Return block</button>

<div id="anim8target" class="box" style="top: 100px; left: 300px; background-color: #fc9;width: 200px;height: 200px">
    <div class="innerBox" >A box</div>
</div>

  require(["dojo/_base/fx", "dojo/on", "dojo/dom", "dojo/domReady!"], function(baseFx, on, dom) {
                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){
                    baseFx.animateProperty({
                        node: anim8target,
                        properties: {
                            top: { start: 100, end: 150 },
                            left: 0,
                            opacity: { start: 1, end: 0 }
                        },
                        duration: 800
                    }).play();
                });
                on(ariseSirButton, "click", function(evt){
                    baseFx.animateProperty({
                        node: anim8target,
                        properties: { top: 100, left: 300, opacity: 1 }
                    }).play();
                });
            });


注意我們仍然提供一個duration(持續屬性),這是動畫所要持續的所有的毫秒的值。藉此我們可以看看具體發生了什麼。

 

緩衝

如果我們能夠描繪,動畫生成的值,我們將會看到一個從開始值到結束值得曲線。

曲線所參照的值叫做"easing".最簡單的曲線是一條直線。

例如,以平均的速度從x:0移動到y:100,但是運動看起來更加的自然,當他慢慢的啓動、加快當快要結束時放緩。默認的行爲在很多地方都能用。但是dojo提供一系列的緩衝函數來得到正確的效果和感覺dojo/fx/easing 模塊有一些緩和的曲線我們能夠加載。

<style type="text/css">
                      * {
                          outline: none !important;
                      }
                      body {
                          margin: 0;
                          padding: 2em;
                          font-family: Lucida Sans,Lucida Grande,Arial !important;
                          font-size: 13px !important;
                          background: white;
                          color: #333;
                      }
                      button {
                          -webkit-transition: background-color 0.2s linear;
                          border-radius:4px;
                          -moz-border-radius: 4px 4px 4px 4px;
                          -moz-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.15);
                          background-color: #E4F2FF;
                          background-image: url("http://ajax.googleapis.com/ajax/libs/dojo/1.7.1/dijit/themes/claro/form/images/button.png");
                          background-position: center top;
                          background-repeat: repeat-x;
                          border: 1px solid #769DC0;
                          padding: 2px 8px 4px;
                          font-size:1em;
                      }
                      button:hover {
                          background-color: #AFD9FF;
                          color: #000000;
                      }
                      h1 {
                          font-size:1.5em;
                      }
                          /* Any demo specific styling needed for this tutorial only */
                      .box {
                          position: absolute;
                          height: 200px;
                          width: 200px;
                          background-color: #ddd;
                          border: 1px #eee;
                          padding: 5px;
                      }
                      .innerBox {
                          margin: 5%;
                          padding: 5px;
                          background-color: white;
                      }
                      #container {
                          position: relative;
                          padding: 10px;
                          height: 300px;
                          width: 450px;
                      }
                      .contentBox {
                          background-color: white;
                          position: absolute;
                          width: 200px;
                          border: solid 1px #99c;
                          margin: 5px;

                          -moz-box-shadow: 10px 10px 5px #888;
                          -webkit-box-shadow: 2px 3px 5px #888;
                          box-shadow: 10px 10px 5px #888;
                      }
                  </style>
<script src="http://ajax.googleapis.com/ajax/libs/dojo/1.7.1/dojo/dojo.js"
            data-dojo-config="isDebug: true, async: true">
    </script>
    <script>
        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();
            });
        });
        </script>

<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>
在這個例子中,我們計算視圖窗口的高度。以便我們能夠定位盒子到底部。通過使用easing bounceOut 函數,它到了最下面然後使它飄起來了一點點。在達到最終值之前。
同時要注意,最頂級的屬性是一個擁有開始和結束屬性的對象。他使我們更加的明白邊界值我們想要添加動畫對象的每個樣式屬性。
幾乎所有的緩衝都有名字 “In”或者”Out” 結束。或者兩者都有。例如”InOut”.名字意味着。或者延遲是在開始之後或者是結束之前,或者在動畫的兩頭。

放在一起

傳統的動畫應用一般使用一個時間軸去模型化在那個時期中發生了那些變化。他通常是在同一時間使事物發生變化。就像一個接一個一樣。就像我沒在一前的章節看到的特效一樣。Dojo爲每個提供了一個機制:fx.combinefx.chain

讓我們看看怎麼把多個工件放到一起。

對於此例子:開始時我們有兩個寫有內容的盒子。我們想讓他們交換位置。爲了加重改變,我們還會淡出在他們之後的背景色。

看以下代碼:

<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>

像平常一樣,我們加載dojo,請求想要的模塊。在我們傳入以來的方法中初始化。

 

<script src="http://ajax.googleapis.com/ajax/libs/dojo/1.7.1/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 方法的實現如下:

<script src="http://ajax.googleapis.com/ajax/libs/dojo/1.7.1/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>

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的數組包含兩個獨立的動畫,我們想要連續的運行他們。先是節點交換然後改變背景色動畫化容器初始化背景色是通過鏈接beforeBegin  事件完成的。在onEnd期間,我們有一些記錄要做。當我們點擊按鈕時,節點倒過來了。

 

 

最終的代碼是靈活、合理和易於擴展的。

你需要做背景動畫並列運行交換嗎?

怎樣回覆內容的透明度當他移動到右邊的時候。經常發生的是。最難的一點是知道何時停止。


小結:

Dojo的動畫工具在一般的情況下爲你提供了便利和簡單。對於特定的、定製的轉換過程,你需要自己掌控。動畫可以使用簡單的小的部分建立,提供一組有用的事件生命週期來幫助同步的改變。

在真實世界中,沒有什麼是直接的從一個狀態到另一個狀態,所以掌控移動和視覺改變的能力是很重要的,以用來創建好的用戶體驗。

在以後章節,我們將通過相同行的模式介紹dojo Toolkit :使簡單的事情容易,使難得事情變得有可能。

 

 











發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章