2016年4月23日 星期六

dojo/fx

dojo/fx

簡介

dojo/fx 是架構於 dojo/_base/fx 之上的另一個動畫模組,擴充了 dojo 在動畫上的另一些功能。 這些額外的動畫函式基本上都是由 dojo/_base/fx 中的 animateProperty() 函式所實作,只是另外提供一個常用動畫函式的簡式介面罷了,所需傳入的參數和 animateProperty() 一樣,如果不熟悉傳入參數的格式,可以看 dojo/_base/fx 這篇。dojo/fx 模組所提供的動畫函式有:

wipeIn()
將元件由上至下慢慢顯示,顯示前不佔螢幕位置,顯示後佔螢幕位置。
wipeOut()
將元件由下至上慢慢消失,消失後不佔螢幕位置。
slideTo()
將元件滑動至指定位置。
chain()
將數個動畫串接,依序執行;串接的動畫可以作用在不同的元件上。
combine()
將數個動畫組合,同時執行;組合的動畫可以作用在不同的元件上。

wipeIn() & wipeOut()

先介紹 wipeIn() 和 wipeOut() 兩個函式。wipeIn() 和 wipeOut() 這兩個動畫函式,其功能和使用條件及使用方式都有相當的限制。個人覺得,如果需要類似的動畫效果,實在不如自己用 animateProperty() 寫一個,用起來也許會方便一些。首先,這兩個函式基本上沒有辦法處理元件的 padding 屬性,如果元件中有定 padding 屬性的值,在動畫時顯示的效果就很奇怪。使用 wipeIn() 時,會突然出現上下 padding 總和的高度,然後再慢慢出現其它的部份,還會超出上下 padding 的高度總合,最後才回縮到正常的高度。使用 wipeOut() 時,會先從元件的下方伸長上下 padding 高度的總和,然後再開始慢慢的消失。總歸一句,如果要用 wipeIn() 和 wipeOut() 這兩個動畫函式的元件就不要定 padding 的屬性。如果用在沒有文字的影象圖片上,也不要用 padding 設定,這兩個函式就還可以用。

其次,wipeIn() 函式的要求和限制更大,它不能指定出現後的高度,元件內容佔據多大的高度,元件最終就只能有這個高度,沒得商量。但在範例中,所看到 在執行完 wipeIn() 後,方塊的高度卻沒有因為內容而縮小,這是因為在 CSS 類別中定義了 display:flex;fles:none; 的原故,如果隔隣的方塊還在,所有的方塊便會維持一樣的高度,如果隔隣的方塊不在,就成了內容的高度,這是意外的發現。很神奇,不是嗎?不過再神奇,也救不了它不支援 padding 設定的事實。再其次,要使用 wipeIn() 函式的元件,得使用 display:none; 的設定,讓它一開始時不會出現在螢幕上,這個設定一定要設在元件的樣式裡,不能設定在元件的 CSS 類別中,不然該元件永遠不會出現在螢幕上。這是因為 wipeIn() 會去修改元件的 display 屬性值,將 display 的設定取消,好讓它顯示在螢幕上,如果 display:none; 是設在 CSS 類別中,WipeIn() 函式就改不到,而元件也永遠不會有露臉的機會了。

wipeIn() 及 wipeOut() 都是透過改變元件的 height 屬性值來逹到動畫的效果。在呼叫完這兩個函式後,元件的 height 屬性值,不論原先設定為何,在函式執行完畢後, height 的值都會被設定為 auto。如果後續還要對該元件做動畫處理,這點得特別注意。

slideTo()

這個功能可以移動元件在螢幕上的位置,但位置坐標是以視野 (viewport) 的絕對位置來設定。不論先前的設定為何,在呼叫完 slideTo() 之後,display 的值都會被改成 absolute。同時 top 和 left 的值都會設成移動過後的坐標。原先元件所在的位置會空出來。

範例

範例中建立三個按鈕及三個 <div>,一個用來展示 wipeIn(),一個用來展示 wipeOut()。二個 <div>都沒有設定 padding 屬性。下方的一個用來展示 slideTo(),這個沒有設定 margin,比較容易看到移動到逹的位置,在按下 Slide To 按鈕後,下方的方塊會移到流覽器的左角,top=0 及left=0 的地方。同時,最下方的水平分隔線會上移,因為此時方塊的元件樣式被改成 style="display:absolute; top=0; left:0"。 還有三條水平分隔線,用來觀察元件顯示前及消失前後,是否佔據螢幕空間。下圖為執行時的起始狀能。

CSS

<style>
html {
    width:100%;
    height:100%;
}
body {
    margin: 0 auto;
    width:1000px;
    height:100%;
    padding-top:20px;
}
.boxContainer {
    display:flex;
}
.box {
    margin: 10px;
    width:100px;
    height:100px; 
}
.out {
    flex:none;
    background-color: skyblue;
}
.in {
    flex:none;
    background-color: lightgreen;
}
.slide {
    margin:0px;
    flex:none;
    background-color: coral;
}
</style>

.out{} 及 .in{} 分別設定兩個 <div> 的外觀屬性,不設 padding 值。.slide{} 設定第三個 <div> 的外觀屬性,margin 值設定為 0。flex 值都設定為 none,以保持方塊的高度和寬度。

HTML

<body class="claro">
    
    
    
    
Here is some text

I can slide!

</body>

注意第 8 行,將 display:none; 設在元素的樣式裡。

Script

<script>
require([
    "dojo/parser",
    "dojo/ready",
    "dojo/dom-style",
    "dojo/fx",
    "dojo/on",
    "dijit/registry"
    ], 
function(
    parser,
    ready,
    style,
    fx,
    on,
    registry
){
    parser.parse();
    ready(1, function(){
        // both wipeIn() and wipeOut() can not handle padding attribute
        // After wipeOut(), element's attributes value - height:"auto"
        registry.byId("wipeOut").on("click", function(){
            fx.wipeOut({
                node:"outBox",
                duration: 3000
            }).play();
        });
        // After wipeIn(), element's attributes value - height:"auto"
        // to hide the element before calling wipeIn(), the display:none must be set in the
        // element's style, setting in the CSS class will cause element not display
        registry.byId("wipeIn").on("click", function(){
            fx.wipeIn({
                node:"inBox",
                duration:3000
            }).play();
        });
        registry.byId("slideTo").on("click", function(){
         fx.slideTo({
         node:"slideBox",
                top:0,
                left:0,
                unit:"px",
                duration:3000
            }).play();
        });
    });
});
</script>

程式就將三個按鈕設定在點按後呼叫對應的函式執行動畫,將動畫執行旳時間設定為 3 秒,其它也沒什麼需要解釋的了。

沒有留言:

張貼留言