3.4 Dojo 特效
原文地址:https://dojotoolkit.org/documentation/tutorials/1.10/effects/index.html
本翻譯項目放在GitBook上,歡迎參與。
GitBook地址:https://www.gitbook.com/book/limeng1900/dojo1-11-tutorials-translation-in-chinese/details
轉載請註明出處:http://blog.csdn.net/taijiedi13/ – 碎夢道
本教程中,我們將探索Dojo提供的特效,它可以讓你的頁面或應用生動起來。
入門
現在爲止,我們已經可以很舒服的從DOM節點來操作DOM和處理事件。但是,在我們執行某些動作時,過渡會非常生硬:移除一個節點讓它從頁面消失,可能會讓用戶迷惑。使用Dojo提供的標準特效,我們可以創建更加平滑的用戶體驗,爲應用添加額外的閃光點。如果我們利用Dojo的dojo/_base/fx
和dojo/fx
可以對這些特效進行連接和組合,進而提供非常炫的動態體驗。
Dojo1.10有兩個
fx
模塊:dojo/_base/fx
和dojo/fx
。
dojo/_base/fx
提供基礎特效方法,之前在Dojo base裏看到過,包括:animateProperty
,anim
,fadeIn
和fadeOut
。
dojo/fx
提供更多高階特效,包括:chain
,combine
,wipeIn
,wipeOut
和slideTo
。
淡入淡出
應用中你可能見過或者用過淡入和淡出。這個 特效很常見,它包含在dojo/_base/fx
的核心特效部分。可以用它來平滑的顯示或隱藏頁面中的元素。請看示例:
<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>
所有的動畫函數都需要一個參數:含屬性的對象。你要用的最重要的屬性是node
屬性:一個DOM節點或一個節點ID字符串。另一個屬性是duration
——動畫的持續時間,以毫秒爲單位,默認爲350毫秒。其他動畫還有別的屬性,不過淡入淡出不需要。
動畫函數返回一個dojo/_base/fx::Animation
對象,它有幾個方法:paly、pause、stop和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>
擦拭特效位於dojo/fx
模塊。本例中,將“wipe”類添加到目標節點。由於wipe函數操作節點內容的高度,“wipe”類將目標節點的高度設爲“auto”。
滑動
目前已經涉及了隱藏節點,但是如果要移動它們呢?淡入淡出和擦拭都不能改變節點的位置。可以用fx.slideTo
。節點的位移可以用來創建頁面上的運動,fx.slideTo
創建一個節點的平滑動畫,通過指定左上角的座標來移動它。
<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>
動畫事件
之前說過所有的動畫方法都返回一個dojo/_base/fx::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){
// Note that we're specifying the beforeBegin as a property of the animation
// rather than using connect. This ensures that our beforeBegin handler
// executes before any others.
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"
});
}
});
// We could have also specified onEnd above alongside beforeBegin,
// but it's just as easy to connect like so
on(anim, "End", function(){
style.set(slideTarget, {
backgroundColor: "blue"
});
}, true);
// Don't forget to actually start the animation!
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
作爲一個參數對象的屬性傳遞。直接原因是在確定在動畫創建的時候就連接beforeBegin
。因此,如果你在動畫創建之後連接beforeBegin
,你的處理器將在動畫的beforeBegin
處理器之後執行,你可能並不想這樣。通過將處理器作爲參數對象屬性傳遞,可以確保你的處理器最先執行。
鏈接
如果我們想要連續播放動畫呢?可以使用之前說過的end
事件來開啓下一個特效,但是不太方便。dojo/fx
提供了幾個方法設置特效順序播放或並行,每個方法都返回一個dojo/_base/fx::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");
// Set up a couple of click handlers to run our chained animations
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/_base/fx::Animation
的play
來開啓鏈式動畫。我們不對每一個獨立特效啓動播放,fx.chain
會進行處理。
組合
dojo/fx
提供的第二個方便的方法是combine
,可以同時開啓多個動畫。在持續最長的動畫結束後,返回的dojo/_base/fx::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");
// Set up a couple of click handlers to run our combined animations
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>
這個例子中,同時進行滑動和淡入淡出。
你可以使用fx.chain
和fx.combine
來創建一些精緻的動畫序列。而且,鏈接和組合都返回一個動畫對象,這些方法還可以進行連接和組合,你就可以用簡單的動畫來創建更加豐富多彩的序列。
小結
使用Dojo可以很容易地爲你的頁面增色。 dojo/_base/fx
and dojo/fx
可以讓你輕易的實現DOM節點的淡入淡出、擦除等,鏈接和組合意味着你可以更快更容易地創建高階動畫。
然而,如果你想要多一些更有難度的事,比如調整一個DOM節點的高但並不一定縮減到零,或者通過動畫變背景顏色?下一節教程fx.animateProperty
會涉及到這些。