Angular 动画

来源:互联网 发布:与吾同在 知乎 编辑:程序博客网 时间:2024/05/29 16:54

原文:https://code.angularjs.org/1.5.0-rc.0/docs/guide/animations

1)、动画

AngularJS 1.3 为常用的directives,例如ngRepeat ngSwitch, 和ngView提供挂钩,通过  $animate service也可以为自定义的directive使用。 这些animation钩子设置在各种directives的生命周期并处触发animations的地方,它会尝试执行一个CSS 过渡、CSS 关键帧Animation或者 JavaScript 回调Animation (依赖于动画处在特定的directive的位置)。 Animations可以使用vanilla CSS占位, 通过遵循Angular JS设置的命名规定或者被定义为factory的时候通过JavaScript 代码。

Animations不可用除非在你的应用里面作为依赖关系包含ngAnimate module。

下面是一个animations例子,通过 ngShow 和 ngHide启用:

index.html

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

animation.css

.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;}

2)、安装

参考 API docs for ngAnimate 关于安装模块的介绍。

你也可能也想设置一个独立的 CSS 文件来定义基于CSS的animations。


3)、如何起作用

Angular JS中的Animations完全基于CSS classes。 只有要你有一个附加到你的网站中HTML element中的CSS class,你可以给它应用animations。 例如我们有一个 HTML template,其中有个repeater像这样:

<div ng-repeat="item in items" class="repeated-item">  {{ item.id }}</div>

可以看到, .repeated-item class存在于将被重复的element,这个class会被用作引用, 在我们应用的CSS应用 或 JavaScript animation 代码,来告知AngularJS执行一个animation。

因为ngRepeat所做的事, 每次一个新子项会被加进列表,ngRepeat 会增加一个 ng-enter class 名到将被添加的element。 当移除后它会应用 ng-leave class 名,而当围绕它移动的时候会应用一个 ng-move class 名。

来看下下面的 CSS code,我们可以看到一些过渡和关键帧动画代码,设置为每个那些事件会当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; }}


也可以使用Javascript代码来对animation同样的操作 (为了执行animations,用到了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 class 名字存在于 element时, AngularJS 自动指出是否执行CSS 或 JavaScript animation。若CSS 和JavaScript animation 代码都存在,并匹配 element上的CSS class 名字,然后 AngularJS 会同时都运行所有animations。

4)、Class和ngClassanimation hooks

AngularJS也注意到因触发 add 和remove hooks而引起的elements的CSS class变化。这意味着如果一个CSS class 从一个element中添加或移除,然后一个animation会在addition 或removal 之前被执行。(牢记 AngularJS 只能在element中用到了 expression 或者 ng-class directive,才会捕捉 class 变化。)

下面例子展示了怎样在变化中执行animations:

index.html

<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>style.css.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;}

虽然 CSS比下面看到的难一点,但点子是一样的。

5)、哪些directives支持animations?

少数常用AngularJS directives 支持并触发 animation hooks,只要任何主事件在其生命周期发生。下表详细解释了什么animation事件会被触发。

DirectiveSupported AnimationsngRepeatenter, leave, and movengViewenter and leavengIncludeenter and leavengSwitchenter and leavengIfenter and leavengClass oradd and removengShow & ngHideadd and remove (the ng-hide class value)

每个animation事件中,完整分解的调用步骤,参考 API docs。

6)、在自己的directives中怎么使用animations?

Animations 在自定义directives中也能建立在直接注入 $animate 到 directive 基础上,并在需要的时候调用就行。

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');      }    });  };}]);

7)、animations开始前防止抖动

当内置带structural  animations 例如 ngIf elements到那些类基于animations的elements例如ngClass, 有时在真实动画开始前发生短暂抖动或者在animated element 短暂可见的地方有内容闪烁。

为了避免如此,你可以在ng-[event]-prepare class应用样式,一旦animation初始化之后就会被添加,但在真实动画开始之前会被移除(等待 $digest过后。 这个class进给 structural animations (enter, move,和leave)添加。

这个例子你可能见到抖动:

<div ng-class="{red: myProp}">  <div ng-class="{blue: myProp}">    <div class="message" ng-if="myProp"></div>  </div></div>

可以在 enter 事件中, .message div 会在动画开始前短暂可见。那个例子,你可以增加样式到CSS,为了确保 element在animation开始前保持隐藏:

.message.ng-enter-prepare {  opacity: 0;}/* Other animation styles ... */

8)、更多animations有关内容

关于 $animate每个可用method的完整分解,参考 API documentation。

要看完整演示,参考 animation step within the AngularJS phonecat tutorial。

0 0
原创粉丝点击