Skip to content

Commit 42cf3ca

Browse files
committed
docs(guide/animation): add info for various topics
- how to enable / disable animations Closes angular#8812 - how to handle conflicts with existing animations Closes angular#8033 Closes angular#11820 - what happens on boostrap / how to enable animations on bootstrap
1 parent fa19d52 commit 42cf3ca

File tree

2 files changed

+134
-26
lines changed

2 files changed

+134
-26
lines changed

docs/content/guide/animations.ngdoc

+134-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
# Animations
88

9-
AngularJS 1.3 provides animation hooks for common directives such as `ngRepeat`, `ngSwitch`, and `ngView`, as well as custom directives
9+
AngularJS provides animation hooks for common directives such as `ngRepeat`, `ngSwitch`, and `ngView`, as well as custom directives
1010
via the `$animate` service. These animation hooks are set in place to trigger animations during the life cycle of various directives and when
1111
triggered, will attempt to perform a CSS Transition, CSS Keyframe Animation or a JavaScript callback Animation (depending on if an animation is
1212
placed on the given directive). Animations can be placed using vanilla CSS by following the naming conventions set in place by AngularJS
@@ -274,6 +274,98 @@ myModule.directive('my-directive', ['$animate', function($animate) {
274274
}]);
275275
```
276276

277+
## Animations on app bootstrap / page load
278+
279+
By default, animations are disabled when the Angular app {@link guide/bootstrap bootstraps}. If you are using the {@link ngApp} directive,
280+
this happens in the `DOMContentLoaded` event, so immediately after the page has been loaded.
281+
Animations are disabled, so that UI and content are instantly visible. Otherwise, with many animations on
282+
the page, the loading process may become too visually overwhelming, and the performance may suffer.
283+
284+
Internally, this is done by waiting for two digests - that is usually enough to wait until all templates
285+
have been downloaded.
286+
287+
If you do want your animations to play when the app bootstraps, you can enable animations globally in
288+
your main module's {@link angular.Module#run run} function:
289+
290+
```js
291+
myModule.run(function($animate) {
292+
$animate.enabled(true);
293+
});
294+
```
295+
296+
## How to (selectively) enable, disable and skip animations
297+
298+
There are three different ways to disable animations, both globally and for specific animations.
299+
Disabling specific animations can help to speed up the render performance, for example for large `ngRepeat`
300+
lists that don't actually have animations. Because ngAnimate checks at runtime if animations are present,
301+
performance will take a hit even if an element has no animation.
302+
303+
### In the config: {@link $animateProvider#classNameFilter $animateProvider.classNameFilter()}
304+
305+
This function can be called in the {@link angular.Module#config config} phase of an app. It takes a regex as the only argument,
306+
which will then be matched against the classes of any element that is about to be animated. The regex
307+
allows a lot of flexibility - you can either allow animations only for specific classes (useful when
308+
you are working with 3rd party animations), or exclude specific classes from getting animated.
309+
310+
```js
311+
app.cofig($animateProvider) {
312+
$animateProvider.classNameFilter(/animate-/);
313+
});
314+
```
315+
316+
```css
317+
/* prefixed with animate- */
318+
.animate-fade-add.animate-fade-add-active {
319+
transition:1s linear all;
320+
opacity:0;
321+
}
322+
```
323+
324+
The classNameFilter approach generally applies the biggest speed boost, because the matching is
325+
done before any other animation disabling strategies are checked. However, once a class has been
326+
excluded via the classNameFilter, it's not possible to enable animations for this element at runtime.
327+
328+
### At runtime: {@link ng.$animate#enabled $animate.enabled()}
329+
330+
This function can be used to enable / disable animations in two different ways:
331+
332+
With a single `boolean` argument, it enables / disables animations globally: `$animate.enabled(false)`
333+
disables all animations in your app.
334+
335+
When the second argument is an native DOM or jQuery element, the function enables / disables
336+
animations on this element *and all its children*: `$animate.enabled(false, myElement)`. This is the
337+
most flexible way to change the animation state. For example, even if you have used it to disable
338+
animations on a parent element, you can still re-enable it for a child element. And compared to the
339+
`classNameFilter`, you can change the animation status at runtime instead of only in the config.
340+
341+
Note however that the `$animate.enabled()` state for individual elements does not overwrite disabling
342+
rules that have been set in the {@link $animateProvider#classNameFilter classNameFilter}.
343+
344+
### Via CSS styles: overwriting styles in the `ng-animate` CSS class
345+
Whenever an animation is started, ngAnimate applies the `ng-animate` class to the element for the
346+
whole duration of the animation. By applying CSS transition / animation styling to the class,
347+
you can skip an animation:
348+
349+
```css
350+
351+
.my-class{
352+
transition: transform 2s;
353+
}
354+
355+
.my-class:hover {
356+
transform: translateX(50px);
357+
}
358+
359+
my-class.ng-animate {
360+
transition: 0s;
361+
}
362+
363+
```
364+
365+
By setting `transition: 0s`, ngAnimate will ignore the existing transition styles, and not try to animate them (Javascript
366+
animations will still execute, though). This can be used to prevent {@link guide/animations#preventing-collisions-with-existing-animations-and-third-party-libraries
367+
issues with existing animations interfering with ngAnimate}.
368+
277369
## Preventing flicker before an animation starts
278370

279371
When nesting elements with structural animations such as `ngIf` into elements that have class-based
@@ -305,6 +397,47 @@ In that case, you can add styles to the CSS that make sure the element stays hid
305397
/* Other animation styles ... */
306398
```
307399

