ng-animate with ng-class directive
Asked Answered
S

2

22

You can use ng-animate with ng-class with the add and remove animations. I'm looking to make one animation in CSS3 but haven't found good examples with ng-class online. So I was wondering if people have good examples they want to share.

I am not sure what my final animation will look like, but for the purpose of this example let's say I just want to make the height of the div gradually increase when I add the class myclass.

 <div ng-class="{{myclass:scopeVar}}" ng-animate="?????"></div>

**CSS**

.myclass.ng-add{??}
.myclass.ng-add-active{??}
.myclass.ng-remove{??}
.myclass.ng-remove-active{??}
Showalter answered 21/1, 2014 at 14:51 Comment(2)
Check my answer here: #21072168Lection
There's been a change in the way ngAnimate works from Angular 1.2 onwards. Look it all up here. yearofmoo.com/2013/08/…Hulk
I
28

Animating an ng-class addition or removal using CSS transition has 3 stages. The order of these stages are very important, I almost spent a day figuring out why a simple animation wasn't working due incorrect understanding of the order in which classes are added.

Stage 1:

classname-add/classname-remove class is added.

Unlike what someone might think, this is actually added before the class is added to/removed from the element.

This is the stage where we should add the transition property 1 as well as initial state of our animation.

Stage 2:

classname class is added or removed.

This is where you specify the eventual styles of the element. This class often has nothing to do with our animation. Remember that we are animating the addition/removal of this class. This class itself shouldn't even need to be aware that there is an animation taking place around it.

Stage 3:

classname-add-active/classname-remove-active class is added.

This is added after the class is added to/removed from the element.

This is the stage where we should specify the final state of our animation.


To see this in action, let's create a classic fade-in-out animation shown when an element's selected state changes (selected class change using ng-class).

angular.module('demo', ['ngAnimate'])
  .controller('demoCtrl', function($scope) {
    $scope.selected = false;
    $scope.selectToggle = function() {
      $scope.selected = !$scope.selected;
    };
  });
.item {
  width: 50px;
  height: 50px;
  background: grey;
}
.item.selected {
  /* this is the actual change to the elment
   *  which has nothing to do with the animation
   */
  background-color: dodgerblue;
}
.item.selected-add,
.item.selected-remove {
  /* Here we specify the transition property and
   * initial state of the animation, which is hidden 
   * state having 0 opacity
   */
  opacity: 0;
  transition: opacity 3s;
}
.item.selected-add-active,
.item.selected-remove-active {
  /* Here we specify the final state of the animation,
   * which is visible having 1 opacity
   */
  opacity: 1;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.7/angular.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.7/angular-animate.js"></script>
<div ng-app="demo" ng-controller="demoCtrl">
  <div class="item" ng-class="{selected:selected}"></div>
  <br>
  <br>
  <button ng-click="selectToggle();">
    {{selected? 'Unselect' : 'Select'}}
  </button>
</div>

1 Why should I specify the transition in the first state, instead of just adding it to the class being toggled or a static selector on the element?, you ask.

Well to explain this, assume you need a one-directional animation, for example a fade-out animation when a fade-out class is added.

If you add transition property on the fade-out class itself, the transition stays on the element even after the animation. Which means when your final state (fade-out-add-active) is removed, the element will slowly fade-in back, so we get a fade-out-fade-in which is not what we wanted.

Idiocy answered 30/6, 2016 at 12:7 Comment(0)
S
14

I've found a solution to this problem so I thought I'd share it.

http://jsfiddle.net/nicolasmoise/XaL9r/1/

What's nice about this one is that it only requires two CSS classes. You can directly insert the CSS3 transition property into your base class. Unlike other ng-animate cases, I believe all the animations are done in CSS3 (no messing with the DOM like with animations with ng-include etc...).

I want to thank Ilan Frumer for the link to his answer. His solution was for animation with ng-show which is very similar but a little different from animations with ng-class. Hence why I decided to post my example.

Showalter answered 3/2, 2014 at 20:36 Comment(6)
This doesn't make any use of ng-animate, thoughChangchangaris
There's no need really, using just CSS3 animations and ng-class you could achieve snappy animations.Showalter
The new ng-animate (1.2.0 + I think) is mostly driven by CSS3 animations, there is a Javascript alternative tooShowalter
What? I don't even see your answerShowalter
This is nice, but can anything be done about the flicker on click?Nathalia
@Showalter "There's no need really," - actually it's required when the current state of the element is not the initial state of your animation, also when the final state of your animation is not the final state of your element.Idiocy

© 2022 - 2024 — McMap. All rights reserved.