What is angular-animate?
The angular-animate package is an AngularJS module that provides support for JavaScript, CSS3 transition, and CSS3 keyframe animation hooks within your AngularJS applications. It allows you to create smooth, complex animations for various elements and states in your application.
What are angular-animate's main functionalities?
CSS-based animations
This feature allows you to define CSS classes for entering and leaving animations. The .ng-enter and .ng-leave classes are used to define the starting state of the animation, while the .ng-enter-active and .ng-leave-active classes define the end state.
/* CSS code */
.fade.ng-enter {
transition: 0.5s linear all;
opacity: 0;
}
.fade.ng-enter-active {
opacity: 1;
}
.fade.ng-leave {
transition: 0.5s linear all;
opacity: 1;
}
.fade.ng-leave-active {
opacity: 0;
}
JavaScript-based animations
This feature allows you to define animations using JavaScript. You can create custom animations for entering and leaving elements by manipulating their CSS properties and using jQuery's animate function.
// JavaScript code
angular.module('myApp', ['ngAnimate'])
.animation('.slide', function() {
return {
enter: function(element, done) {
element.css({
position: 'relative',
left: '-10px',
opacity: 0
});
element.animate({
left: '0px',
opacity: 1
}, 1000, done);
},
leave: function(element, done) {
element.css({
position: 'relative',
left: '0px',
opacity: 1
});
element.animate({
left: '-10px',
opacity: 0
}, 1000, done);
}
};
});
ngAnimate directive
The ngAnimate directive can be used to apply animations to elements within an AngularJS application. In this example, the .fade class is applied to each item in the ng-repeat directive, and the corresponding CSS animations are triggered when items are added or removed.
<div ng-app="myApp" ng-controller="myCtrl">
<div ng-repeat="item in items" class="fade">
{{item}}
</div>
</div>
<script>
angular.module('myApp', ['ngAnimate'])
.controller('myCtrl', function($scope) {
$scope.items = ['Item 1', 'Item 2', 'Item 3'];
});
</script>
Other packages similar to angular-animate
ng2-animate
ng2-animate is an Angular (2+) module that provides a set of reusable animations for Angular applications. It offers a variety of pre-built animations that can be easily applied to elements, making it simpler to add animations without writing custom CSS or JavaScript. Compared to angular-animate, ng2-animate is designed for newer versions of Angular and provides a more modern approach to animations.
react-transition-group
react-transition-group is a popular library for managing animations in React applications. It provides components like Transition, CSSTransition, and TransitionGroup to handle the entering and exiting of elements with animations. While it serves a similar purpose to angular-animate, it is specifically designed for React and offers a different API and set of features tailored to React's component-based architecture.
animejs
animejs is a lightweight JavaScript animation library that works with any JavaScript framework, including AngularJS. It provides a powerful and flexible API for creating complex animations with minimal code. Unlike angular-animate, which is tightly integrated with AngularJS, animejs is a general-purpose animation library that can be used across different frameworks and projects.
packaged angular-animate
This repo is for distribution on npm
and bower
. The source for this module is in the
main AngularJS repo.
Please file issues and pull requests against that repo.
Install
You can install this package either with npm
or with bower
.
npm
npm install angular-animate
Then add ngAnimate
as a dependency for your app:
angular.module('myApp', [require('angular-animate')]);
bower
bower install angular-animate
Then add a <script>
to your index.html
:
<script src="/bower_components/angular-animate/angular-animate.js"></script>
Then add ngAnimate
as a dependency for your app:
angular.module('myApp', ['ngAnimate']);
Documentation
Documentation is available on the
AngularJS docs site.
License
The MIT License
Copyright (c) 2010-2015 Google, Inc. http://angularjs.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
1.4.4 pylon-requirement (2015-08-13)
Bug Fixes
- $animate:
- $animateCss: make sure that
skipBlocking
avoids the pre-emptive transition-delay styling
(11695ca6) - $compile:
- $injector: Allows ES6 function syntax
(44a96a4c,
#12424, #12425)
- $location: don't crash if navigating outside the app base
(9e492c35,
#11667)
- $q: Use extend to avoid overwriting prototype
(3abb3fef,
#10697)
- $rootScope: don't clear phase if $apply is re-entered
(e0cf496f,
#12174)
- Angular: allow unescaped
=
signs in values in parseKeyValue
(f13852c1,
#12351) - httpParamSerializerJQLike: Follow jQuery for index of arrays of objects
(18a2e4fb)
- i18n: by default put negative sign before currency symbol
(96f2e3be,
#10158)
- injector: check that modulesToLoad isArray.
(5abf593e,
#12285)
- input: Firefox validation trigger
(e7423168,
#12102)
- merge: regExp should not be treated as a objects when merging.
(a5221f32,
#12419, #12409)
- ng/$locale: by default put negative sign before currency symbol
(52986724,
#10158)
- ngAnimate:
- always apply a preparation reflow for CSS-based animations
(d33cedda,
#12553, #12554, #12267, #12554)
- ensure that only string-based addClass/removeClass values are applied
(0d6fc2dc,
#12458, #12459)
- ensure that parent class-based animations are never closed by their children
(32d3cbb3,
#11975, #12276)
- allow animations on body and root elements
(44ce9c82,
#11956, #12245)
- $timeout without invokeApply
(7db5f361,
#12281, #12282)
- ngCsp: allow CSP to be configurable
(618356e4,
#11933, #8459, #12346)
- ngModel: correct minErr usage for correct doc creation
(a268c29f,
#12386, #12416)
- ngOptions: allow empty option selection with multiple attribute
(c11a7d67,
#12511, #12541)
- ngSanitize: escape the wide char quote marks in a regex in linky.js
(39ff3332,
#11609)
Features
Performance Improvements
Breaking Changes
- ngAnimate: due to 32d3cbb3,
CSS classes added/removed by ngAnimate are now applied synchronously once the first digest has passed.
The previous behavior involved ngAnimate having to wait for one
requestAnimationFrame before CSS classes were added/removed. The CSS classes
are now applied directly after the first digest that is triggered after
$animate.addClass
, $animate.removeClass
or $animate.setClass
is
called. If any of your code relies on waiting for one frame before
checking for CSS classes on the element then please change this
behavior. If a parent class-based animation, however, is run through a
JavaScript animation which triggers an animation for beforeAddClass
and/or beforeRemoveClass
then the CSS classes will not be applied
in time for the children (and the parent class-based animation will not
be cancelled by any child animations).
- $q due to 6838c979,
When writing tests, there is no need to call
$timeout.flush()
to resolve a call to $q.when
with a value.
The previous behavior involved creating an extra promise that needed to be resolved. This is no longer needed when
$q.when
is called with a value. In the case that the test is not aware if $q.when
is called with a value or
another promise, it is possible to replace $timeout.flush();
with $timeout.flush(0);
.
describe('$q.when', function() {
it('should not need a call to $timeout.flush() to resolve already resolved promises',
inject(function($q, $timeout) {
$q.when('foo');
// In AngularJS 1.4.3 a call to `$timeout.flush();` was needed
$timeout.verifyNoPendingTasks();
}));
it('should accept $timeout.flush(0) when not sure if $q.when was called with a value or a promise',
inject(function($q, $timeout) {
$q.when('foo');
$timeout.flush(0);
$timeout.verifyNoPendingTasks();
}));
it('should need a call to $timeout.flush() to resolve $q.when when called with a promise',
inject(function($q, $timeout) {
$q.when($q.when('foo'));
$timeout.flush();
$timeout.verifyNoPendingTasks();
}));
});
-
form: Due to 94533e57,
the name
attribute of form
elements can now only contain characters that can be evaluated as part
of an Angular expression. This is because Angular uses the value of name
as an assignable expression
to set the form on the $scope
. For example, name="myForm"
assigns the form to $scope.myForm
and
name="myObj.myForm"
assigns it to $scope.myObj.myForm
.
Previously, it was possible to also use names such name="my:name"
, because Angular used a special setter
function for the form name. Now the general, more robust $parse
setter is used.
The easiest way to migrate your code is therefore to remove all special characters from the name
attribute.
If you need to keep the special characters, you can use the following directive, which will replace
the name
with a value that can be evaluated as an expression in the compile function, and then
re-set the original name in the postLink function. This ensures that (1), the form is published on
the scope, and (2), the form has the original name, which might be important if you are doing server-side
form submission.
angular.module('myApp').directive('form', function() {
return {
restrict: 'E',
priority: 1000,
compile: function(element, attrs) {
var unsupportedCharacter = ':'; // change accordingly
var originalName = attrs.name;
if (attrs.name && attrs.name.indexOf(unsupportedCharacter) > 0) {
attrs.$set('name', 'this["' + originalName + '"]');
}
return postLinkFunction(scope, element) {
// Don't trigger $observers
element.setAttribute('name', originalName);
}
}
};
});
<a name="1.4.3"></a>