AngularJS入门之动画

AngularJS中ngAnimate模块支持动画效果,但是ngAnimate模块并未包含在AngularJS核心库中,因此需要使用ngAnimate需要在定义Module时声明对其的引用。

AngularJS中实现动画效果有两大种方式:

  • 基于CSS的动画效果
    • CSS Transition Animation
    • CSS Class-based Animation
  • 基于Javascript的动画效果

 

官方给出的能支持动画效果的Directives:

DirectiveSupported Animations
ngRepeat enter, leave and move
ngView enter and leave
ngInclude enter and leave
ngSwitch enter and leave
ngIf enter and leave
ngClass add and remove (the CSS class(es) present)
ngShow & ngHide add and remove (the ng-hide class value)
form & ngModel add and remove (dirty, pristine, valid, invalid & all other validations)
ngMessages add and remove (ng-active & ng-inactive)
ngMessage enter and leave

 

基于CSS的动画效果:

1. CSS Transition Animation

示例1(官方Demo):

 1 <!DOCTYPE>
 2 <html>
 3 <head>
 4     <style type="text/css">
 5         /* 开始时的样式 */
 6         .fade.ng-enter {
 7             transition: 5s linear all; /* 当使用css transition实现动画效果时,在开始时的样式中必须包含transition的设置 */
 8             opacity: 0;
 9         }
10 
11             /* 结束时的样式 */
12             .fade.ng-enter.ng-enter-active {
13                 opacity: 1;
14             }
15     </style>
16 
17     <script src="/Scripts/angular.js"></script>
18     <script src="/Scripts/angular-animate.js"></script>
19     <script type="text/javascript">
20         (function () {
21             var app = angular.module('cssBasedAnimationTest', ['ngAnimate']);
22         })();
23     </script>
24 </head>
25 <body ng-app="cssBasedAnimationTest">
26     <div ng-if="bool" class="fade">
27         Fade me in out
28     </div>
29     <button ng-click="bool=true">Fade In!</button>
30     <button ng-click="bool=false">Fade Out!</button>
31 </body>
32 </html>

注意:使用CSS Transition时,ng-EVENT(动画开始前的样式)和ng-EVENT-active(动画执行完毕后的样式)这两组样式必须同时出现,且在ng-EVENT中必须包含transition的设置。

 

本篇开头提到过,AngularJS核心库并不包含ngAnimate模块,因此我们首先需要在定义Module时,添加对ngAnimate模块引用的声明:

var app = angular.module('cssBasedAnimationTest', ['ngAnimate']);

 

使用ngIf(ng-if)来控制class="fade"的元素是否加载到DOM:

<div ng-if="bool" class="fade">

注意:ngIf和ngShow/ngHide不同,ngIf在元素隐藏时DOM中并没有该元素,而使用ngShow/ngHide时元素依然存在于DOM中。

 

点击"Fade In!"按钮时,加载div到DOM并触发enter,AngularJS对元素自动添加ng-enter和ng-enter-active的样式,并从ng-enter到ng-enter-active执行样式转换。为了能看清过程,我们将ng-enter中的过渡时间设置为5s,点击"Fade In!"按钮后观察Html的变化。

Step 1(点击前,如前面所说,ngIf在触发前,DOM中并没有div):

 

Step 2(点击按钮后,AngularJS自动添加了ng-animate、ng-enter、ng-enter-active这三个动画相关的样式名,并由ngAnimate模块执行动画效果):

 

Step 3(动画执行完后,示例中是5s后,ng-animate、ng-enter、ng-enter-active被移除,div的状态为ng-enter-active中指定的状态):

 

另外一种CSS transition的方法是使用CSS的Keyframe关键字,对于示例1中样式文件可改为如下:

 1 <style type="text/css">
 2     /* 开始时的样式,使用keyframes不需要定义结束时的样式 */
 3     .fade.ng-enter {
 4         animation: my_fade_animation 0.5s linear;
 5         -webkit-animation: my_fade_animation 0.5s linear;
 6     }
 7 
 8     @keyframes my_fade_animation {
 9         from {
10             opacity: 0;
11         }
12 
13         to {
14             opacity: 1;
15         }
16     }
17 
18     @-webkit-keyframes my_fade_animation {
19         from {
20             opacity: 0;
21         }
22 
23         to {
24             opacity: 1;
25         }
26     }
27 </style>

这种写法中是不需要ng-EVENT-active的。

 

2. CSS Class-based Animation:

Class-based Animation即为通过ngClass、ngShow、ngHide等Directives执行动画效果。  

示例2:

<!DOCTYPE>
<html>
<head>
    <style type="text/css">
        .fade.ng-hide {
            transition: 3s linear all;
            opacity: 0;
        }

        .fade.ng-show {
            transition: 3s linear all;
            opacity: 1;
        }
    </style>

    <script src="/Scripts/angular.js"></script>
    <script src="/Scripts/angular-animate.js"></script>
    <script type="text/javascript">
        (function () {
            var app = angular.module('cssClassBasedAnimationTest', ['ngAnimate']);
        })();
    </script>
