博弈AngularJS讲义(12) - 动画

动画

? AngularJS 1.3版本为常用的指令(ngRepeat,ngSwitch,ngView...)提供了动画支持,另外还可以通过$animate组件为自定义的指令提供动画支持。这些动画钩子(hook)将在指令的生命周期内触发基于CSS变换(Transition), CSS Keyframe,或者js回调的动画。添加动画支持需要引入ngAnimate模块(下载附件angular-animate.zip)。

? 下面的例子在ngShow和ngHide上面加入了动画支持:

??

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

? ??

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

? ? 运行结果: 上述sample-show-hide类通过transition控制动画

? ? ?

?


?

工作原理

? ?AngularJS的动画是基于CSS类的。只需在HTML标签上加上CSS类,就可以通过AngularJS在上面实现动画。例如:

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

? ? 我们将基于repeated-item在CSS或者js中实现动画。 ngRepeat指令会在列表每项被加入后给相应的DOM元素添加ng-enter类。但列表项被删除后会在对应的DOM元素上添加ng-leave,在remove过程中的列表项的CSS类为ng-move.

? ? 让我们来看下面的CSS代码,我们会在ng-repeat不同阶段的CSS类中添加transition和keyframe:

? ??

/*
  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; }
}

? ?

? ?我们也可以通过JS控制style:

? ?

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) {}
  }
});

? ?

? ?AngularJS会识别生成的CSS类,自动执行动画。如果CSS和JS代码同时存在,AngularJS会同时执行。

?

基于Class和ngClass的钩子

? ?AngularJS可以在DOM元素添加或者删除CSS类的过程中执行动画。注意只有在相应元素上加上表达式或者ngClass指令,AngularJS才会捕获样式的变化。

? ?让我们看如下实例:

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

? ?运行结果:

? ?

?

?

支持动画的指令

? ?下面的表格中列出了支持动画的指令:

? ?

Directive Supported Animations
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)


?如何在自定义的指令中使用动画

? 可以通过$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‘);
      }
    });
  };
}]);

? 我们将在后续的章节中详解$animate API.

?

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。