©
本文档使用 PHP中文网手册 发布
ngAnimate
The ngAnimate
module provides support for JavaScript, CSS3 transition and CSS3 keyframe animation hooks within existing core and custom directives.
To see animations in action, all that is required is to define the appropriate CSS classes
or to register a JavaScript animation via the myModule.animation() function. The directives that support animation automatically are:
ngRepeat
, ngInclude
, ngIf
, ngSwitch
, ngShow
, ngHide
, ngView
and ngClass
. Custom directives can take advantage of animation
by using the $animate
service.
Below is a more detailed breakdown of the supported animation events provided by pre-existing ng directives:
Directive | Supported Animations |
---|---|
ngRepeat | enter, leave and move |
ngView | enter and leave |
ngInclude | enter and leave |
ngSwitch | enter and leave |
ngIf | enter and leave |
ngClass | add and remove (the CSS class(es) present) |
ngShow & ngHide | add and remove (the ng-hide class value) |
form & ngModel | add and remove (dirty, pristine, valid, invalid & all other validations) |
ngMessages | add and remove (ng-active & ng-inactive) |
ngMessage | enter and leave |
You can find out more information about animations upon visiting each directive page.
Below is an example of how to apply animations to a directive that supports animation hooks:
<style Type="text/css">
.slide.ng-enter, .slide.ng-leave {
-webkit-transition:0.5s linear all;
transition:0.5s linear all;
}
.slide.ng-enter { } /* starting animations for enter */
.slide.ng-enter.ng-enter-active { } /* terminal animations for enter */
.slide.ng-leave { } /* starting animations for leave */
.slide.ng-leave.ng-leave-active { } /* terminal animations for leave */
</style>
<!--
the animate service will automatically add .ng-enter and .ng-leave to the element
to trigger the CSS transition/animations
-->
<ANY class="slide" ng-include="..."></ANY>
记住,默认情况下, if an animation is running, any child elements cannot be animated
until the parent element's animation has completed. This blocking feature can be overridden by
placing the ng-animate-children
attribute on a parent container tag.
<div class="slide-animation" ng-if="on" ng-animate-children>
<div class="fade-animation" ng-if="on">
<div class="explode-animation" ng-if="on">
...
</div>
</div>
</div>
When the on
expression value changes and an animation is triggered then each of the elements within
will all animate without the block being applied to child elements.
The following code below demonstrates how to perform animations using CSS transitions with Angular:
<style Type="text/css">
/*
The animate class is apart of the element and the ng-enter class
is attached to the element once the enter animation event is triggered
*/
.reveal-animation.ng-enter {
-webkit-transition: 1s linear all; /* Safari/Chrome */
transition: 1s linear all; /* All other modern browsers and IE10+ */
/* The animation preparation code */
opacity: 0;
}
/*
记住, that you want to combine both CSS
classes together to avoid any CSS-specificity
conflicts
*/
.reveal-animation.ng-enter.ng-enter-active {
/* The animation code itself */
opacity: 1;
}
</style>
<div class="view-container">
<div ng-view class="reveal-animation"></div>
</div>
The following code below demonstrates how to perform animations using CSS animations with Angular:
<style Type="text/css">
.reveal-animation.ng-enter {
-webkit-animation: enter_sequence 1s linear; /* Safari/Chrome */
animation: enter_sequence 1s linear; /* IE10+ and Future Browsers */
}
@-webkit-keyframes enter_sequence {
from { opacity:0; }
to { opacity:1; }
}
@keyframes enter_sequence {
from { opacity:0; }
to { opacity:1; }
}
</style>
<div class="view-container">
<div ng-view class="reveal-animation"></div>
</div>
Both CSS3 animations and transitions can be used together and the animate service will figure out the correct duration and delay timing.
Upon DOM mutation, the event class is added first (something like ng-enter
), then the browser prepares itself to add
the active class (in this case ng-enter-active
) which then triggers the animation. The animation module will automatically
detect the CSS code to determine when the animation ends. Once the animation is over then both CSS classes will be
removed from the DOM. If a browser does not support CSS transitions or CSS animations then the animation will start and end
immediately resulting in a DOM element that is at its final state. This final state is when the DOM element
has no CSS transition/animation classes applied to it.
Structural transitions (such as enter, leave and move) will always apply a 0s none
transition
value to force the browser into rendering the styles defined in the setup (.ng-enter, .ng-leave
or .ng-move) class. This means that any active transition animations operating on the element
will be cut off to make way for the enter, leave or move animation.
Class-based transitions refer to transition animations that are triggered when a CSS class is
added to or removed from the element (via $animate.addClass
, $animate.removeClass
,
$animate.setClass
, or by directives such as ngClass
, ngModel
and form
).
They are different when compared to structural animations since they do not cancel existing
animations nor do they block successive transitions from rendering on the same element.
This distinction allows for multiple class-based transitions to be performed on the same element.
In addition to ngAnimate supporting the default (natural) functionality of class-based transition
animations, ngAnimate also decorates the element with starting and ending CSS classes to aid the
developer in further styling the element throughout the transition animation. Earlier versions
of ngAnimate may have caused natural CSS transitions to break and not render properly due to
$animate temporarily blocking transitions using 0s none
in order to allow the setup CSS class
(the -add
or -remove
class) to be applied without triggering an animation. However, as of
version 1.3, this workaround has been removed with ngAnimate and all non-ngAnimate CSS
class transitions are compatible with ngAnimate.
There is, however, one special case when dealing with class-based transitions in ngAnimate.
When rendering class-based transitions that make use of the setup and active CSS classes
(如: .fade-add
and .fade-add-active
for when .fade
is added) be sure to define
the transition value on the active CSS class and not the setup class.
.fade-add {
/* remember to place a 0s transition here
to ensure that the styles are applied instantly
even if the element already has a transition style */
transition:0s linear all;
/* starting CSS styles */
opacity:1;
}
.fade-add.fade-add-active {
/* this will be the length of the animation */
transition:1s linear all;
opacity:0;
}
The setup CSS class (in this case .fade-add
) also has a transition style property, however, it
has a duration of zero. This may not be required, however, incase the browser is unable to render
the styling present in this CSS class instantly then it could be that the browser is attempting
to perform an unnecessary transition.
This workaround, however, does not apply to standard class-based transitions that are rendered when a CSS class containing a transition is applied to an element:
.fade {
/* this works as expected */
transition:1s linear all;
opacity:0;
}
Please keep this in mind when coding the CSS markup that will be used within class-based transitions. Also, try not to mix the two class-based animation flavors together since the CSS code may become overly complex.
A Staggering animation is a collection of animations that are issued with a slight delay in between each successive operation resulting in a curtain-like effect. The ngAnimate module, as of 1.2.0, supports staggering animations and the stagger effect can be performed by creating a ng-EVENT-stagger CSS class and attaching that class to the base CSS class used for the animation. The style property expected within the stagger class can either be a transition-delay or an animation-delay property (or both if your animation contains both transitions and keyframe animations).
.my-animation.ng-enter {
/* standard transition code */
-webkit-transition: 1s linear all;
transition: 1s linear all;
opacity:0;
}
.my-animation.ng-enter-stagger {
/* this will have a 100ms delay between each successive leave animation */
-webkit-transition-delay: 0.1s;
transition-delay: 0.1s;
/* in case the stagger doesn't work then these two values
must be set to 0 to avoid an accidental CSS inheritance */
-webkit-transition-duration: 0s;
transition-duration: 0s;
}
.my-animation.ng-enter.ng-enter-active {
/* standard transition styles */
opacity:1;
}
Staggering animations work by default in ngRepeat (so long as the CSS class is defined). Outside of ngRepeat, to use staggering animations on your own, they can be triggered by firing multiple calls to the same event on $animate. However, the restrictions surrounding this are that each of the elements must have the same CSS className value as well as the same parent element. A stagger operation will also be reset if more than 10ms has passed after the last animation has been fired.
The following code will issue the ng-leave-stagger event on the element provided:
var kids = parent.children();
$animate.leave(kids[0]); //stagger index=0
$animate.leave(kids[1]); //stagger index=1
$animate.leave(kids[2]); //stagger index=2
$animate.leave(kids[3]); //stagger index=3
$animate.leave(kids[4]); //stagger index=4
$timeout(Function() {
//stagger has reset itself
$animate.leave(kids[5]); //stagger index=0
$animate.leave(kids[6]); //stagger index=1
}, 100, false);
Stagger animations are currently only supported within CSS-defined animations.
//!annotate="YourApp" Your AngularJS Module|Replace this or ngModule with the module that you used to define your application.
var ngModule = angular.module('YourApp', ['ngAnimate']);
ngModule.animation('.my-crazy-animation', Function() {
return {
enter: Function(element, done) {
//run the animation here and call done when the animation is complete
return Function(cancelled) {
//this (可选) function will be called when the animation
//completes or when the animation is cancelled (the cancelled
//flag will be set to true if cancelled).
};
},
leave: Function(element, done) { },
move: Function(element, done) { },
//animation that can be triggered before the class is added
beforeAddClass: Function(element, className, done) { },
//animation that can be triggered after the class is added
addClass: Function(element, className, done) { },
//animation that can be triggered before the class is removed
beforeRemoveClass: Function(element, className, done) { },
//animation that can be triggered after the class is removed
removeClass: Function(element, className, done) { }
};
});
JavaScript-defined animations are created with a CSS-like class selector and a collection of events which are set to run a javascript callback function. When an animation is triggered, $animate will look for a matching animation which fits the element's CSS class attribute value and then run the matching animation event function (if found). In other words, if the CSS classes present on the animated element match any of the JavaScript animations then the callback function will be executed. It should be also noted that only simple, single class selectors are allowed (compound class selectors are not supported).
Within a JavaScript animation, an object containing various event callback animation functions is expected to be returned. As explained above, these callbacks are triggered based on the animation event. Therefore if an enter animation is run, and the JavaScript animation is found, then the enter callback will handle that animation (in addition to the CSS keyframe animation or transition code that is defined via a stylesheet).
First include angular-animate.js
in your HTML:
<script src="angular.js">
<script src="angular-animate.js">
You can download this file from the following places:
//ajax.googleapis.com/ajax/libs/angularjs/X.Y.Z/angular-animate.js
bower install angular-animate@X.Y.Z
"//code.angularjs.org/X.Y.Z/angular-animate.js"
where X.Y.Z is the AngularJS version you are running.
Then load the module in your application by adding it as a dependent module:
angular.module('app', ['ngAnimate']);
With that you're ready to get started!
名称 | 描述 |
---|---|
$animateProvider |
The |
名称 | 描述 |
---|---|
$animate |
The |