Merge afb-client
[src/app-framework-demo.git] / afb-client / bower_components / foundation-apps / js / angular / services / foundation.core.animation.js
diff --git a/afb-client/bower_components/foundation-apps/js/angular/services/foundation.core.animation.js b/afb-client/bower_components/foundation-apps/js/angular/services/foundation.core.animation.js
new file mode 100644 (file)
index 0000000..535798a
--- /dev/null
@@ -0,0 +1,129 @@
+(function() {
+  'use strict';
+
+  angular.module('foundation.core.animation', [])
+    .service('FoundationAnimation', FoundationAnimation)
+  ;
+
+  function FoundationAnimation() {
+    var animations = [];
+    var service = {};
+
+    var initClasses        = ['ng-enter', 'ng-leave'];
+    var activeClasses      = ['ng-enter-active', 'ng-leave-active'];
+    var activeGenericClass = 'is-active';
+    var events = [
+      'webkitAnimationEnd', 'mozAnimationEnd',
+      'MSAnimationEnd', 'oanimationend',
+      'animationend', 'webkitTransitionEnd',
+      'otransitionend', 'transitionend'
+    ];
+
+    service.animate = animate;
+    service.toggleAnimation = toggleAnimation;
+
+    return service;
+
+    function toggleAnimation(element, futureState) {
+      if(futureState) {
+        element.addClass(activeGenericClass);
+      } else {
+        element.removeClass(activeGenericClass);
+      }
+    }
+
+    function animate(element, futureState, animationIn, animationOut) {
+      var timedOut = true;
+      var self = this;
+      self.cancelAnimation = cancelAnimation;
+
+      var animationClass = futureState ? animationIn: animationOut;
+      var activation = futureState;
+      var initClass = activation ? initClasses[0] : initClasses[1];
+      var activeClass = activation ? activeClasses[0] : activeClasses[1];
+      //stop animation
+      registerElement(element);
+      reset();
+      element.addClass(animationClass);
+      element.addClass(initClass);
+
+      element.addClass(activeGenericClass);
+
+      //force a "tick"
+      reflow();
+
+      //activate
+      element[0].style.transitionDuration = '';
+      element.addClass(activeClass);
+
+      element.one(events.join(' '), function() {
+        finishAnimation();
+      });
+
+      setTimeout(function() {
+        if(timedOut) {
+          finishAnimation();
+        }
+      }, 3000);
+
+      function finishAnimation() {
+        deregisterElement(element);
+        reset(); //reset all classes
+        element[0].style.transitionDuration = '';
+        element.removeClass(!activation ? activeGenericClass : ''); //if not active, remove active class
+        reflow();
+        timedOut = false;
+      }
+
+
+      function cancelAnimation(element) {
+        deregisterElement(element);
+        angular.element(element).off(events.join(' ')); //kill all animation event handlers
+        timedOut = false;
+      }
+
+      function registerElement(el) {
+        var elObj = {
+          el: el,
+          animation: self
+        };
+
+        //kill in progress animations
+        var inProgress = animations.filter(function(obj) {
+          return obj.el === el;
+        });
+        if(inProgress.length > 0) {
+          var target = inProgress[0].el[0];
+
+          inProgress[0].animation.cancelAnimation(target);
+        }
+
+        animations.push(elObj);
+      }
+
+      function deregisterElement(el) {
+        var index;
+        var currentAnimation = animations.filter(function(obj, ind) {
+          if(obj.el === el) {
+            index = ind;
+          }
+        });
+
+        if(index >= 0) {
+          animations.splice(index, 1);
+        }
+
+      }
+
+      function reflow() {
+        return element[0].offsetWidth;
+      }
+
+      function reset() {
+        element[0].style.transitionDuration = 0;
+        element.removeClass(initClasses.join(' ') + ' ' + activeClasses.join(' ') + ' ' + animationIn + ' ' + animationOut);
+      }
+    }
+  }
+
+})();