feat(animate): adds basic support for CSS animations on enter and leave

Closes #3876
This commit is contained in:
Robert Messerle
2015-08-28 14:39:34 -07:00
parent effbb54f3d
commit 39ce9d3397
26 changed files with 688 additions and 8 deletions

View File

@ -1,4 +1,5 @@
import {Inject, Injectable, OpaqueToken} from 'angular2/src/core/di';
import {AnimationBuilder} from 'angular2/src/animate/animation_builder';
import {isPresent, isBlank, RegExpWrapper, CONST_EXPR} from 'angular2/src/core/facade/lang';
import {BaseException, WrappedException} from 'angular2/src/core/facade/exceptions';
@ -42,7 +43,7 @@ export class DomRenderer extends Renderer {
* @private
*/
constructor(private _eventManager: EventManager,
private _domSharedStylesHost: DomSharedStylesHost,
private _domSharedStylesHost: DomSharedStylesHost, private _animate: AnimationBuilder,
private _templateCloner: TemplateCloner, @Inject(DOCUMENT) document) {
super();
this._document = document;
@ -94,7 +95,51 @@ export class DomRenderer extends Renderer {
var previousFragmentNodes = resolveInternalDomFragment(previousFragmentRef);
if (previousFragmentNodes.length > 0) {
var sibling = previousFragmentNodes[previousFragmentNodes.length - 1];
moveNodesAfterSibling(sibling, resolveInternalDomFragment(fragmentRef));
let nodes = resolveInternalDomFragment(fragmentRef);
moveNodesAfterSibling(sibling, nodes);
this.animateNodesEnter(nodes);
}
}
/**
* Iterates through all nodes being added to the DOM and animates them if necessary
* @param nodes
*/
animateNodesEnter(nodes: Node[]) {
for (let i = 0; i < nodes.length; i++) this.animateNodeEnter(nodes[i]);
}
/**
* Performs animations if necessary
* @param node
*/
animateNodeEnter(node: Node) {
if (DOM.isElementNode(node) && DOM.hasClass(node, 'ng-animate')) {
DOM.addClass(node, 'ng-enter');
this._animate.css()
.addAnimationClass('ng-enter-active')
.start(<HTMLElement>node)
.onComplete(() => { DOM.removeClass(node, 'ng-enter'); });
}
}
/**
* If animations are necessary, performs animations then removes the element; otherwise, it just
* removes the element.
* @param node
*/
animateNodeLeave(node: Node) {
if (DOM.isElementNode(node) && DOM.hasClass(node, 'ng-animate')) {
DOM.addClass(node, 'ng-leave');
this._animate.css()
.addAnimationClass('ng-leave-active')
.start(<HTMLElement>node)
.onComplete(() => {
DOM.removeClass(node, 'ng-leave');
DOM.remove(node);
});
} else {
DOM.remove(node);
}
}
@ -104,7 +149,9 @@ export class DomRenderer extends Renderer {
}
var parentView = resolveInternalDomView(elementRef.renderView);
var element = parentView.boundElements[elementRef.renderBoundElementIndex];
moveNodesAfterSibling(element, resolveInternalDomFragment(fragmentRef));
var nodes = resolveInternalDomFragment(fragmentRef);
moveNodesAfterSibling(element, nodes);
this.animateNodesEnter(nodes);
}
_detachFragmentScope = wtfCreateScope('DomRenderer#detachFragment()');
@ -112,7 +159,7 @@ export class DomRenderer extends Renderer {
var s = this._detachFragmentScope();
var fragmentNodes = resolveInternalDomFragment(fragmentRef);
for (var i = 0; i < fragmentNodes.length; i++) {
DOM.remove(fragmentNodes[i]);
this.animateNodeLeave(fragmentNodes[i]);
}
wtfLeave(s);
}