fix(animations): make sure easing values work with web-animations (#15195)

Closes #15115
Closes #15195

PR Close #15195
This commit is contained in:
Matias Niemelä 2017-03-15 19:50:19 -07:00 committed by Miško Hevery
parent 2a0e55ffb5
commit f92591054b
2 changed files with 31 additions and 23 deletions

View File

@ -267,14 +267,18 @@ export class AnimationTimelineVisitor implements AnimationDslVisitor {
const normalizedStyles = normalizeStyles(ast.styles); const normalizedStyles = normalizeStyles(ast.styles);
const easing = context.currentAnimateTimings && context.currentAnimateTimings.easing; const easing = context.currentAnimateTimings && context.currentAnimateTimings.easing;
if (easing) { this._applyStyles(normalizedStyles, easing, context);
normalizedStyles['easing'] = easing;
}
context.currentTimeline.setStyles(normalizedStyles);
context.previousNode = ast; context.previousNode = ast;
} }
private _applyStyles(styles: ɵStyleData, easing: string, context: AnimationTimelineContext) {
if (styles.hasOwnProperty('easing')) {
easing = easing || styles['easing'] as string;
delete styles['easing'];
}
context.currentTimeline.setStyles(styles, easing);
}
visitKeyframeSequence( visitKeyframeSequence(
ast: AnimationKeyframesSequenceMetadata, context: AnimationTimelineContext) { ast: AnimationKeyframesSequenceMetadata, context: AnimationTimelineContext) {
const MAX_KEYFRAME_OFFSET = 1; const MAX_KEYFRAME_OFFSET = 1;
@ -299,7 +303,7 @@ export class AnimationTimelineVisitor implements AnimationDslVisitor {
(step.offset != null ? step.offset : parseFloat(normalizedStyles['offset'] as string)) : (step.offset != null ? step.offset : parseFloat(normalizedStyles['offset'] as string)) :
(i == limit ? MAX_KEYFRAME_OFFSET : i * offsetGap); (i == limit ? MAX_KEYFRAME_OFFSET : i * offsetGap);
innerTimeline.forwardTime(offset * duration); innerTimeline.forwardTime(offset * duration);
innerTimeline.setStyles(normalizedStyles); this._applyStyles(normalizedStyles, null, innerContext);
}); });
// this will ensure that the parent timeline gets all the styles from // this will ensure that the parent timeline gets all the styles from
@ -316,6 +320,7 @@ export class AnimationTimelineVisitor implements AnimationDslVisitor {
export class TimelineBuilder { export class TimelineBuilder {
public duration: number = 0; public duration: number = 0;
public easing: string = ''; public easing: string = '';
private _previousKeyframe: ɵStyleData = {};
private _currentKeyframe: ɵStyleData; private _currentKeyframe: ɵStyleData;
private _keyframes = new Map<number, ɵStyleData>(); private _keyframes = new Map<number, ɵStyleData>();
private _styleSummary: {[prop: string]: StyleAtTime} = {}; private _styleSummary: {[prop: string]: StyleAtTime} = {};
@ -339,6 +344,9 @@ export class TimelineBuilder {
} }
private _loadKeyframe() { private _loadKeyframe() {
if (this._currentKeyframe) {
this._previousKeyframe = this._currentKeyframe;
}
this._currentKeyframe = this._keyframes.get(this.duration); this._currentKeyframe = this._keyframes.get(this.duration);
if (!this._currentKeyframe) { if (!this._currentKeyframe) {
this._currentKeyframe = Object.create(this._backFill, {}); this._currentKeyframe = Object.create(this._backFill, {});
@ -357,19 +365,20 @@ export class TimelineBuilder {
} }
private _updateStyle(prop: string, value: string|number) { private _updateStyle(prop: string, value: string|number) {
if (prop != 'easing') { this._localTimelineStyles[prop] = value;
this._localTimelineStyles[prop] = value; this._globalTimelineStyles[prop] = value;
this._globalTimelineStyles[prop] = value; this._styleSummary[prop] = {time: this.currentTime, value};
this._styleSummary[prop] = {time: this.currentTime, value};
}
} }
setStyles(styles: ɵStyleData) { setStyles(styles: ɵStyleData, easing: string = null) {
if (easing) {
this._previousKeyframe['easing'] = easing;
}
Object.keys(styles).forEach(prop => { Object.keys(styles).forEach(prop => {
if (prop !== 'offset') { if (prop !== 'offset') {
const val = styles[prop]; const val = styles[prop];
this._currentKeyframe[prop] = val; this._currentKeyframe[prop] = val;
if (prop !== 'easing' && !this._localTimelineStyles[prop]) { if (!this._localTimelineStyles[prop]) {
this._backFill[prop] = this._globalTimelineStyles[prop] || AUTO_STYLE; this._backFill[prop] = this._globalTimelineStyles[prop] || AUTO_STYLE;
} }
this._updateStyle(prop, val); this._updateStyle(prop, val);

View File

@ -160,9 +160,9 @@ export function main() {
]; ];
const player = invokeAnimationSequence(steps)[0]; const player = invokeAnimationSequence(steps)[0];
const lastKeyframe = player.keyframes[1]; const firstKeyframe = player.keyframes[0];
const lastKeyframeEasing = <string>lastKeyframe['easing']; const firstKeyframeEasing = firstKeyframe['easing'] as string;
expect(lastKeyframeEasing.replace(/\s+/g, '')).toEqual('cubic-bezier(.29,.55,.53,1.53)'); expect(firstKeyframeEasing.replace(/\s+/g, '')).toEqual('cubic-bezier(.29,.55,.53,1.53)');
}); });
}); });
@ -524,8 +524,8 @@ export function main() {
const player = invokeAnimationSequence(steps)[0]; const player = invokeAnimationSequence(steps)[0];
expect(player.keyframes).toEqual([ expect(player.keyframes).toEqual([
{opacity: 0, offset: 0}, {opacity: 0, offset: .25}, {opacity: 0, offset: 0}, {opacity: 0, offset: .25, easing: 'ease-out'},
{opacity: 1, offset: 1, easing: 'ease-out'} {opacity: 1, offset: 1}
]); ]);
}); });
@ -540,9 +540,8 @@ export function main() {
const player = players[0]; const player = players[0];
expect(player.keyframes).toEqual([ expect(player.keyframes).toEqual([
{width: 0, offset: 0}, {width: 10, offset: .25, easing: 'linear'}, {width: 0, offset: 0, easing: 'linear'}, {width: 10, offset: .25, easing: 'ease-out'},
{width: 20, offset: .75, easing: 'ease-out'}, {width: 20, offset: .75, easing: 'ease-in'}, {width: 30, offset: 1}
{width: 30, offset: 1, easing: 'ease-in'}
]); ]);
}); });
@ -626,8 +625,8 @@ export function main() {
const players = invokeAnimationSequence(steps, fromStyles, toStyles); const players = invokeAnimationSequence(steps, fromStyles, toStyles);
expect(players[0].keyframes).toEqual([ expect(players[0].keyframes).toEqual([
{background: 'blue', offset: 0}, {background: 'blue', offset: 0, easing: 'ease-out'},
{background: 'red', easing: 'ease-out', offset: 1} {background: 'red', offset: 1}
]); ]);
}); });
}); });