SuperNinja
SuperNinja

Reputation: 1606

Angularjs: animation service

First off I am using ng-boilerplate, so my dependencies have been declared in my controller.

My directive in HTML is as follows:

<div div-float="logo.left" class="letterhead-widget" id="logo">

I set the value of logo.left to either 'left' or 'false' depending on a ng-click. With the scope.$watch I check the change in the iAttrs.divFloat, whether it's set to 'left' or false. I can log out the newVal when == 'left' Here is where the problem lies as the $animate.addClass(element, 'logoLeft); is not firing and cannot log either 'add' or 'remove'.

Any ideas why my addClass or removeClass is not working for me? I can validate that the .logoLeft is being added and removed, but I take it that's not through the $animation

angular.module('floats', [])

.directive('divFloat', ['$animate', function ($animate) {
    return function (scope, element, iAttrs) {
        // console.log(iAttrs);
        scope.$watch(iAttrs.divFloat, function(newVal){
            if(newVal == 'left'){
                console.log(newVal);
                $animate.addClass(element, 'logoLeft');
            } else {
                $animate.removeClass(element, 'logoLeft');
            }

        });
    };
}])

.animation(".logoLeft", function(){
    return {
        addClass: function(element, className){
            console.log('add');
            // TweenMax.to(element, 0.35 , {opacity:0, display:'none'});
        },
        removeClass: function(element, className){
            console.log('remove');
            // TweenMax.to(element, 0.50 , {delay: 0.35, opacity:1, display:'block'});
        }
    };
});

Update -- Confirmed This directive is causing conflict? How should I go about handling this as I will have multiple directives that I want to interact with $animation

angular.module('fade', [])

.directive('hideMe', [ '$animate', function ($animate) {
    return  function (scope, iElement, iAttrs) {
        scope.$watch(iAttrs.hideMe, function(newValue){
            if(newValue){
                $animate.removeClass(iElement, 'fade');
            } else {
                $animate.addClass(iElement, 'fade');
            }
        });
    };
}])

.animation(".fade", function(){
    return {
        addClass: function(iElement, className){
            TweenMax.to(iElement, 0.35 , {opacity:0, display:'none'});
        },
        removeClass: function(iElement, className){
            TweenMax.to(iElement, 0.50 , {delay: 0.35, opacity:1, display:'block'});
        }
    };
});

Upvotes: 0

Views: 737

Answers (2)

Blake Bowen
Blake Bowen

Reputation: 1049

You need to call done in your animations to remove ng-animate. Without it, Angular still thinks the animation is running.

.animation(".fade", function() {
  return {
    addClass: function(element, className, done) {
      TweenMax.to(element, 0.35, {
        autoAlpha: 0,
        onComplete: done
      });
    },
    removeClass: function(element, className, done) {
      TweenMax.to(element, 0.50, {
        autoAlpha: 1,
        onComplete: done
      });
    }
  };
});

Plunk

http://plnkr.co/edit/wR579YLOAHh2su5WkK4P?p=preview

var app = angular.module("app", ["ngAnimate"])

.controller('MainCtrl', function() {

  var vm = this;
  vm.hide = false;
})

.directive("hideMe", ["$animate",
  function($animate) {
    return function(scope, element, attrs) {
      scope.$watch(attrs.hideMe, function(newValue) {
        if (!newValue) {
          $animate.removeClass(element, "fade");
        } else {
          $animate.addClass(element, "fade");
        }
      });
    };
  }
])

.animation(".fade", function() {
  return {
    addClass: function(element, className, done) {
      TweenMax.to(element, 0.35, {
        autoAlpha: 0,
        onComplete: done
      });
    },
    removeClass: function(element, className, done) {
      TweenMax.to(element, 0.50, {
        autoAlpha: 1,
        onComplete: done
      });
    }
  };
});
.block {
  width: 500px;
  height: 100px;
  background-color: black;
  margin-top: 25px;
}
<script src="http://cdnjs.cloudflare.com/ajax/libs/gsap/1.13.2/TweenMax.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.0-rc.3/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.0-rc.3/angular-animate.min.js"></script>

<div ng-app="app" ng-controller="MainCtrl as vm">
  <button ng-click="vm.hide = !vm.hide">Toggle Hide</button>
  <div class="block" hide-me="vm.hide"></div>
</div>

Upvotes: 1

olefrank
olefrank

Reputation: 6820

You should watch the scope property (specified as a string) instead of the attribute value:

Instead of:

scope.$watch(iAttrs.divFloat, function(newVal){...}

use:

scope.$watch("logo.left", function(newVal){...}

(or what ever you've called the property in your controller)

See this: https://stackoverflow.com/a/14568170/1736012

Upvotes: 0

Related Questions