UNPKG

foundation-apps

Version:

A responsive, Angular-powered framework for web apps from ZURB.

147 lines (117 loc) 3.9 kB
(function() { 'use strict'; angular.module('foundation.core.animation', []) .service('FoundationAnimation', FoundationAnimation) ; FoundationAnimation.$inject = ['$q']; function FoundationAnimation($q) { 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 animationTimeout; var deferred = $q.defer(); 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]; run(); return deferred.promise; function run() { //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.on(events.join(' '), eventHandler); animationTimeout = setTimeout(function() { if(timedOut) { finishAnimation(); } }, 3000); } function eventHandler(e) { if (element[0] === e.target) { clearTimeout(animationTimeout); finishAnimation(); } } 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; element.off(events.join(' '), eventHandler); deferred.resolve({element: element, active: activation}); } function cancelAnimation(element) { deregisterElement(element); angular.element(element).off(events.join(' ')); //kill all animation event handlers timedOut = false; deferred.reject(); } 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); } } } })();