docs(guide/animations): list missing animated directives (and other improvements)

- List missing animation-aware directives.
- Fix/Improve wording/formatting.
- Fix typos.
- Limit lines to 100 chars.
This commit is contained in:
Georgios Kalpakas
2017-01-10 19:46:08 +02:00
parent 9341671d78
commit 17fb15d7a4
+210 -196
View File
@@ -6,20 +6,26 @@
# Animations
AngularJS provides animation hooks for common directives such as `ngRepeat`, `ngSwitch`, and `ngView`, as well as custom directives
via the `$animate` service. These animation hooks are set in place to trigger animations during the life cycle of various directives and when
triggered, will attempt to perform a CSS Transition, CSS Keyframe Animation or a JavaScript callback Animation (depending on if an animation is
placed on the given directive). Animations can be placed using vanilla CSS by following the naming conventions set in place by AngularJS
or with JavaScript code when it's defined as a factory.
AngularJS provides animation hooks for common directives such as
{@link ng.directive:ngRepeat ngRepeat}, {@link ng.directive:ngSwitch ngSwitch}, and
{@link ngRoute.directive:ngView ngView}, as well as custom directives via the `$animate` service.
These animation hooks are set in place to trigger animations during the life cycle of various
directives and when triggered, will attempt to perform a CSS Transition, CSS Keyframe Animation or a
JavaScript callback Animation (depending on whether an animation is placed on the given directive).
Animations can be placed using vanilla CSS by following the naming conventions set in place by
AngularJS or with JavaScript code, defined as a factory.
<div class="alert alert-info">
Note that we have used non-prefixed CSS transition properties in our examples as the major browsers now support non-prefixed
properties. If you intend to support older browsers or certain mobile browsers then you will need to include prefixed
versions of the transition properties. Take a look at http://caniuse.com/#feat=css-transitions for what browsers require prefixes,
and https://github.com/postcss/autoprefixer for a tool that can automatically generate the prefixes for you.
Note that we have used non-prefixed CSS transition properties in our examples as the major
browsers now support non-prefixed properties. If you intend to support older browsers or certain
mobile browsers then you will need to include prefixed versions of the transition properties. Take
a look at http://caniuse.com/#feat=css-transitions for what browsers require prefixes, and
https://github.com/postcss/autoprefixer for a tool that can automatically generate the prefixes
for you.
</div>
Animations are not available unless you include the {@link ngAnimate `ngAnimate` module} as a dependency within your application.
Animations are not available unless you include the {@link ngAnimate `ngAnimate` module} as a
dependency of your application.
Below is a quick example of animations being enabled for `ngShow` and `ngHide`:
@@ -59,8 +65,9 @@ You may also want to setup a separate CSS file for defining CSS-based animations
## How they work
Animations in AngularJS are completely based on CSS classes. As long as you have a CSS class attached to a HTML element within
your website, you can apply animations to it. Lets say for example that we have an HTML template with a repeater in it like so:
Animations in AngularJS are completely based on CSS classes. As long as you have a CSS class
attached to a HTML element within your application, you can apply animations to it. Lets say for
example that we have an HTML template with a repeater like so:
```html
<div ng-repeat="item in items" class="repeated-item">
@@ -68,22 +75,21 @@ your website, you can apply animations to it. Lets say for example that we have
</div>
```
As you can see, the `.repeated-item` class is present on the element that will be repeated and this class will be
used as a reference within our application's CSS and/or JavaScript animation code to tell AngularJS to perform an animation.
As you can see, the `repeated-item` class is present on the element that will be repeated and this
class will be used as a reference within our application's CSS and/or JavaScript animation code to
tell AngularJS to perform an animation.
As ngRepeat does its thing, each time a new item is added into the list, ngRepeat will add
a `ng-enter` class name to the element that is being added. When removed it will apply a `ng-leave` class name and when moved around
it will apply a `ng-move` class name.
As `ngRepeat` does its thing, each time a new item is added into the list, `ngRepeat` will add an
`ng-enter` class to the element that is being added. When removed it will apply an `ng-leave` class
and when moved around it will apply an `ng-move` class.
Taking a look at the following CSS code, we can see some transition and keyframe animation code set for each of those events that
occur when ngRepeat triggers them:
Taking a look at the following CSS code, we can see some transition and keyframe animation code set
up for each of those events that occur when `ngRepeat` triggers them:
```css
/*
We're using CSS transitions for when
the enter and move events are triggered
for the element that has the .repeated-item
class
We are using CSS transitions for when the enter and move events
are triggered for the element that has the `repeated-item` class
*/
.repeated-item.ng-enter, .repeated-item.ng-move {
transition: all 0.5s linear;
@@ -91,10 +97,8 @@ occur when ngRepeat triggers them:
}
/*
The ng-enter-active and ng-move-active
are where the transition destination properties
are set so that the animation knows what to
animate.
`.ng-enter-active` and `.ng-move-active` are where the transition destination
properties are set so that the animation knows what to animate
*/
.repeated-item.ng-enter.ng-enter-active,
.repeated-item.ng-move.ng-move-active {
@@ -102,73 +106,64 @@ occur when ngRepeat triggers them:
}
/*
We're using CSS keyframe animations for when
the leave event is triggered for the element
that has the .repeated-item class
We are using CSS keyframe animations for when the `leave` event
is triggered for the element that has the `repeated-item` class
*/
.repeated-item.ng-leave {
animation: 0.5s my_animation;
}
@keyframes my_animation {
from { opacity:1; }
to { opacity:0; }
from { opacity: 1; }
to { opacity: 0; }
}
```
The same approach to animation can be used using JavaScript code (**jQuery is used within to perform animations**):
The same approach to animation can be used using JavaScript code
(**for simplicity, we rely on jQuery to perform animations here**):
```js
myModule.animation('.repeated-item', function() {
return {
enter: function(element, done) {
element.css('opacity',0);
jQuery(element).animate({
opacity: 1
}, done);
// Initialize the element's opacity
element.css('opacity', 0);
// optional onDone or onCancel callback
// function to handle any post-animation
// cleanup operations
// Animate the element's opacity
// (`element.animate()` is provided by jQuery)
element.animate({opacity: 1}, done);
// Optional `onDone`/`onCancel` callback function
// to handle any post-animation cleanup operations
return function(isCancelled) {
if(isCancelled) {
jQuery(element).stop();
if (isCancelled) {
// Abort the animation if cancelled
// (`element.stop()` is provided by jQuery)
element.stop();
}
}
};
},
leave: function(element, done) {
// Initialize the element's opacity
element.css('opacity', 1);
jQuery(element).animate({
opacity: 0
}, done);
// optional onDone or onCancel callback
// function to handle any post-animation
// cleanup operations
return function(isCancelled) {
if(isCancelled) {
jQuery(element).stop();
}
}
},
move: function(element, done) {
element.css('opacity', 0);
jQuery(element).animate({
opacity: 1
}, done);
// Animate the element's opacity
// (`element.animate()` is provided by jQuery)
element.animate({opacity: 0}, done);
// optional onDone or onCancel callback
// function to handle any post-animation
// cleanup operations
// Optional `onDone`/`onCancel` callback function
// to handle any post-animation cleanup operations
return function(isCancelled) {
if(isCancelled) {
jQuery(element).stop();
if (isCancelled) {
// Abort the animation if cancelled
// (`element.stop()` is provided by jQuery)
element.stop();
}
}
};
},
// you can also capture these animation events
// We can also capture the following animation events:
move: function(element, done) {},
addClass: function(element, className, done) {},
removeClass: function(element, className, done) {}
}
@@ -176,74 +171,84 @@ myModule.animation('.repeated-item', function() {
```
With these generated CSS class names present on the element at the time, AngularJS automatically
figures out whether to perform a CSS and/or JavaScript animation. If both CSS and JavaScript animation
code is present, and match the CSS class name on the element, then AngularJS will run both animations at the same time.
figures out whether to perform a CSS and/or JavaScript animation. Note that you can't have both CSS
and JavaScript animations based on the same CSS class. See
{@link ngAnimate#css-js-animations-together here} for more details.
## Class and ngClass animation hooks
## Class and `ngClass` animation hooks
AngularJS also pays attention to CSS class changes on elements by triggering the **add** and **remove** hooks.
This means that if a CSS class is added to or removed from an element then an animation can be executed in between,
before the CSS class addition or removal is finalized. (Keep in mind that AngularJS will only be
able to capture class changes if an **expression** or the **ng-class** directive is used on the element.)
AngularJS also pays attention to CSS class changes on elements by triggering the **add** and
**remove** hooks. This means that if a CSS class is added to or removed from an element then an
animation can be executed in between, before the CSS class addition or removal is finalized.
(Keep in mind that AngularJS will only be able to capture class changes if an
**interpolated expression** or the **ng-class** directive is used on the element.)
The example below shows how to perform animations during class changes:
<example module="ngAnimate" deps="angular-animate.js" animations="true" name="animate-css-class">
<file name="index.html">
<p>
<input type="button" value="set" ng-click="myCssVar='css-class'">
<input type="button" value="clear" ng-click="myCssVar=''">
<br>
<span ng-class="myCssVar">CSS-Animated Text</span>
</p>
</file>
<file name="style.css">
.css-class-add, .css-class-remove {
transition: all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;
}
<file name="index.html">
<p>
<button ng-click="myCssVar='css-class'">Set</button>
<button ng-click="myCssVar=''">Clear</button>
<br>
<span ng-class="myCssVar">CSS-Animated Text</span>
</p>
</file>
<file name="style.css">
.css-class-add, .css-class-remove {
transition: all 0.5s cubic-bezier(0.250, 0.460, 0.450, 0.940);
}
.css-class,
.css-class-add.css-class-add-active {
color: red;
font-size:3em;
}
.css-class,
.css-class-add.css-class-add-active {
color: red;
font-size: 3em;
}
.css-class-remove.css-class-remove-active {
font-size:1.0em;
color: black;
}
</file>
.css-class-remove.css-class-remove-active {
font-size: 1em;
color: black;
}
</file>
</example>
Although the CSS is a little different than what we saw before, the idea is the same.
## Which directives support animations?
A handful of common AngularJS directives support and trigger animation hooks whenever any major event occurs during its life cycle.
The table below explains in detail which animation events are triggered
A handful of common AngularJS directives support and trigger animation hooks whenever any major
event occurs during their life cycle. The table below explains in detail which animation events are
triggered:
| Directive | Supported Animations |
|-------------------------------------------------------------------------------------|------------------------------------------|
| {@link ng.directive:ngRepeat#animations ngRepeat} | enter, leave, and move |
| {@link ngRoute.directive:ngView#animations ngView} | enter and leave |
| {@link ng.directive:ngInclude#animations ngInclude} | enter and leave |
| {@link ng.directive:ngSwitch#animations ngSwitch} | enter and leave |
| {@link ng.directive:ngIf#animations ngIf} | enter and leave |
| {@link ng.directive:ngClass#animations ngClass or &#123;&#123;class&#125;&#125;} | add and remove |
| {@link ng.directive:ngShow#animations ngShow & ngHide} | add and remove (the ng-hide class value) |
| Directive | Supported Animations |
|-------------------------------------------------------------------------------|---------------------------------------------------------------------------|
| {@link ng.directive:ngRepeat#animations ngRepeat} | enter, leave, and move |
| {@link ng.directive:ngIf#animations ngIf} | enter and leave |
| {@link ng.directive:ngSwitch#animations ngSwitch} | enter and leave |
| {@link ng.directive:ngInclude#animations ngInclude} | enter and leave |
| {@link ngRoute.directive:ngView#animations ngView} | enter and leave |
| {@link module:ngMessages#animations ngMessage / ngMessageExp} | enter and leave |
| {@link ng.directive:ngClass#animations ngClass / {{class&#125;&#8203;&#125;} | add and remove |
| {@link ng.directive:ngClass#animations ngClassEven / ngClassOdd} | add and remove |
| {@link ng.directive:ngHide#animations ngHide} | add and remove (the `ng-hide` class) |
| {@link ng.directive:ngShow#animations ngShow} | add and remove (the `ng-hide` class) |
| {@link ng.directive:ngModel#animation-hooks ngModel} | add and remove ({@link ng.directive:ngModel#css-classes various classes}) |
| {@link ng.directive:form#animation-hooks form / ngForm} | add and remove ({@link ng.directive:form#css-classes various classes}) |
| {@link module:ngMessages#animations ngMessages} | add and remove (the `ng-active`/`ng-inactive` classes) |
For a full breakdown of the steps involved during each animation event, refer to the {@link ng.$animate API docs}.
For a full breakdown of the steps involved during each animation event, refer to the
{@link ng.$animate API docs}.
## How do I use animations in my own directives?
Animations within custom directives can also be established by injecting `$animate` directly into your directive and
making calls to it when needed.
Animations within custom directives can also be established by injecting `$animate` directly into
your directive and making calls to it when needed.
```js
myModule.directive('my-directive', ['$animate', function($animate) {
return function(scope, element, attrs) {
return function(scope, element) {
element.on('click', function() {
if(element.hasClass('clicked')) {
if (element.hasClass('clicked')) {
$animate.removeClass(element, 'clicked');
} else {
$animate.addClass(element, 'clicked');
@@ -255,17 +260,19 @@ myModule.directive('my-directive', ['$animate', function($animate) {
## Animations on app bootstrap / page load
By default, animations are disabled when the AngularJS app {@link guide/bootstrap bootstraps}. If you are using the {@link ngApp} directive,
this happens in the `DOMContentLoaded` event, so immediately after the page has been loaded.
Animations are disabled, so that UI and content are instantly visible. Otherwise, with many animations on
the page, the loading process may become too visually overwhelming, and the performance may suffer.
By default, animations are disabled when the AngularJS app {@link guide/bootstrap bootstraps}. If you
are using the {@link ngApp} directive, this happens in the `DOMContentLoaded` event, so immediately
after the page has been loaded. Animations are disabled, so that UI and content are instantly
visible. Otherwise, with many animations on the page, the loading process may become too visually
overwhelming, and the performance may suffer.
Internally, `ngAnimate` waits until all template downloads that are started right after bootstrap have finished.
Then, it waits for the currently running {@link ng.$rootScope.Scope#$digest} and the one after that to finish.
This ensures that the whole app has been compiled fully before animations are attempted.
Internally, `ngAnimate` waits until all template downloads that are started right after bootstrap
have finished. Then, it waits for the currently running {@link ng.$rootScope.Scope#$digest $digest}
and one more after that, to finish. This ensures that the whole app has been compiled fully before
animations are attempted.
If you do want your animations to play when the app bootstraps, you can enable animations globally in
your main module's {@link angular.Module#run run} function:
If you do want your animations to play when the app bootstraps, you can enable animations globally
in your main module's {@link angular.Module#run run} function:
```js
myModule.run(function($animate) {
@@ -276,16 +283,17 @@ myModule.run(function($animate) {
## How to (selectively) enable, disable and skip animations
There are three different ways to disable animations, both globally and for specific animations.
Disabling specific animations can help to speed up the render performance, for example for large `ngRepeat`
lists that don't actually have animations. Because ngAnimate checks at runtime if animations are present,
performance will take a hit even if an element has no animation.
Disabling specific animations can help to speed up the render performance, for example for large
`ngRepeat` lists that don't actually have animations. Because `ngAnimate` checks at runtime if
animations are present, performance will take a hit even if an element has no animation.
### In the config: {@link $animateProvider#classNameFilter $animateProvider.classNameFilter()}
### During the config: {@link $animateProvider#classNameFilter $animateProvider.classNameFilter()}
This function can be called in the {@link angular.Module#config config} phase of an app. It takes a regex as the only argument,
which will then be matched against the classes of any element that is about to be animated. The regex
allows a lot of flexibility - you can either allow animations only for specific classes (useful when
you are working with 3rd party animations), or exclude specific classes from getting animated.
This function can be called during the {@link angular.Module#config config} phase of an app. It
takes a regex as the only argument, which will then be matched against the classes of any element
that is about to be animated. The regex allows a lot of flexibility - you can either allow
animations for specific classes only (useful when you are working with 3rd party animations), or
exclude specific classes from getting animated.
```js
app.config(function($animateProvider) {
@@ -294,42 +302,42 @@ app.config(function($animateProvider) {
```
```css
/&#42; prefixed with animate- &#42;/
/&#42; prefixed with `animate-` &#42;/
.animate-fade-add.animate-fade-add-active {
transition: all 1s linear;
opacity: 0;
}
```
The classNameFilter approach generally applies the biggest speed boost, because the matching is
done before any other animation disabling strategies are checked. However, that also means it is not
possible to override class name matching with the two following strategies. It's of course still possible
to enable / disable animations by changing an element's class name at runtime.
The `classNameFilter` approach generally gives the biggest speed boost, because the matching is done
before any other animation disabling strategies are checked. However, that also means it is not
possible to override class name matching with the two following strategies. It's of course still
possible to enable / disable animations by changing an element's class name at runtime.
### At runtime: {@link ng.$animate#enabled $animate.enabled()}
This function can be used to enable / disable animations in two different ways:
With a single `boolean` argument, it enables / disables animations globally: `$animate.enabled(false)`
disables all animations in your app.
With a single `boolean` argument, it enables / disables animations globally:
`$animate.enabled(false)` disables all animations in your app.
When the first argument is a native DOM or jqLite/jQuery element, the function enables / disables
animations on this element *and all its children*: `$animate.enabled(myElement, false)`. This is the
most flexible way to change the animation state. For example, even if you have used it to disable
animations on a parent element, you can still re-enable it for a child element. And compared to the
`classNameFilter`, you can change the animation status at runtime instead of during the config phase.
animations on this element *and all its children*: `$animate.enabled(myElement, false)`. You can
still use it to re-enable animations for a child element, even if you have disabled them on a parent
element. And compared to the `classNameFilter`, you can change the animation status at runtime
instead of during the config phase.
Note however that the `$animate.enabled()` state for individual elements does not overwrite disabling
rules that have been set in the {@link $animateProvider#classNameFilter classNameFilter}.
Note however that the `$animate.enabled()` state for individual elements does not overwrite
disabling rules that have been set in the {@link $animateProvider#classNameFilter classNameFilter}.
### Via CSS styles: overwriting styles in the `ng-animate` CSS class
Whenever an animation is started, ngAnimate applies the `ng-animate` class to the element for the
whole duration of the animation. By applying CSS transition / animation styling to the class,
you can skip an animation:
Whenever an animation is started, `ngAnimate` applies the `ng-animate` class to the element for the
whole duration of the animation. By applying CSS transition / animation styling to that class, you
can skip an animation:
```css
.my-class{
.my-class {
transition: transform 2s;
}
@@ -340,23 +348,23 @@ you can skip an animation:
my-class.ng-animate {
transition: 0s;
}
```
By setting `transition: 0s`, ngAnimate will ignore the existing transition styles, and not try to animate them (Javascript
animations will still execute, though). This can be used to prevent {@link guide/animations#preventing-collisions-with-existing-animations-and-third-party-libraries
issues with existing animations interfering with ngAnimate}.
By setting `transition: 0s`, `ngAnimate` will ignore the existing transition styles, and not try to
animate them (Javascript animations will still execute, though). This can be used to prevent
{@link guide/animations#preventing-collisions-with-existing-animations-and-third-party-libraries
issues with existing animations interfering with `ngAnimate`}.
## Preventing flicker before an animation starts
When nesting elements with structural animations such as `ngIf` into elements that have class-based
animations such as `ngClass`, it sometimes happens that before the actual animation starts, there is a brief flicker or flash of content
where the animated element is briefly visible.
When nesting elements with structural animations, such as `ngIf`, into elements that have
class-based animations such as `ngClass`, it sometimes happens that before the actual animation
starts, there is a brief flicker or flash of content where the animated element is briefly visible.
To prevent this, you can apply styles to the `ng-[event]-prepare` class, which is added as soon as an animation is initialized,
but removed before the actual animation starts (after waiting for a $digest). This class is only added for *structural*
animations (`enter`, `move`, and `leave`).
To prevent this, you can apply styles to the `ng-[event]-prepare` class, which is added as soon as
an animation is initialized, but removed before the actual animation starts (after waiting for a
`$digest`). This class is only added for *structural* animations (`enter`, `move`, and `leave`).
Here's an example where you might see flickering:
@@ -368,8 +376,9 @@ Here's an example where you might see flickering:
</div>
```
It is possible that during the `enter` event, the `.message` div will be briefly visible before it starts animating.
In that case, you can add styles to the CSS that make sure the element stays hidden before the animation starts:
It is possible that during the `enter` event, the `.message` div will be briefly visible before it
starts animating. In that case, you can add styles to the CSS that make sure the element stays
hidden before the animation starts:
```css
.message.ng-enter-prepare {
@@ -379,66 +388,71 @@ In that case, you can add styles to the CSS that make sure the element stays hid
/* Other animation styles ... */
```
## Preventing Collisions with Existing Animations and Third Party Libraries
By default, any `ngAnimate` enabled directives will assume any transition / animation styles on the
element are part of an `ngAnimate` animation. This can lead to problems when the styles are actually
for animations that are independent of `ngAnimate`.
## Preventing collisions with existing animations and third-party libraries
For example, an element acts as a loading spinner. It has an infinite css animation on it, and also an
{@link ngIf `ngIf`} directive, for which no animations are defined:
By default, any `ngAnimate`-enabled directives will assume that `transition` / `animation` styles on
the element are part of an `ngAnimate` animation. This can lead to problems when the styles are
actually for animations that are independent of `ngAnimate`.
For example, an element acts as a loading spinner. It has an infinite css animation on it, and also
an {@link ngIf `ngIf`} directive, for which no animations are defined:
```css
@keyframes rotating {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
.spinner {
animation: rotating 2s linear infinite;
}
.spinner {
animation: rotating 2s linear infinite;
@keyframes rotating {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
```
Now, when the `ngIf` changes, `ngAnimate` will see the spinner animation and use
it to animate the `enter`/`leave` event, which doesn't work because
the animation is infinite. The element will still be added / removed after a timeout, but there will be a
noticable delay.
Now, when the `ngIf` expression changes, `ngAnimate` will see the spinner animation and use it to
animate the `enter`/`leave` event, which doesn't work because the animation is infinite. The element
will still be added / removed after a timeout, but there will be a noticeable delay.
This might also happen because some third-party frameworks place animation duration defaults
across many element or className selectors in order to make their code small and reuseable.
This might also happen because some third-party frameworks place animation duration defaults across
many element or className selectors in order to make their code small and reusable.
You can prevent this unwanted behavior by adding CSS to the `.ng-animate` class that is added
for the whole duration of an animation. Simply overwrite the transition / animation duration. In the
You can prevent this unwanted behavior by adding CSS to the `.ng-animate` class, that is added for
the whole duration of each animation. Simply overwrite the transition / animation duration. In the
case of the spinner, this would be:
```css
.spinner.ng-animate {
transition: 0s none;
animation: 0s none;
animation: 0s none;
transition: 0s none;
}
```
If you do have CSS transitions / animations defined for the animation events, make sure they have higher priority
than any styles that are independent from ngAnimate.
If you do have CSS transitions / animations defined for the animation events, make sure they have a
higher priority than any styles that are not related to `ngAnimate`.
You can also use one of the two other {@link guide/animations#how-to-selectively-enable-disable-and-skip-animations strategies to disable animations}.
You can also use one of the other
{@link guide/animations#how-to-selectively-enable-disable-and-skip-animations
strategies to disable animations}.
### Enable animations for elements outside of the AngularJS application DOM tree: {@link ng.$animate#pin $animate.pin()}
## Enable animations outside of the application DOM tree: {@link ng.$animate#pin $animate.pin()}
Before animating, `ngAnimate` checks to see if the element being animated is inside the application DOM tree,
and if it is not, no animation is run. Usually, this is not a problem as most apps use the `ngApp`
attribute / bootstrap the app on the `html` or `body` element.
Before animating, `ngAnimate` checks if the animated element is inside the application DOM tree. If
not, no animation is run. Usually, this is not a problem since most apps use the `html` or `body`
elements as their root.
Problems arise when the application is bootstrapped on a different element, and animations are
attempted on elements that are outside the application tree, e.g. when libraries append popup and modal
elements as the last child in the body tag.
attempted on elements that are outside the application tree, e.g. when libraries append popup or
modal elements to the body tag.
You can use {@link ng.$animate#pin `$animate.pin(elementToAnimate, parentHost)`} to specify that an
element belongs to your application. Simply call it before the element is added to the DOM / before
the animation starts, with the element you want to animate, and the element which should be its
assumed parent.
You can use {@link ng.$animate#pin `$animate.pin(element, parentHost)`} to associate an element with
another element that belongs to your application. Simply call it before the element is added to the
DOM / before the animation starts, with the element you want to animate, and the element which
should be its assumed parent.
## More about animations
For a full breakdown of each method available on `$animate`, see the {@link ng.$animate API documentation}.
For a full breakdown of each method available on `$animate`, see the
{@link ng.$animate API documentation}.
To see a complete demo, see the {@link tutorial/step_14 animation step within the AngularJS phonecat tutorial}.
To see a complete demo, see the {@link tutorial/step_14 animation step in the phonecat tutorial}.