點擊查看AngularJS系列目錄
轉載請注明出處:http://www.cnblogs.com/leosx/
在AngularJS 1.3 中,給一些指令(eg: ngRepeat,ngSwitch, ngView等)提供了一個動畫的鈎子,也就是說,這些指令可以使用 $animate 動畫服務(是一個服務哦,可以注入到controller里面去)。 這些動畫鈎子可以再整個指令的生命周期中隨着各種指示,觸發等進行動作,顯示動畫效果,我們可以使用HTML5的各種動畫效果,類似 Transition,Keyframe,或者回調函數(這取決於是否給指令配置了動畫)。如果在一個factory工廠方法中,使用AngularJS或者Javascript代碼定義,設置了規范的命名空間了的時候,就可以使用動畫了(這句話感覺翻譯的有問題,忘指點迷津…)。
如果你的應用程序沒有依賴於 ngAnimate 模塊的話,你的所有動畫都是沒有用的。
下面我們來看一下一個使用 ngShow 和 ngHide 進行顯示隱藏的動畫:
<style> .sample-show-hide { padding:10px; border:1px solid black; background:white; } .sample-show-hide { -webkit-transition:all linear 0.5s; transition:all linear 0.5s; } .sample-show-hide.ng-hide { opacity:0; } </style> <div ng-app> <div ng-init="checked=true"> <label> <input type="checkbox" ng-model="checked" style="float:left; margin-right:10px;"> Is Visible... </label> <div class="check-element sample-show-hide" ng-show="checked" style="clear:both;"> Visible... </div> </div> </div>
效果圖:
安裝動畫模塊
可以查看動畫模塊來查看如何安裝。
它們是怎么樣工作的
在AngularJS中的動畫,完全是基於css 樣式類的。所以你首先得有這樣動畫class。我們還是來看看例子吧!
<div ng-repeat="item in items" class="repeated-item"> {{ item.id }} </div>
我們看看 ngRepeat,它會重復 items里面的每一個元素,生成一個這個模板的副本,對於每一個副本元素的增加,Angualr都會在該元素上增加一個名為ng-enter 的 class 樣式,當這個元素被刪除的時候,會增加一個 ng-leave的 class樣式,當你移動這個元素的時候,它就會增加一個ng-move的 class 類樣式。
我們來看看下面的css代碼,我們可以看到它使用了CSS3的一些過度,關鍵幀,變幻等動畫效果。而且它們的觸發時間呢,比較需要注意,可以看到,它們的觸發時間是當你使用了 ngRepeat之后,會出現上面一段我們說到的那幾個樣式來進行觸發的。代碼如下:
/*
We're using CSS transitions for when
the enter and move events are triggered
for the element that has the .repeated-item
class
*/
.repeated-item.ng-enter, .repeated-item.ng-move {
-webkit-transition:0.5s linear all;
-moz-transition:0.5s linear all;
-o-transition:0.5s linear all;
transition:0.5s linear all;
opacity:0;
}
/*
The ng-enter-active and ng-move-active
are where the transition destination properties
are set so that the animation knows what to
animate.
*/
.repeated-item.ng-enter.ng-enter-active,
.repeated-item.ng-move.ng-move-active {
opacity:1;
}
/*
We're using CSS keyframe animations for when
the leave event is triggered for the element
that has the .repeated-item class
*/
.repeated-item.ng-leave {
-webkit-animation:0.5s my_animation;
-moz-animation:0.5s my_animation;
-o-animation:0.5s my_animation;
animation:0.5s my_animation;
}
@keyframes my_animation {
from { opacity:1; }
to { opacity:0; }
}
/*
Unfortunately each browser vendor requires
its own definition of keyframe animation code...
*/
@-webkit-keyframes my_animation {
from { opacity:1; }
to { opacity:0; }
}
@-moz-keyframes my_animation {
from { opacity:1; }
to { opacity:0; }
}
@-o-keyframes my_animation {
from { opacity:1; }
to { opacity:0; }
}
當然,如果你要兼容IE什么的,你也可以使用JQuery去實現這些動畫效果,對吧,看看下面代碼:
myModule.animation('.repeated-item', function() {
return {
enter : function(element, done) {
element.css('opacity',0);
jQuery(element).animate({
opacity: 1
}, done);
// optional onDone or onCancel callback
// function to handle any post-animation
// cleanup operations
return function(isCancelled) {
if(isCancelled) {
jQuery(element).stop();
}
}
},
leave : function(element, done) {
element.css('opacity', 1);
jQuery(element).animate({
opacity: 0
}, done);
// optional onDone or onCancel callback
// function to handle any post-animation
// cleanup operations
return function(isCancelled) {
if(isCancelled) {
jQuery(element).stop();
}
}
},
move : function(element, done) {
element.css('opacity', 0);
jQuery(element).animate({
opacity: 1
}, done);
// optional onDone or onCancel callback
// function to handle any post-animation
// cleanup operations
return function(isCancelled) {
if(isCancelled) {
jQuery(element).stop();
}
}
},
// you can also capture these animation events
addClass : function(element, className, done) {},
removeClass : function(element, className, done) {}
}
});
當這些CSS樣式或者Javascript代碼被添加到了元素上以后,AngularJS會自動的在對應的觸發器中執行力的CSS樣式,或者JavaScript代碼的。 如果既有CSS,也有JavaScript代碼,並且CSS樣式名已經在元素上能匹配到了了,那么AngularJS會讓兩個動畫同時執行的。
Class 類樣式和 ngClass 動畫鈎子
AngularJS也有自己的動畫鈎子,這樣的話,我們就可以根據元素的觸發器,去添加或者移除動畫鈎子,也就是相當於如果CSS樣式類存在的話,就會把這些動畫樣式應用於這個元素上。但是有個前提,那就是這個元素是在AngularJS應用程序中的,也就是受AngularJS控制的才行! 不然依然是不會有動畫效果的。
我們還是來一個例子來看看效果吧!
<style> .css-class-add, .css-class-remove { -webkit-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s; -moz-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s; -o-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s; transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s; } .css-class, .css-class-add.css-class-add-active { color: red; font-size:3em; } .css-class-remove.css-class-remove-active { font-size:1.0em; color:black; } </style> <p> <input type="button" value="set" ng-click="myCssVar='css-class'"> <input type="button" value="clear" ng-click="myCssVar=''"> <br> <span ng-class="myCssVar">CSS-Animated Text</span> </p>
點擊set按鈕效果:
點擊Clear按鈕的效果如下:
哪些指令支持動畫呢?
有少數常見的AngularJS指令是支持和觸發動畫鈎子的。下表詳細解釋這些動畫:
指令 | 支持的動畫 |
ngRepeat | enter, leave, and move |
ngView | enter and leave |
ngInclude | enter and leave |
ngSwitch | enter and leave |
ngIf | enter and leave |
ngClass or | add and remove |
ngShow & ngHide | add and remove (the ng-hide class value) |
對於每個指令指令的動畫的詳細介紹的話,請參考API文檔.
我們怎么在我們自定義的指令中使用動畫呢?其實比較簡單,你只需要在你創建指令的工廠中,注入 $animate 到工廠中,然后你在你的指令中,就可以使用了。
myModule.directive('my-directive', ['$animate', function($animate) {
return function(scope, element, attrs) {
element.on('click', function() {
if(element.hasClass('clicked')) {
$animate.removeClass(element, 'clicked');
} else {
$animate.addClass(element, 'clicked');
}
});
};
}]);