revert: fix(animations): ensure all child elements are rendered before running animations

This reverts commit cbe85a0893.
This commit is contained in:
Matias Niemelä
2016-07-07 14:12:17 -07:00
parent cbe85a0893
commit f1fc1dc669
20 changed files with 81 additions and 283 deletions
@@ -11,7 +11,9 @@ import {AUTO_STYLE, BaseException} from '@angular/core';
import {AnimationKeyframe, AnimationPlayer, AnimationStyles, NoOpAnimationPlayer} from '../../core_private';
import {StringMapWrapper} from '../facade/collection';
import {StringWrapper, isNumber, isPresent} from '../facade/lang';
import {AnimationDriver} from './animation_driver';
import {getDOM} from './dom_adapter';
import {DomAnimatePlayer} from './dom_animate_player';
import {dashCaseToCamelCase} from './util';
import {WebAnimationsPlayer} from './web_animations_player';
@@ -19,17 +21,19 @@ import {WebAnimationsPlayer} from './web_animations_player';
export class WebAnimationsDriver implements AnimationDriver {
animate(
element: any, startingStyles: AnimationStyles, keyframes: AnimationKeyframe[],
duration: number, delay: number, easing: string): WebAnimationsPlayer {
duration: number, delay: number, easing: string): AnimationPlayer {
var anyElm = <any>element;
var formattedSteps: {[key: string]: string | number}[] = [];
var startingStyleLookup: {[key: string]: string | number} = {};
if (isPresent(startingStyles) && startingStyles.styles.length > 0) {
startingStyleLookup = _populateStyles(element, startingStyles, {});
startingStyleLookup = _populateStyles(anyElm, startingStyles, {});
startingStyleLookup['offset'] = 0;
formattedSteps.push(startingStyleLookup);
}
keyframes.forEach((keyframe: AnimationKeyframe) => {
let data = _populateStyles(element, keyframe.styles, startingStyleLookup);
let data = _populateStyles(anyElm, keyframe.styles, startingStyleLookup);
data['offset'] = keyframe.offset;
formattedSteps.push(data);
});
@@ -56,7 +60,14 @@ export class WebAnimationsDriver implements AnimationDriver {
playerOptions['easing'] = easing;
}
return new WebAnimationsPlayer(element, formattedSteps, playerOptions);
var player = this._triggerWebAnimation(anyElm, formattedSteps, playerOptions);
return new WebAnimationsPlayer(player, duration);
}
/** @internal */
_triggerWebAnimation(elm: any, keyframes: any[], options: any): DomAnimatePlayer {
return elm.animate(keyframes, options);
}
}
@@ -67,8 +78,9 @@ function _populateStyles(
styles.styles.forEach((entry) => {
StringMapWrapper.forEach(entry, (val: any, prop: string) => {
var formattedProp = dashCaseToCamelCase(prop);
data[formattedProp] =
val == AUTO_STYLE ? val : val.toString() + _resolveStyleUnit(val, prop, formattedProp);
data[formattedProp] = val == AUTO_STYLE ?
_computeStyle(element, formattedProp) :
val.toString() + _resolveStyleUnit(val, prop, formattedProp);
});
});
StringMapWrapper.forEach(defaultStyles, (value: string, prop: string) => {
@@ -142,3 +154,7 @@ function _isPixelDimensionStyle(prop: string): boolean {
return false;
}
}
function _computeStyle(element: any, prop: string): string {
return getDOM().getComputedStyle(element)[prop];
}
@@ -6,29 +6,20 @@
* found in the LICENSE file at https://angular.io/license
*/
import {AUTO_STYLE} from '@angular/core';
import {AnimationPlayer} from '../../core_private';
import {StringMapWrapper} from '../facade/collection';
import {isPresent} from '../facade/lang';
import {getDOM} from './dom_adapter';
import {DomAnimatePlayer} from './dom_animate_player';
export class WebAnimationsPlayer implements AnimationPlayer {
private _subscriptions: Function[] = [];
private _finished = false;
private _initialized = false;
private _player: DomAnimatePlayer;
private _started: boolean = false;
private _duration: number;
public parentPlayer: AnimationPlayer = null;
constructor(
public element: HTMLElement, public keyframes: {[key: string]: string | number}[],
public options: {[key: string]: string | number}) {
this._duration = <number>options['duration'];
constructor(private _player: DomAnimatePlayer, public totalTime: number) {
// this is required to make the player startable at a later time
this.reset();
this._player.onfinish = () => this._onFinish();
}
private _onFinish() {
@@ -42,46 +33,13 @@ export class WebAnimationsPlayer implements AnimationPlayer {
}
}
init(): void {
if (this._initialized) return;
this._initialized = true;
var anyElm = <any>this.element;
var keyframes = this.keyframes.map(styles => {
var formattedKeyframe: {[key: string]: string | number} = {};
StringMapWrapper.forEach(styles, (value: string | number, prop: string) => {
formattedKeyframe[prop] = value == AUTO_STYLE ? _computeStyle(anyElm, prop) : value;
});
return formattedKeyframe;
});
this._player = this._triggerWebAnimation(anyElm, keyframes, this.options);
// this is required so that the player doesn't start to animate right away
this.reset();
this._player.onfinish = () => this._onFinish();
}
/** @internal */
_triggerWebAnimation(elm: any, keyframes: any[], options: any): DomAnimatePlayer {
return <DomAnimatePlayer>elm.animate(keyframes, options);
}
onDone(fn: Function): void { this._subscriptions.push(fn); }
play(): void {
this.init();
this._player.play();
}
play(): void { this._player.play(); }
pause(): void {
this.init();
this._player.pause();
}
pause(): void { this._player.pause(); }
finish(): void {
this.init();
this._onFinish();
this._player.finish();
}
@@ -93,20 +51,12 @@ export class WebAnimationsPlayer implements AnimationPlayer {
this.play();
}
hasStarted(): boolean { return this._started; }
destroy(): void {
this.reset();
this._onFinish();
}
get totalTime(): number { return this._duration; }
setPosition(p: number): void { this._player.currentTime = p * this.totalTime; }
setPosition(p: any /** TODO #9100 */): void { this._player.currentTime = p * this.totalTime; }
getPosition(): number { return this._player.currentTime / this.totalTime; }
}
function _computeStyle(element: any, prop: string): string {
return getDOM().getComputedStyle(element)[prop];
}
@@ -12,7 +12,6 @@ import {el} from '@angular/platform-browser/testing/browser_util';
import {AnimationKeyframe, AnimationStyles} from '../../core_private';
import {DomAnimatePlayer} from '../../src/dom/dom_animate_player';
import {WebAnimationsDriver} from '../../src/dom/web_animations_driver';
import {WebAnimationsPlayer} from '../../src/dom/web_animations_player';
import {StringMapWrapper} from '../../src/facade/collection';
import {MockDomAnimatePlayer} from '../../testing/mock_dom_animate_player';
@@ -52,8 +51,8 @@ export function main() {
_makeKeyframe(1, {'font-size': '555px'})
];
var player = driver.animate(elm, startingStyles, styles, 0, 0, 'linear');
var details = _formatOptions(player);
driver.animate(elm, startingStyles, styles, 0, 0, 'linear');
var details = driver.log.pop();
var startKeyframe = details['keyframes'][0];
var firstKeyframe = details['keyframes'][1];
var lastKeyframe = details['keyframes'][2];
@@ -72,8 +71,8 @@ export function main() {
var startingStyles = _makeStyles({'borderTopWidth': 40});
var styles = [_makeKeyframe(0, {'font-size': 100}), _makeKeyframe(1, {'height': '555em'})];
var player = driver.animate(elm, startingStyles, styles, 0, 0, 'linear');
var details = _formatOptions(player);
driver.animate(elm, startingStyles, styles, 0, 0, 'linear');
var details = driver.log.pop();
var startKeyframe = details['keyframes'][0];
var firstKeyframe = details['keyframes'][1];
var lastKeyframe = details['keyframes'][2];
@@ -89,8 +88,8 @@ export function main() {
var startingStyles = _makeStyles({});
var styles = [_makeKeyframe(0, {'color': 'green'}), _makeKeyframe(1, {'color': 'red'})];
var player = driver.animate(elm, startingStyles, styles, 1000, 1000, 'linear');
var details = _formatOptions(player);
driver.animate(elm, startingStyles, styles, 1000, 1000, 'linear');
var details = driver.log.pop();
var options = details['options'];
expect(options['fill']).toEqual('both');
});
@@ -99,8 +98,8 @@ export function main() {
var startingStyles = _makeStyles({});
var styles = [_makeKeyframe(0, {'color': 'green'}), _makeKeyframe(1, {'color': 'red'})];
var player = driver.animate(elm, startingStyles, styles, 1000, 1000, 'ease-out');
var details = _formatOptions(player);
driver.animate(elm, startingStyles, styles, 1000, 1000, 'ease-out');
var details = driver.log.pop();
var options = details['options'];
expect(options['easing']).toEqual('ease-out');
});
@@ -109,15 +108,11 @@ export function main() {
var startingStyles = _makeStyles({});
var styles = [_makeKeyframe(0, {'color': 'green'}), _makeKeyframe(1, {'color': 'red'})];
var player = driver.animate(elm, startingStyles, styles, 1000, 1000, null);
var details = _formatOptions(player);
driver.animate(elm, startingStyles, styles, 1000, 1000, null);
var details = driver.log.pop();
var options = details['options'];
var keys = StringMapWrapper.keys(options);
expect(keys.indexOf('easing')).toEqual(-1);
});
});
}
function _formatOptions(player: WebAnimationsPlayer): {[key: string]: any} {
return {'element': player.element, 'keyframes': player.keyframes, 'options': player.options};
}
@@ -7,32 +7,16 @@
*/
import {AsyncTestCompleter, MockAnimationPlayer, beforeEach, beforeEachProviders, ddescribe, describe, expect, iit, inject, it, xdescribe, xit} from '@angular/core/testing/testing_internal';
import {el} from '@angular/platform-browser/testing/browser_util';
import {DomAnimatePlayer} from '../../src/dom/dom_animate_player';
import {WebAnimationsPlayer} from '../../src/dom/web_animations_player';
import {MockDomAnimatePlayer} from '../../testing/mock_dom_animate_player';
class ExtendedWebAnimationsPlayer extends WebAnimationsPlayer {
public domPlayer = new MockDomAnimatePlayer();
constructor(
public element: HTMLElement, public keyframes: {[key: string]: string | number}[],
public options: {[key: string]: string | number}) {
super(element, keyframes, options);
}
_triggerWebAnimation(elm: any, keyframes: any[], options: any): DomAnimatePlayer {
return this.domPlayer;
}
}
export function main() {
function makePlayer(): {[key: string]: any} {
var someElm = el('<div></div>');
var player = new ExtendedWebAnimationsPlayer(someElm, [], {});
player.init();
return {'captures': player.domPlayer.captures, 'player': player};
var mockPlayer = new MockDomAnimatePlayer();
var c = mockPlayer.captures;
var p = new WebAnimationsPlayer(mockPlayer, 0);
return {'captures': c, 'player': p};
}
describe('WebAnimationsPlayer', () => {
@@ -14,7 +14,7 @@ import {AnimationDriver} from '../src/dom/animation_driver';
import {StringMapWrapper} from '../src/facade/collection';
export class MockAnimationDriver extends AnimationDriver {
public log: {[key: string]: any}[] = [];
log: any[] /** TODO #9100 */ = [];
animate(
element: any, startingStyles: AnimationStyles, keyframes: AnimationKeyframe[],
duration: number, delay: number, easing: string): AnimationPlayer {
@@ -38,9 +38,11 @@ function _serializeKeyframes(keyframes: AnimationKeyframe[]): any[] {
}
function _serializeStyles(styles: AnimationStyles): {[key: string]: any} {
var flatStyles: {[key: string]: any} = {};
styles.styles.forEach(entry => StringMapWrapper.forEach(entry, (val: any, prop: string) => {
flatStyles[prop] = val;
}));
var flatStyles = {};
styles.styles.forEach(
entry => StringMapWrapper.forEach(
entry, (val: any /** TODO #9100 */, prop: any /** TODO #9100 */) => {
(flatStyles as any /** TODO #9100 */)[prop] = val;
}));
return flatStyles;
}
@@ -1,64 +0,0 @@
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
import {AnimationPlayer} from '../../core/src/animation/animation_player';
import {isPresent} from '../../core/src/facade/lang';
export class MockAnimationPlayer implements AnimationPlayer {
private _subscriptions: any[] /** TODO #9100 */ = [];
private _finished = false;
private _destroyed = false;
private _started: boolean = false;
public parentPlayer: AnimationPlayer = null;
public log: any[] /** TODO #9100 */ = [];
private _onfinish(): void {
if (!this._finished) {
this._finished = true;
this.log.push('finish');
this._subscriptions.forEach((entry) => { entry(); });
this._subscriptions = [];
if (!isPresent(this.parentPlayer)) {
this.destroy();
}
}
}
init(): void { this.log.push('init'); }
onDone(fn: Function): void { this._subscriptions.push(fn); }
hasStarted() { return this._started; }
play(): void {
this._started = true;
this.log.push('play');
}
pause(): void { this.log.push('pause'); }
restart(): void { this.log.push('restart'); }
finish(): void { this._onfinish(); }
reset(): void { this.log.push('reset'); }
destroy(): void {
if (!this._destroyed) {
this._destroyed = true;
this.finish();
this.log.push('destroy');
}
}
setPosition(p: any /** TODO #9100 */): void {}
getPosition(): number { return 0; }
}