Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

Commit f031430

Browse files
committed
docs(guide/animations): improve animations guide
1 parent 556e8ee commit f031430

File tree

1 file changed

+289
-0
lines changed

1 file changed

+289
-0
lines changed

docs/content/guide/animations.ngdoc

+289
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,289 @@
1+
@ngdoc overview
2+
@name Developer Guide: Animations
3+
@description
4+
5+
6+
# Animations
7+
8+
AngularJS 1.2 provides animation hooks for common directives such as `ngRepeat`, `ngSwitch`, and `ngView`, as well as custom directives
9+
via the `$animate` service. These animation hooks are set in place to trigger animations during the life cycle of various directives and when
10+
triggered, will attempt to perform a CSS Transition, CSS Keyframe Animation or a JavaScript callback Animation (depending on if an animation is
11+
placed on the given directive). Animations can be placed using vanilla CSS by following the naming conventions set in place by AngularJS
12+
or with JavaScript code when it's defined as a factory.
13+
14+
Animations are not available unless you include the {@link api/ngAnimate `ngAnimate` module} as a dependency within your application.
15+
16+
Below is a quick example of animations being enabled for `ngShow` and `ngHide`:
17+
18+
<example animations="true">
19+
<file name="index.html">
20+
<div ng-init="checked=true">
21+
<label>
22+
<input type="checkbox" ng-model="checked" style="float:left; margin-right:10px;"> Is Visible...
23+
</label>
24+
<div class="check-element animate-show-hide" ng-show="checked" style="clear:both;">
25+
Visible...
26+
</div>
27+
</div>
28+
</file>
29+
<file name="animations.css">
30+
.animate-show-hide {
31+
padding:10px;
32+
border:1px solid black;
33+
background:white;
34+
}
35+
36+
.animate-show-hide.ng-hide-add, .animate-show-hide.ng-hide-remove {
37+
-webkit-transition:all linear 0.5s;
38+
-moz-transition:all linear 0.5s;
39+
-o-transition:all linear 0.5s;
40+
transition:all linear 0.5s;
41+
display:block!important;
42+
}
43+
44+
.animate-show-hide.ng-hide-add.ng-hide-add-active,
45+
.animate-show-hide.ng-hide-remove {
46+
opacity:0;
47+
}
48+
49+
.animate-show-hide.ng-hide-add,
50+
.animate-show-hide.ng-hide-remove.ng-hide-remove-active {
51+
opacity:1;
52+
}
53+
</file>
54+
</example>
55+
56+
## Installation
57+
58+
See the {@link api/ngAnimate API docs for `ngAnimate`} for instructions on installing the module.
59+
60+
You may also want to setup a separate CSS file for defining CSS-based animations.
61+
62+
## How they work
63+
64+
Animations in AngularJS are completely based on CSS classes. As long as you have a CSS class attached to a HTML element within
65+
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:
66+
67+
<pre>
68+
<div ng-repeat="item in items" class="repeated-item">
69+
{{ item.id }}
70+
</div>
71+
</pre>
72+
73+
As you can see, the `.repeated-item` class is present on the element that will be repeated and this class will be
74+
used as a reference within our application's CSS and/or JavaScript animation code to tell AngularJS to perform an animation.
75+
76+
As ngRepeat does its thing, each time a new item is added into the list, ngRepeat will add
77+
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
78+
it will apply a `ng-move` class name.
79+
80+
Taking a look at the following CSS code, we can see some transition and keyframe animation code set for each of those events that
81+
occur when ngRepeat triggers them:
82+
83+
<pre>
84+
&#47;&#42;
85+
We're using CSS transitions for when
86+
the enter and move events are triggered
87+
for the element that has the .repeated-item
88+
class
89+
&#42;&#47;
90+
.repeated-item.ng-enter, .repeated-item.ng-move {
91+
-webkit-transition:0.5s linear all;
92+
-moz-transition:0.5s linear all;
93+
-o-transition:0.5s linear all;
94+
transition:0.5s linear all;
95+
opacity:0;
96+
}
97+
98+
&#47;&#42;
99+
The ng-enter-active and ng-move-active
100+
are where the transition destination properties
101+
are set so that the animation knows what to
102+
animate.
103+
&#42;&#47;
104+
.repeated-item.ng-enter.ng-enter-active,
105+
.repeated-item.ng-move.ng-move-active {
106+
opacity:1;
107+
}
108+
109+
&#47;&#42;
110+
We're using CSS keyframe animations for when
111+
the leave event is triggered for the element
112+
that has the .repeated-item class
113+
&#42;&#47;
114+
.repeated-item.ng-leave {
115+
-webkit-animation:0.5s my_animation;
116+
-moz-animation:0.5s my_animation;
117+
-o-animation:0.5s my_animation;
118+
animation:0.5s my_animation;
119+
}
120+
121+
&#64;keyframes my_animation {
122+
from { opacity:1; }
123+
to { opacity:0; }
124+
}
125+
126+
&#47;&#42;
127+
Unfortunately each browser vendor requires
128+
its own definition of keyframe animation code...
129+
&#42;&#47;
130+
&#64;-webkit-keyframes my_animation {
131+
from { opacity:1; }
132+
to { opacity:0; }
133+
}
134+
135+
&#64;-moz-keyframes my_animation {
136+
from { opacity:1; }
137+
to { opacity:0; }
138+
}
139+
140+
&#64;-o-keyframes my_animation {
141+
from { opacity:1; }
142+
to { opacity:0; }
143+
}
144+
</pre>
145+
146+
The same approach to animation can be used using JavaScript code (**jQuery is used within to perform animations**):
147+
148+
<pre>
149+
myModule.animation('.repeated-item', function() {
150+
return {
151+
enter : function(element, done) {
152+
element.css('opacity',0);
153+
jQuery(element).animate({
154+
opacity: 1
155+
}, done);
156+
157+
// optional onDone or onCancel callback
158+
// function to handle any post-animation
159+
// cleanup operations
160+
return function(isCancelled) {
161+
if(isCancelled) {
162+
jQuery(element).stop();
163+
}
164+
}
165+
},
166+
leave : function(element, done) {
167+
element.css('opacity', 1);
168+
jQuery(element).animate({
169+
opacity: 0
170+
}, done);
171+
172+
// optional onDone or onCancel callback
173+
// function to handle any post-animation
174+
// cleanup operations
175+
return function(isCancelled) {
176+
if(isCancelled) {
177+
jQuery(element).stop();
178+
}
179+
}
180+
},
181+
move : function(element, done) {
182+
element.css('opacity', 0);
183+
jQuery(element).animate({
184+
opacity: 1
185+
}, done);
186+
187+
// optional onDone or onCancel callback
188+
// function to handle any post-animation
189+
// cleanup operations
190+
return function(isCancelled) {
191+
if(isCancelled) {
192+
jQuery(element).stop();
193+
}
194+
}
195+
},
196+
197+
// you can also capture these animation events
198+
addClass : function(element, className, done) {},
199+
removeClass : function(element, className, done) {}
200+
}
201+
});
202+
</pre>
203+
204+
With these generated CSS class names present on the element at the time, AngularJS automatically
205+
figures out whether to perform a CSS and/or JavaScript animation. If both CSS and JavaScript animation
206+
code is present, and match the CSS class name on the element, then AngularJS will run both animations at the same time.
207+
208+
## Class and ngClass animation hooks
209+
210+
AngularJS also pays attention to CSS class changes on elements by triggering the **add** and **remove** hooks.
211+
This means that if a CSS class is added to or removed from an element then an animation can be executed in between
212+
before the CSS class addition or removal is finalized. (Keep in mind that AngularJS will only be
213+
able to capture class changes if an **expression** or the **ng-class** directive is used on the element.)
214+
215+
The example below shows how to perform animations during class changes:
216+
217+
<example animations="true">
218+
<file name="index.html">
219+
<p>
220+
<input type="button" value="set" ng-click="myCssVar='css-class'">
221+
<input type="button" value="clear" ng-click="myCssVar=''">
222+
<br>
223+
<span ng-class="myCssVar">CSS-Animated Text</span>
224+
</p>
225+
</file>
226+
<file name="style.css">
227+
.css-class-add, .css-class-remove {
228+
-webkit-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;
229+
-moz-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;
230+
-o-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;
231+
transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;
232+
}
233+
234+
.css-class,
235+
.css-class-add.css-class-add-active {
236+
color: red;
237+
font-size:3em;
238+
}
239+
240+
.css-class-remove.css-class-remove-active {
241+
font-size:1.0em;
242+
color:black;
243+
}
244+
</file>
245+
</example>
246+
247+
Although the CSS is a little different then what we saw before, the idea is the same.
248+
249+
## Which directives support animations?
250+
251+
A handful of common AngularJS directives support and trigger animation hooks whenever any major event occurs during its life cycle.
252+
The table below explains in detail which animation events are triggered
253+
254+
| Directive | Supported Animations |
255+
|-------------------------------------------------------------------------------------|------------------------------------------|
256+
| {@link api/ng.directive:ngRepeat#animations ngRepeat} | enter, leave, and move |
257+
| {@link api/ngRoute.directive:ngView#animations ngView} | enter and leave |
258+
| {@link api/ng.directive:ngInclude#animations ngInclude} | enter and leave |
259+
| {@link api/ng.directive:ngSwitch#animations ngSwitch} | enter and leave |
260+
| {@link api/ng.directive:ngIf#animations ngIf} | enter and leave |
261+
| {@link api/ng.directive:ngShow#animations ngClass or &#123;&#123;class&#125;&#125;} | add and remove |
262+
| {@link api/ng.directive:ngShow#animations ngShow & ngHide} | add and remove (the ng-hide class value) |
263+
264+
For a full breakdown of the steps involved during each animation event, refer to the {@link api/ngAnimate.$animate API docs}.
265+
266+
## How do I use animations in my own directives?
267+
268+
You can also use animations within custom directives can also be established by injecting `$animate` directly into your directive and
269+
making calls to it when needed.
270+
271+
<pre>
272+
myModule.directive('my-directive', ['$animate', function($animate) {
273+
return function(element, scope, attrs) {
274+
element.bind('click', function() {
275+
if(element.hasClass('clicked')) {
276+
$animate.removeClass(element, 'clicked');
277+
} else {
278+
$animate.addClass(element, 'clicked');
279+
}
280+
});
281+
};
282+
}]);
283+
</pre>
284+
285+
## More about animations
286+
287+
For a full breakdown of each method available on `$animate`, see the {@link api/ngAnimate.$animate API documentation}.
288+
289+
To see a complete demo, see the {@link tutorial/step_12 animation step within the AngularJS phonecat tutorial}.

0 commit comments

Comments
 (0)