refactor(animations): add an onStart handler for AnimationPlayer (#10360)
This commit is contained in:
parent
23a27776e2
commit
3c561475c8
|
@ -12,7 +12,8 @@ import {Math} from '../facade/math';
|
||||||
import {AnimationPlayer} from './animation_player';
|
import {AnimationPlayer} from './animation_player';
|
||||||
|
|
||||||
export class AnimationGroupPlayer implements AnimationPlayer {
|
export class AnimationGroupPlayer implements AnimationPlayer {
|
||||||
private _subscriptions: Function[] = [];
|
private _onDoneFns: Function[] = [];
|
||||||
|
private _onStartFns: Function[] = [];
|
||||||
private _finished = false;
|
private _finished = false;
|
||||||
private _started = false;
|
private _started = false;
|
||||||
|
|
||||||
|
@ -41,14 +42,16 @@ export class AnimationGroupPlayer implements AnimationPlayer {
|
||||||
if (!isPresent(this.parentPlayer)) {
|
if (!isPresent(this.parentPlayer)) {
|
||||||
this.destroy();
|
this.destroy();
|
||||||
}
|
}
|
||||||
this._subscriptions.forEach(subscription => subscription());
|
this._onDoneFns.forEach(fn => fn());
|
||||||
this._subscriptions = [];
|
this._onDoneFns = [];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
init(): void { this._players.forEach(player => player.init()); }
|
init(): void { this._players.forEach(player => player.init()); }
|
||||||
|
|
||||||
onDone(fn: Function): void { this._subscriptions.push(fn); }
|
onStart(fn: () => void): void { this._onStartFns.push(fn); }
|
||||||
|
|
||||||
|
onDone(fn: () => void): void { this._onDoneFns.push(fn); }
|
||||||
|
|
||||||
hasStarted() { return this._started; }
|
hasStarted() { return this._started; }
|
||||||
|
|
||||||
|
@ -56,7 +59,11 @@ export class AnimationGroupPlayer implements AnimationPlayer {
|
||||||
if (!isPresent(this.parentPlayer)) {
|
if (!isPresent(this.parentPlayer)) {
|
||||||
this.init();
|
this.init();
|
||||||
}
|
}
|
||||||
this._started = true;
|
if (!this.hasStarted()) {
|
||||||
|
this._onStartFns.forEach(fn => fn());
|
||||||
|
this._onStartFns = [];
|
||||||
|
this._started = true;
|
||||||
|
}
|
||||||
this._players.forEach(player => player.play());
|
this._players.forEach(player => player.play());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,8 @@ import {scheduleMicroTask} from '../facade/lang';
|
||||||
* @experimental Animation support is experimental.
|
* @experimental Animation support is experimental.
|
||||||
*/
|
*/
|
||||||
export abstract class AnimationPlayer {
|
export abstract class AnimationPlayer {
|
||||||
abstract onDone(fn: Function): void;
|
abstract onDone(fn: () => void): void;
|
||||||
|
abstract onStart(fn: () => void): void;
|
||||||
abstract init(): void;
|
abstract init(): void;
|
||||||
abstract hasStarted(): boolean;
|
abstract hasStarted(): boolean;
|
||||||
abstract play(): void;
|
abstract play(): void;
|
||||||
|
@ -32,19 +33,27 @@ export abstract class AnimationPlayer {
|
||||||
}
|
}
|
||||||
|
|
||||||
export class NoOpAnimationPlayer implements AnimationPlayer {
|
export class NoOpAnimationPlayer implements AnimationPlayer {
|
||||||
private _subscriptions: any[] /** TODO #9100 */ = [];
|
private _onDoneFns: Function[] = [];
|
||||||
|
private _onStartFns: Function[] = [];
|
||||||
private _started = false;
|
private _started = false;
|
||||||
public parentPlayer: AnimationPlayer = null;
|
public parentPlayer: AnimationPlayer = null;
|
||||||
constructor() { scheduleMicroTask(() => this._onFinish()); }
|
constructor() { scheduleMicroTask(() => this._onFinish()); }
|
||||||
/** @internal */
|
/** @internal */
|
||||||
_onFinish() {
|
_onFinish() {
|
||||||
this._subscriptions.forEach(entry => { entry(); });
|
this._onDoneFns.forEach(fn => fn());
|
||||||
this._subscriptions = [];
|
this._onDoneFns = [];
|
||||||
}
|
}
|
||||||
onDone(fn: Function): void { this._subscriptions.push(fn); }
|
onStart(fn: () => void): void { this._onStartFns.push(fn); }
|
||||||
|
onDone(fn: () => void): void { this._onDoneFns.push(fn); }
|
||||||
hasStarted(): boolean { return this._started; }
|
hasStarted(): boolean { return this._started; }
|
||||||
init(): void {}
|
init(): void {}
|
||||||
play(): void { this._started = true; }
|
play(): void {
|
||||||
|
if (!this.hasStarted()) {
|
||||||
|
this._onStartFns.forEach(fn => fn());
|
||||||
|
this._onStartFns = [];
|
||||||
|
}
|
||||||
|
this._started = true;
|
||||||
|
}
|
||||||
pause(): void {}
|
pause(): void {}
|
||||||
restart(): void {}
|
restart(): void {}
|
||||||
finish(): void { this._onFinish(); }
|
finish(): void { this._onFinish(); }
|
||||||
|
|
|
@ -13,7 +13,8 @@ import {AnimationPlayer, NoOpAnimationPlayer} from './animation_player';
|
||||||
export class AnimationSequencePlayer implements AnimationPlayer {
|
export class AnimationSequencePlayer implements AnimationPlayer {
|
||||||
private _currentIndex: number = 0;
|
private _currentIndex: number = 0;
|
||||||
private _activePlayer: AnimationPlayer;
|
private _activePlayer: AnimationPlayer;
|
||||||
private _subscriptions: Function[] = [];
|
private _onDoneFns: Function[] = [];
|
||||||
|
private _onStartFns: Function[] = [];
|
||||||
private _finished = false;
|
private _finished = false;
|
||||||
private _started: boolean = false;
|
private _started: boolean = false;
|
||||||
|
|
||||||
|
@ -50,14 +51,16 @@ export class AnimationSequencePlayer implements AnimationPlayer {
|
||||||
if (!isPresent(this.parentPlayer)) {
|
if (!isPresent(this.parentPlayer)) {
|
||||||
this.destroy();
|
this.destroy();
|
||||||
}
|
}
|
||||||
this._subscriptions.forEach(subscription => subscription());
|
this._onDoneFns.forEach(fn => fn());
|
||||||
this._subscriptions = [];
|
this._onDoneFns = [];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
init(): void { this._players.forEach(player => player.init()); }
|
init(): void { this._players.forEach(player => player.init()); }
|
||||||
|
|
||||||
onDone(fn: Function): void { this._subscriptions.push(fn); }
|
onStart(fn: () => void): void { this._onStartFns.push(fn); }
|
||||||
|
|
||||||
|
onDone(fn: () => void): void { this._onDoneFns.push(fn); }
|
||||||
|
|
||||||
hasStarted() { return this._started; }
|
hasStarted() { return this._started; }
|
||||||
|
|
||||||
|
@ -65,7 +68,11 @@ export class AnimationSequencePlayer implements AnimationPlayer {
|
||||||
if (!isPresent(this.parentPlayer)) {
|
if (!isPresent(this.parentPlayer)) {
|
||||||
this.init();
|
this.init();
|
||||||
}
|
}
|
||||||
this._started = true;
|
if (!this.hasStarted()) {
|
||||||
|
this._onStartFns.forEach(fn => fn());
|
||||||
|
this._onStartFns = [];
|
||||||
|
this._started = true;
|
||||||
|
}
|
||||||
this._activePlayer.play();
|
this._activePlayer.play();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -173,6 +173,18 @@ export function main() {
|
||||||
group.destroy();
|
group.destroy();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should run the onStart method when started but only once', () => {
|
||||||
|
var player = new AnimationGroupPlayer([]);
|
||||||
|
var calls = 0;
|
||||||
|
player.onStart(() => calls++);
|
||||||
|
expect(calls).toEqual(0);
|
||||||
|
player.play();
|
||||||
|
expect(calls).toEqual(1);
|
||||||
|
player.pause();
|
||||||
|
player.play();
|
||||||
|
expect(calls).toEqual(1);
|
||||||
|
});
|
||||||
|
|
||||||
it('should call onDone after the next microtask if no players are provided', fakeAsync(() => {
|
it('should call onDone after the next microtask if no players are provided', fakeAsync(() => {
|
||||||
var group = new AnimationGroupPlayer([]);
|
var group = new AnimationGroupPlayer([]);
|
||||||
var completed = false;
|
var completed = false;
|
||||||
|
|
|
@ -29,5 +29,17 @@ export function main() {
|
||||||
player.restart();
|
player.restart();
|
||||||
player.destroy();
|
player.destroy();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
it('should run the onStart method when started but only once', fakeAsync(() => {
|
||||||
|
var player = new NoOpAnimationPlayer();
|
||||||
|
var calls = 0;
|
||||||
|
player.onStart(() => calls++);
|
||||||
|
expect(calls).toEqual(0);
|
||||||
|
player.play();
|
||||||
|
expect(calls).toEqual(1);
|
||||||
|
player.pause();
|
||||||
|
player.play();
|
||||||
|
expect(calls).toEqual(1);
|
||||||
|
}));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -196,6 +196,18 @@ export function main() {
|
||||||
sequence.destroy();
|
sequence.destroy();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should run the onStart method when started but only once', () => {
|
||||||
|
var player = new AnimationSequencePlayer([]);
|
||||||
|
var calls = 0;
|
||||||
|
player.onStart(() => calls++);
|
||||||
|
expect(calls).toEqual(0);
|
||||||
|
player.play();
|
||||||
|
expect(calls).toEqual(1);
|
||||||
|
player.pause();
|
||||||
|
player.play();
|
||||||
|
expect(calls).toEqual(1);
|
||||||
|
});
|
||||||
|
|
||||||
it('should call onDone after the next microtask if no players are provided', fakeAsync(() => {
|
it('should call onDone after the next microtask if no players are provided', fakeAsync(() => {
|
||||||
var sequence = new AnimationSequencePlayer([]);
|
var sequence = new AnimationSequencePlayer([]);
|
||||||
var completed = false;
|
var completed = false;
|
||||||
|
|
|
@ -10,7 +10,8 @@ import {AnimationPlayer} from '../src/animation/animation_player';
|
||||||
import {isPresent} from '../src/facade/lang';
|
import {isPresent} from '../src/facade/lang';
|
||||||
|
|
||||||
export class MockAnimationPlayer implements AnimationPlayer {
|
export class MockAnimationPlayer implements AnimationPlayer {
|
||||||
private _subscriptions: any[] /** TODO #9100 */ = [];
|
private _onDoneFns: Function[] = [];
|
||||||
|
private _onStartFns: Function[] = [];
|
||||||
private _finished = false;
|
private _finished = false;
|
||||||
private _destroyed = false;
|
private _destroyed = false;
|
||||||
private _started: boolean = false;
|
private _started: boolean = false;
|
||||||
|
@ -19,13 +20,13 @@ export class MockAnimationPlayer implements AnimationPlayer {
|
||||||
|
|
||||||
public log: any[] /** TODO #9100 */ = [];
|
public log: any[] /** TODO #9100 */ = [];
|
||||||
|
|
||||||
private _onfinish(): void {
|
private _onFinish(): void {
|
||||||
if (!this._finished) {
|
if (!this._finished) {
|
||||||
this._finished = true;
|
this._finished = true;
|
||||||
this.log.push('finish');
|
this.log.push('finish');
|
||||||
|
|
||||||
this._subscriptions.forEach((entry) => { entry(); });
|
this._onDoneFns.forEach(fn => fn());
|
||||||
this._subscriptions = [];
|
this._onDoneFns = [];
|
||||||
if (!isPresent(this.parentPlayer)) {
|
if (!isPresent(this.parentPlayer)) {
|
||||||
this.destroy();
|
this.destroy();
|
||||||
}
|
}
|
||||||
|
@ -34,12 +35,18 @@ export class MockAnimationPlayer implements AnimationPlayer {
|
||||||
|
|
||||||
init(): void { this.log.push('init'); }
|
init(): void { this.log.push('init'); }
|
||||||
|
|
||||||
onDone(fn: Function): void { this._subscriptions.push(fn); }
|
onDone(fn: () => void): void { this._onDoneFns.push(fn); }
|
||||||
|
|
||||||
|
onStart(fn: () => void): void { this._onStartFns.push(fn); }
|
||||||
|
|
||||||
hasStarted() { return this._started; }
|
hasStarted() { return this._started; }
|
||||||
|
|
||||||
play(): void {
|
play(): void {
|
||||||
this._started = true;
|
if (!this.hasStarted()) {
|
||||||
|
this._onStartFns.forEach(fn => fn());
|
||||||
|
this._onStartFns = [];
|
||||||
|
this._started = true;
|
||||||
|
}
|
||||||
this.log.push('play');
|
this.log.push('play');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,7 +54,7 @@ export class MockAnimationPlayer implements AnimationPlayer {
|
||||||
|
|
||||||
restart(): void { this.log.push('restart'); }
|
restart(): void { this.log.push('restart'); }
|
||||||
|
|
||||||
finish(): void { this._onfinish(); }
|
finish(): void { this._onFinish(); }
|
||||||
|
|
||||||
reset(): void { this.log.push('reset'); }
|
reset(): void { this.log.push('reset'); }
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,8 @@ import {getDOM} from './dom_adapter';
|
||||||
import {DomAnimatePlayer} from './dom_animate_player';
|
import {DomAnimatePlayer} from './dom_animate_player';
|
||||||
|
|
||||||
export class WebAnimationsPlayer implements AnimationPlayer {
|
export class WebAnimationsPlayer implements AnimationPlayer {
|
||||||
private _subscriptions: Function[] = [];
|
private _onDoneFns: Function[] = [];
|
||||||
|
private _onStartFns: Function[] = [];
|
||||||
private _finished = false;
|
private _finished = false;
|
||||||
private _initialized = false;
|
private _initialized = false;
|
||||||
private _player: DomAnimatePlayer;
|
private _player: DomAnimatePlayer;
|
||||||
|
@ -37,8 +38,8 @@ export class WebAnimationsPlayer implements AnimationPlayer {
|
||||||
if (!isPresent(this.parentPlayer)) {
|
if (!isPresent(this.parentPlayer)) {
|
||||||
this.destroy();
|
this.destroy();
|
||||||
}
|
}
|
||||||
this._subscriptions.forEach(fn => fn());
|
this._onDoneFns.forEach(fn => fn());
|
||||||
this._subscriptions = [];
|
this._onDoneFns = [];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,10 +67,17 @@ export class WebAnimationsPlayer implements AnimationPlayer {
|
||||||
return <DomAnimatePlayer>element.animate(keyframes, options);
|
return <DomAnimatePlayer>element.animate(keyframes, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
onDone(fn: Function): void { this._subscriptions.push(fn); }
|
onStart(fn: () => void): void { this._onStartFns.push(fn); }
|
||||||
|
|
||||||
|
onDone(fn: () => void): void { this._onDoneFns.push(fn); }
|
||||||
|
|
||||||
play(): void {
|
play(): void {
|
||||||
this.init();
|
this.init();
|
||||||
|
if (!this.hasStarted()) {
|
||||||
|
this._onStartFns.forEach(fn => fn());
|
||||||
|
this._onStartFns = [];
|
||||||
|
this._started = true;
|
||||||
|
}
|
||||||
this._player.play();
|
this._player.play();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -128,5 +128,16 @@ export function main() {
|
||||||
expect(captures2['finish'].length).toEqual(1);
|
expect(captures2['finish'].length).toEqual(1);
|
||||||
expect(captures2['cancel'].length).toEqual(0);
|
expect(captures2['cancel'].length).toEqual(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should run the onStart method when started but only once', () => {
|
||||||
|
var calls = 0;
|
||||||
|
player.onStart(() => calls++);
|
||||||
|
expect(calls).toEqual(0);
|
||||||
|
player.play();
|
||||||
|
expect(calls).toEqual(1);
|
||||||
|
player.pause();
|
||||||
|
player.play();
|
||||||
|
expect(calls).toEqual(1);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,7 +69,8 @@ export declare abstract class AnimationPlayer {
|
||||||
abstract getPosition(): number;
|
abstract getPosition(): number;
|
||||||
abstract hasStarted(): boolean;
|
abstract hasStarted(): boolean;
|
||||||
abstract init(): void;
|
abstract init(): void;
|
||||||
abstract onDone(fn: Function): void;
|
abstract onDone(fn: () => void): void;
|
||||||
|
abstract onStart(fn: () => void): void;
|
||||||
abstract pause(): void;
|
abstract pause(): void;
|
||||||
abstract play(): void;
|
abstract play(): void;
|
||||||
abstract reset(): void;
|
abstract reset(): void;
|
||||||
|
|
Loading…
Reference in New Issue