</head>
<body ng-app="cssClassBasedAnimationTest" ng-init="bool=true">
    <div ng-show="bool" class="fade">
        This is ng-show.
    </div>
    <div ng-hide="bool" class="fade">
        This is ng-hide.
    </div>
    <button ng-click="bool=!bool">Toggle</button>
</body>
</html>

本例改自官方Demo,除了官方Demo中有点问题之外,另外我自己添加了.fade.ng-show以及两个div分别使用ng-show和ng-hide两个属性。为了能看清Html的变化,动画过渡时间也设置成了3s。

图1:

 

图2:

 

实际观察Html的变化,无论是ngShow还是ngHide,其实都是在隐藏元素时,默认添加ng-hide-animate、ng-hide-add、ng-hide-add-active样式。也就是针对像ngHide、ngShow等这些可以感知动画的Directives,由AngularJS的ngAnimate模块自动添加了CSS Transition动画。

ngAminate能检测的行为是样式的add或者remove, 那如何显式的指定add和remove的样式呢?

示例3(官方Demo):

 1 <!DOCTYPE>
 2 <html>
 3 <head>
 4     <style type="text/css">
 5         .highlight {
 6             transition: 3s linear all;
 7         }
 8 
 9             .highlight.on-add {
10                 background: white;
11             }
12 
13             .highlight.on {
14                 background: yellow;
15             }
16 
17             .highlight.on-remove {
18                 background: black;
19             }
20     </style>
21 
22     <script src="/Scripts/angular.js"></script>
23     <script src="/Scripts/angular-animate.js"></script>
24     <script type="text/javascript">
25         (function () {
26             var app = angular.module('cssClassBasedAnimationTest', ['ngAnimate']);
27         })();
28     </script>
29 </head>
30 <body ng-app="cssClassBasedAnimationTest" ng-init="bool=true">
31     <div ng-class="{on:onOff}" class="highlight">
32         Highlight this box
33     </div>
34     <button ng-click="onOff=!onOff">Toggle</button>
35 </body>
36 </html>

 

我们让ng-class随着点击Toggle按钮变化,当onOff=true时样式on会被ngAnimate执行on-add的过程,反之则执行on-remove的过程。由于显式指定了样式,当我们运行示例3时,这个过程就一目了然了。

  

基于Javascript的动画效果:

使用基于Javascript的动画效果可以让你在脚本中使用其他的Service甚至引用第三方的脚本进行动画的制作,使动画效果更丰富多变。

与基于CSS的动画效果相似,基于Javascript的动画效果也会由AngularJS自动添加一些指定的样式到元素上,但基于Javascript的动画效果还需要使用module.animation()添加动画脚本。

 

示例4:

 1 <!DOCTYPE>
 2 <html>
 3 <head>
 4     <script src="/Scripts/angular.js"></script>
 5     <script src="/Scripts/angular-animate.js"></script>
 6     <script src="/Scripts/jquery-1.9.1.js"></script>
 7     <script type="text/javascript">
 8         (function () {
 9             var app = angular.module('javascriptBasedAnimationTest', ['ngAnimate']);
10 
11             app.animation('.slide', [function () {
12                 return {
13                     enter: function (element, doneFn) {
14                         jQuery(element).fadeIn(1000, doneFn);
15                     },
16 
17                     move: function (element, doneFn) {
18                         jQuery(element).fadeIn(1000, doneFn);
19                     },
20 
21                     leave: function (element, doneFn) {
22                         jQuery(element).fadeOut(1000, doneFn);
23                     }
24                 }
25             }]);
26 
27             app.controller('myController', ['$scope', function ($scope) {
28                 $scope.students = ["Tom","Jack","Alice","May","Thomas"];
29             }]);
30         })();
31     </script>
32 </head>
33 <body ng-app="javascriptBasedAnimationTest" ng-controller="myController">
34     <div ng-if="isshow" ng-repeat="stu in students" class="slide">
35         {{ stu }}
36     </div>
37     <input type="button" value="Toggle" ng-click="isshow=!isshow" />
38 </body>
39 </html>

注:本例为了便于实现js的动画效果引入了jQuery。

 

示例4中,我们对class='slide'的元素的AngularJS中的默认行为添加了动画行为,当使用ngIf让元素enter或者remove时,将触发动画效果。

关于更复杂的对象,也可参考参考资料中提到的AngularJS Hub的例子,本文就不展开了。

 

参考资料

AngularJS官方文档:https://docs.angularjs.org/api/ngAnimate

ngAnimate:http://www.nganimate.org/

AngularJS Hub: http://www.angularjshub.com/examples/animations/javascriptanimations/

posted @ 2015-06-01 09:05  无上@诀  阅读(4685)  评论(1编辑  收藏  举报