Tell ngAnimate to only animate ngShow/ngHide
Asked Answered
S

1

12

I have an AngularJS 1.2.2 web application with a <div> that I show/hide based on some $scope property. Using the ngAnimate module, I animate the showing and hiding of the <div>.

<div id="square" ng-show="showSquare" class="animate-shiny"></div>

I also have a class I want to place on this <div> and for this I use ngClass.

<div id="square" ng-show="showSquare" class="animate-shiny" ng-class="{ cool: extraCool }"></div>

And as it so happens, sometimes that class gets applied at the same moment as when the <div> is shown/hidden. This causes the show/hide animation to not work anymore, apparantly it finds ngClass more interesting to animate, even though I don't want to use ngAnimate for that animation.

Here's a Plnkr that demonstrates the behavior. Clicking the show/hide button works great, clicking the make cool button works great, but the button that combines these two causes the show/hide animation to break.

How do I fix this? And can I do it without manually addressing $animate?

Thanks in advance!

Spicy answered 28/11, 2013 at 8:45 Comment(0)
R
13

The problem is that you are trying to animate using the class and not discriminate between when things should animate. That is, your transition effect applies to the class in general, which ng-animate perceives as having to do work whenever that class is referenced. I modified your css a bit to get pretty close, if not exactly, what you want:

#square {
  width: 50px;
  height: 50px;
  background-color: blue;
  transition: 0.4s all ease-out;
}

#square.cool {
  box-shadow: 0 0 10px 3px green;
  background-color: lightgreen;
}

#square.ng-hide-add, #square.ng-hide-remove
{
  display: block !important; 
}

#square.ng-hide-remove, #square.ng-hide-add.ng-hide-add-active{
  margin-left: -80px;
    opacity: 0;
}

#square.ng-hide-remove.ng-hide-remove-active, #square.ng-hide-add{
  margin-left: 0;
    opacity: 1;
}

Here is the new plunkr so you can play with it: http://plnkr.co/edit/a7wiZfCrEGCXfIDSvF9r?p=preview

If you want to ONLY animate the show/hide and do not want a transition for the color, simply move the transition to the #square.ng-hide-add, #square.ng-hide-remove declaration.

Robillard answered 3/12, 2013 at 21:9 Comment(3)
That is pretty sweet!Thetisa
See the documentation at docs.angularjs.org/api/ngAnimate, section "usage", under the listed directives it says: "You can find out more information about animations upon visiting each directive page." - that is where you can find the directive-specific class names to trigger the more specific animations.Gardell
Although this is usable for me, there's still some weird behavior. If I slow the animation down to four seconds, then show the square (first button) and then apply both changes (last button) I see no animation for the cool effect. My square gets animated using ng-animate, but the .cool class doesn't get applied with animation anymore. I'm not sure why, the transition is defined properly...Spicy

© 2022 - 2024 — McMap. All rights reserved.