Skip to content

Commit

Permalink
fix(animations): repair flicker issues with WA polyfill (#16937)
Browse files Browse the repository at this point in the history
Fixes #16919
Fixes #16918
  • Loading branch information
matsko authored and chuckjaz committed May 22, 2017
1 parent 08dfe91 commit e7d9fd8
Show file tree
Hide file tree
Showing 7 changed files with 85 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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());
}
Original file line number Diff line number Diff line change
Expand Up @@ -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);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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 */
Expand All @@ -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 = [];
Expand Down
15 changes: 11 additions & 4 deletions packages/animations/browser/src/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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] = '';
});
}
}
Expand Down Expand Up @@ -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());
}
Original file line number Diff line number Diff line change
@@ -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 {}
}

0 comments on commit e7d9fd8

Please sign in to comment.