400+
## Preventing Collisions with Existing Animations and Third Party Libraries
401+
By default, any `ngAnimate` enabled directives will assume any transition / animation styles on the
402+
element are part of an `ngAnimate` animation. This can lead to problems when the styles are actually
403+
for animations that are independent of `ngAnimate`.
404+
405+
For example, an element acts as a loading spinner. It has an inifinite css animation on it, and also an
406+
{@link ngIf `ngIf`} directive, for which no animations are defined:
407+
408+
```css
409+
@keyframes rotating {
410+
from { transform: rotate(0deg); }
411+
to { transform: rotate(360deg); }
412+
}
413+
414+
.spinner {
415+
animation: rotating 2s linear infinite;
416+
}
417+
```
418+
419+
Now, when the `ngIf` changes, `ngAnimate` will see the spinner animation and use
420+
it to animate the `enter`/`leave` event, which doesn't work because
421+
the animation is infinite. The element will still be added / removed after a timeout, but there will be a
422+
noticable delay.
423+
424+
This might also happen because some third-party frameworks place animation duration defaults
425+
across many element or className selectors in order to make their code small and reuseable.
426+
427+
You can prevent this unwanted behavior by adding CSS to the `.ng-animate` class that is added
428+
for the whole duration of an animation. Simply overwrite the transition / animation duration. In the
429+
case of the spinner, this would be:
430+
431+
.spinner.ng-animate {
432+
transition: 0s none;
433+
animation: 0s none;
434+
}
435+
436+
If you do have CSS transitions / animations defined for the animation events, make sure they have higher priority
437+
than any styles that are independent from ngAnimate.
438+
439+
You can also use one of the two other {@link guide/animations#how-to-selectively-enable-disable-and-skip-animations strategies to disable animations}
440+
308441
## More about animations
309442

310443
For a full breakdown of each method available on `$animate`, see the {@link ng.$animate API documentation}.

src/ngAnimate/module.js

-25
Original file line numberDiff line numberDiff line change
@@ -699,31 +699,6 @@
699699
* possible be sure to visit the {@link ng.$animate $animate service API page}.
700700
*
701701
*
702-
* ### Preventing Collisions With Third Party Libraries
703-
*
704-
* Some third-party frameworks place animation duration defaults across many element or className
705-
* selectors in order to make their code small and reuseable. This can lead to issues with ngAnimate, which
706-
* is expecting actual animations on these elements and has to wait for their completion.
707-
*
708-
* You can prevent this unwanted behavior by using a prefix on all your animation classes:
709-
*
710-
* ```css
711-
* /* prefixed with animate- */
712-
* .animate-fade-add.animate-fade-add-active {
713-
* transition:1s linear all;
714-
* opacity:0;
715-
* }
716-
* ```
717-
*
718-
* You then configure `$animate` to enforce this prefix:
719-
*
720-
* ```js
721-
* $animateProvider.classNameFilter(/animate-/);
722-
* ```
723-
*
724-
* This also may provide your application with a speed boost since only specific elements containing CSS class prefix
725-
* will be evaluated for animation when any DOM changes occur in the application.
726-
*
727702
* ## Callbacks and Promises
728703
*
729704
* When `$animate` is called it returns a promise that can be used to capture when the animation has ended. Therefore if we were to trigger

0 commit comments

Comments
 (0)