fix(animations): repair flicker issues with WA polyfill (#16937)
Fixes #16919 Fixes #16918
This commit is contained in:
parent
08dfe91b95
commit
e7d9fd8056
|
@ -5,6 +5,8 @@
|
|||
* 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 {dashCaseToCamelCase} from '../../util';
|
||||
|
||||
import {AnimationStyleNormalizer} from './animation_style_normalizer';
|
||||
|
||||
export class WebAnimationsStyleNormalizer extends AnimationStyleNormalizer {
|
||||
|
@ -41,8 +43,3 @@ function makeBooleanMap(keys: string[]): {[key: string]: boolean} {
|
|||
keys.forEach(key => map[key] = true);
|
||||
return map;
|
||||
}
|
||||
|
||||
const DASH_CASE_REGEXP = /-+([a-z0-9])/g;
|
||||
export function dashCaseToCamelCase(input: string): string {
|
||||
return input.replace(DASH_CASE_REGEXP, (...m: any[]) => m[1].toUpperCase());
|
||||
}
|
||||
|
|
|
@ -997,9 +997,8 @@ export class TransitionAnimationEngine {
|
|||
});
|
||||
|
||||
allConsumedElements.forEach(element => addClass(element, NG_ANIMATING_CLASSNAME));
|
||||
|
||||
const player = optimizeGroupPlayer(allNewPlayers);
|
||||
player.onDone(() => {
|
||||
player.onDestroy(() => {
|
||||
allConsumedElements.forEach(element => removeClass(element, NG_ANIMATING_CLASSNAME));
|
||||
setStyles(rootElement, instruction.toStyles);
|
||||
});
|
||||
|
|
|
@ -53,6 +53,11 @@ export class WebAnimationsPlayer implements AnimationPlayer {
|
|||
}
|
||||
|
||||
init(): void {
|
||||
this._buildPlayer();
|
||||
this._preparePlayerBeforeStart();
|
||||
}
|
||||
|
||||
private _buildPlayer(): void {
|
||||
if (this._initialized) return;
|
||||
this._initialized = true;
|
||||
|
||||
|
@ -82,14 +87,16 @@ export class WebAnimationsPlayer implements AnimationPlayer {
|
|||
|
||||
this._player = this._triggerWebAnimation(this.element, keyframes, this.options);
|
||||
this._finalKeyframe = keyframes.length ? keyframes[keyframes.length - 1] : {};
|
||||
this._player.addEventListener('finish', () => this._onFinish());
|
||||
}
|
||||
|
||||
private _preparePlayerBeforeStart() {
|
||||
// this is required so that the player doesn't start to animate right away
|
||||
if (this._delay) {
|
||||
this._resetDomPlayerState();
|
||||
} else {
|
||||
this._player.pause();
|
||||
}
|
||||
this._player.addEventListener('finish', () => this._onFinish());
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
|
@ -108,7 +115,7 @@ export class WebAnimationsPlayer implements AnimationPlayer {
|
|||
onDestroy(fn: () => void): void { this._onDestroyFns.push(fn); }
|
||||
|
||||
play(): void {
|
||||
this.init();
|
||||
this._buildPlayer();
|
||||
if (!this.hasStarted()) {
|
||||
this._onStartFns.forEach(fn => fn());
|
||||
this._onStartFns = [];
|
||||
|
|
|
@ -123,16 +123,18 @@ export function copyStyles(
|
|||
|
||||
export function setStyles(element: any, styles: ɵStyleData) {
|
||||
if (element['style']) {
|
||||
Object.keys(styles).forEach(prop => element.style[prop] = styles[prop]);
|
||||
Object.keys(styles).forEach(prop => {
|
||||
const camelProp = dashCaseToCamelCase(prop);
|
||||
element.style[camelProp] = styles[prop];
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export function eraseStyles(element: any, styles: ɵStyleData) {
|
||||
if (element['style']) {
|
||||
Object.keys(styles).forEach(prop => {
|
||||
// IE requires '' instead of null
|
||||
// see https://github.com/angular/angular/issues/7916
|
||||
element.style[prop] = '';
|
||||
const camelProp = dashCaseToCamelCase(prop);
|
||||
element.style[camelProp] = '';
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -206,3 +208,8 @@ export function mergeAnimationOptions(
|
|||
}
|
||||
return destination;
|
||||
}
|
||||
|
||||
const DASH_CASE_REGEXP = /-+([a-z0-9])/g;
|
||||
export function dashCaseToCamelCase(input: string): string {
|
||||
return input.replace(DASH_CASE_REGEXP, (...m: any[]) => m[1].toUpperCase());
|
||||
}
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
/**
|
||||
* @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 {DOMAnimation} from '../../../src/render/web_animations/dom_animation';
|
||||
import {WebAnimationsPlayer} from '../../../src/render/web_animations/web_animations_player';
|
||||
|
||||
export function main() {
|
||||
let element: any;
|
||||
let innerPlayer: MockDomAnimation|null = null;
|
||||
beforeEach(() => {
|
||||
element = {};
|
||||
element['animate'] = () => { return innerPlayer = new MockDomAnimation(); };
|
||||
});
|
||||
|
||||
describe('WebAnimationsPlayer tests', () => {
|
||||
it('should automatically pause the player when created and initialized', () => {
|
||||
const keyframes = [
|
||||
{opacity: 0, offset: 0},
|
||||
{opacity: 1, offset: 1},
|
||||
];
|
||||
|
||||
const player = new WebAnimationsPlayer(element, keyframes, {duration: 1000});
|
||||
|
||||
player.init();
|
||||
const p = innerPlayer !;
|
||||
expect(p.log).toEqual(['pause']);
|
||||
|
||||
player.play();
|
||||
expect(p.log).toEqual(['pause', 'play']);
|
||||
});
|
||||
|
||||
it('should not pause the player if created and started before initialized', () => {
|
||||
const keyframes = [
|
||||
{opacity: 0, offset: 0},
|
||||
{opacity: 1, offset: 1},
|
||||
];
|
||||
|
||||
const player = new WebAnimationsPlayer(element, keyframes, {duration: 1000});
|
||||
|
||||
player.play();
|
||||
const p = innerPlayer !;
|
||||
expect(p.log).toEqual(['play']);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
class MockDomAnimation implements DOMAnimation {
|
||||
log: string[] = [];
|
||||
cancel(): void { this.log.push('cancel'); }
|
||||
play(): void { this.log.push('play'); }
|
||||
pause(): void { this.log.push('pause'); }
|
||||
finish(): void { this.log.push('finish'); }
|
||||
onfinish: Function = () => {};
|
||||
position: number = 0;
|
||||
currentTime: number = 0;
|
||||
addEventListener(eventName: string, handler: (event: any) => any): any {}
|
||||
dispatchEvent(eventName: string): any {}
|
||||
}
|
Loading…
Reference in New Issue