Search code examples
angularjsng-animate

Using AngularJS $animate service to trigger JS defined animations


I'm triggering animations manually through a directive - and it works fine.

element.bind('click', function() {
  $animate.addClass(element, 'my-animation');
});

.animation('.my-animation', function() {
    return {
        addClass: function(element) {
            element.html('<span>Animating</span>');
        }
    }
})

Here's a simple isolated working example in AngularJS 1.2.8: http://plnkr.co/edit/5h5LbkqeL7i38NHSzisq?p=preview

But if I change the Angular version to 1.3+ the animation no longer triggers. I realize that the $animate service has gone through an overhaul and have tried various methods $animate.animate() etc.

Here's the same example failing in 1.3.8: http://plnkr.co/edit/eTB1nmQLcO3nkpbaedqt?p=preview

Is it a bug? Am I daft? Help appreciated :)


Solution

  • This is due to the breaking changes introduced with 1.3.0-RC.0 when the $animate service started to use promises instead of callbacks for animations.

    Few excerpts from the changelog:

    Both the API for the cancallation method and the done callback for $animate animations is different. Instead of using a callback function for each of the $animate animation methods, a promise is used instead.

    ...

    keep in mind that you will still need to run $scope.$apply inside of the then callback to trigger a digest.

    ...

    $animate.addClass, $animate.removeClass and $animate.setClass will no longer start the animation right after being called in the directive code. The animation will only commence once a digest has passed. This means that all animation-related testing code requires an extra digest to kick off the animation.

    As bind is a jQuery/jqLite method it does not trigger the digest loop automatically for you like for example ng-click would.

    To solve your problem simple wrap the code inside the attached event handler in a call to $apply:

    element.bind('click', function() {
      scope.$apply(function() {
        $animate.addClass(element, 'my-animation');
      });
    });
    

    Demo: http://plnkr.co/edit/KTJs71WDLL4OXYmKTaYV?p=preview