OLD | NEW |
(Empty) | |
| 1 /** |
| 2 * CSS animation and DOM lifecycle management for AngularDart apps. |
| 3 * |
| 4 * The [angular.animate](#angular/angular-animate) library makes it easier to bu
ild animations |
| 5 * that affect the lifecycle of DOM elements. A useful example of this is animat
ing the |
| 6 * removal of an element from the DOM. In order to do this ideally the |
| 7 * operation should immediatly execute and manipulate the data model, |
| 8 * and the framework should handle the actual remove of the DOM element once |
| 9 * the animation complets. This ensures that the logic and model of the |
| 10 * application is seperated so that the state of the model can be reasoned |
| 11 * about without having to wory about future modifications of the model. |
| 12 * This library uses computed css styles to calculate the total duration |
| 13 * of an animation and handles the addition, removal, and modification of DOM |
| 14 * elements for block level directives such as `ng-if`, `ng-repeat`, |
| 15 * `ng-hide`, and more. |
| 16 * |
| 17 * To use, install the AnimationModule into your main module: |
| 18 * |
| 19 * var module = new Module() |
| 20 * ..install(new AnimationModule()); |
| 21 * |
| 22 * Once the module has been installed, all block level DOM manipulations will |
| 23 * be routed through the [CssAnimate] class instead of the |
| 24 * default [NgAnimate] implementation. This will, in turn, |
| 25 * perform the tracking, manipulation, and computation for animations. |
| 26 * |
| 27 * As an example of how this works, let's walk through what happens whan an |
| 28 * element is added to the DOM. The [CssAnimate] implementation will add the |
| 29 * `.ng-enter` class to new DOM elements when they are inserted into the DOM |
| 30 * by a directive and will read the computed style. If there is a |
| 31 * transition or keyframe animation, that animation duration will be read, |
| 32 * and the animation will be performed. The `.ng-enter-active` class will be |
| 33 * added to the DOM element to set the target state for transition based |
| 34 * animations. When the animation is complete (determined by the |
| 35 * precomputed duration) the `.ng-enter` and `.ng-enter-active` classes |
| 36 * will be removed from the DOM element. |
| 37 * |
| 38 * When removing elements from the DOM, a simliar pattern is followed. The |
| 39 * `.ng-leave` class will be added to an element, the transition and / or |
| 40 * keyframe animation duration will be computed, and if it is non-zero the |
| 41 * animation will be run by adding the `.ng-leave-active` class. When |
| 42 * the animation completes, the element will be physically removed from the |
| 43 * DOM. |
| 44 * |
| 45 * The same set of steps is run for each of the following types of DOM |
| 46 * manipulation: |
| 47 * |
| 48 * * `.ng-enter` |
| 49 * * `.ng-leave` |
| 50 * * `.ng-move` |
| 51 * * `.{cssclass}-add` |
| 52 * * `.{cssclass}-remove` |
| 53 * |
| 54 * When writing the css for animating a component you should avoid putting |
| 55 * css transitions on elements that might be animated or there may be |
| 56 * unintended pauses or side effects when an element is removed. |
| 57 * |
| 58 * Fade out example: |
| 59 * |
| 60 * HTML: |
| 61 * <div class="goodbye" ng-if="ctrl.visible"> |
| 62 * Goodbye world! |
| 63 * </div> |
| 64 * |
| 65 * CSS: |
| 66 * .goodbye.ng-leave { |
| 67 * opacity: 1; |
| 68 * transition: opacity 1s; |
| 69 * } |
| 70 * .goodbye.ng-leave.ng-leave-active { |
| 71 * opacity: 0; |
| 72 * } |
| 73 * |
| 74 * This will perform a fade out animation on the 'goodby' div when the |
| 75 * `ctrl.visible` property goes from `true` to `false`. |
| 76 * |
| 77 * The [CssAnimate] will also do optimizations on running animations by |
| 78 * preventing child DOM animations with the [AnimationOptimizer]. This |
| 79 * prevents transitions on child elements while the parent is animating, |
| 80 * but will not stop running transitions once they have started. |
| 81 * |
| 82 * Finally, it's possible to change the behavior of the [AnimationOptimizer] |
| 83 * by using the `ng-animate` and `ng-animate-children` with the options |
| 84 * `never`, `always`, or `auto`. `ng-animate` works only on the specific |
| 85 * element it is applied too and will override other optimizations if `never` |
| 86 * or `always` is specified. `ng-animate` defaults to `auto` which will |
| 87 * defer to the `ng-animate-children` on a parent element or the currently |
| 88 * running animation check. |
| 89 * |
| 90 * `ng-animate-children` allows animation to be controlled on large chunks of |
| 91 * DOM. It only affects child elements, and allows the `always`, `never`, |
| 92 * and `auto` values to be specified. Always will always attempt animations |
| 93 * on child DOM directives, never will always prevent them (except in the |
| 94 * case where a given element has `ng-animate="always"` specified), |
| 95 * and `auto` will defer the decision to the currently running animation |
| 96 * check. |
| 97 */ |
| 98 |
| 99 library angular.animate; |
| 100 |
| 101 import 'dart:async'; |
| 102 import 'dart:html' as dom; |
| 103 |
| 104 import 'package:angular/core/annotation.dart'; |
| 105 import 'package:angular/core/module_internal.dart'; |
| 106 import 'package:angular/core_dom/module_internal.dart'; |
| 107 import 'package:angular/core_dom/dom_util.dart' as util; |
| 108 import 'package:logging/logging.dart'; |
| 109 import 'package:perf_api/perf_api.dart'; |
| 110 import 'package:di/di.dart'; |
| 111 |
| 112 @MirrorsUsed(targets: const [ |
| 113 'angular.animate' |
| 114 ]) |
| 115 import 'dart:mirrors' show MirrorsUsed; |
| 116 |
| 117 part 'animations.dart'; |
| 118 part 'animation_loop.dart'; |
| 119 part 'animation_optimizer.dart'; |
| 120 part 'css_animate.dart'; |
| 121 part 'css_animation.dart'; |
| 122 part 'ng_animate.dart'; |
| 123 |
| 124 final Logger _logger = new Logger('ng.animate'); |
| 125 |
| 126 /** |
| 127 * Installing the AnimationModule will install a [CssAnimate] implementation of |
| 128 * the [NgAnimate] interface in your application. This will change the behavior |
| 129 * of view construction, and some of the native directives to allow you to add |
| 130 * and define css transition and keyframe animations for the styles of your |
| 131 * elements. |
| 132 * |
| 133 * Example html: |
| 134 * |
| 135 * <div ng-if="ctrl.myBoolean" class="my-div">...</div> |
| 136 * |
| 137 * Example css defining an opacity transition over .5 seconds using the |
| 138 * `.ng-enter` and `.ng-leave` css classes: |
| 139 * |
| 140 * .my-div.ng-enter { |
| 141 * transition: all 500ms; |
| 142 * opacity: 0; |
| 143 * } |
| 144 * .my-div.ng-enter-active { |
| 145 * opacity: 1; |
| 146 * } |
| 147 * |
| 148 * .my-div.ng-leave { |
| 149 * transition: all 500ms; |
| 150 * opacity: 1; |
| 151 * } |
| 152 * .my-div.ng-leave-active { |
| 153 * opacity: 0; |
| 154 * } |
| 155 */ |
| 156 class AnimationModule extends Module { |
| 157 AnimationModule() { |
| 158 type(AnimationFrame); |
| 159 type(AnimationLoop); |
| 160 type(CssAnimationMap); |
| 161 type(AnimationOptimizer); |
| 162 value(NgAnimate, null); |
| 163 type(NgAnimateChildren); |
| 164 type(Animate, implementedBy: CssAnimate); |
| 165 } |
| 166 } |
OLD | NEW |