fix(core): animations should blend in all previously transitioned styles into next animation if interrupted (#13148)
This commit is contained in:

committed by
Igor Minar

parent
1bd04e95de
commit
889b48d85f
@ -20,10 +20,8 @@ export class WebAnimationsDriver implements AnimationDriver {
|
||||
previousPlayers: AnimationPlayer[] = []): WebAnimationsPlayer {
|
||||
let formattedSteps: {[key: string]: string | number}[] = [];
|
||||
let startingStyleLookup: {[key: string]: string | number} = {};
|
||||
if (isPresent(startingStyles) && startingStyles.styles.length > 0) {
|
||||
if (isPresent(startingStyles)) {
|
||||
startingStyleLookup = _populateStyles(startingStyles, {});
|
||||
startingStyleLookup['offset'] = 0;
|
||||
formattedSteps.push(startingStyleLookup);
|
||||
}
|
||||
|
||||
keyframes.forEach((keyframe: AnimationKeyframe) => {
|
||||
@ -32,14 +30,18 @@ export class WebAnimationsDriver implements AnimationDriver {
|
||||
formattedSteps.push(data);
|
||||
});
|
||||
|
||||
// this is a special case when only styles are applied as an
|
||||
// animation. When this occurs we want to animate from start to
|
||||
// end with the same values. Removing the offset and having only
|
||||
// start/end values is suitable enough for the web-animations API
|
||||
if (formattedSteps.length == 1) {
|
||||
const start = formattedSteps[0];
|
||||
start['offset'] = null;
|
||||
formattedSteps = [start, start];
|
||||
// Styling passed into element.animate() must always be balanced.
|
||||
// The special cases below can occur if only style() calls exist
|
||||
// within an animation or when a style() calls are used prior
|
||||
// to a group() animation being issued or if the renderer is
|
||||
// invoked by the user directly.
|
||||
if (formattedSteps.length == 0) {
|
||||
formattedSteps = [startingStyleLookup, startingStyleLookup];
|
||||
} else if (formattedSteps.length == 1) {
|
||||
const start = startingStyleLookup;
|
||||
const end = formattedSteps[0];
|
||||
end['offset'] = null;
|
||||
formattedSteps = [start, end];
|
||||
}
|
||||
|
||||
const playerOptions: {[key: string]: string | number} = {
|
||||
|
@ -69,12 +69,21 @@ export class WebAnimationsPlayer implements AnimationPlayer {
|
||||
|
||||
const previousStyleProps = Object.keys(this.previousStyles);
|
||||
if (previousStyleProps.length) {
|
||||
let startingKeyframe = findStartingKeyframe(keyframes);
|
||||
let startingKeyframe = keyframes[0];
|
||||
let missingStyleProps: string[] = [];
|
||||
previousStyleProps.forEach(prop => {
|
||||
if (isPresent(startingKeyframe[prop])) {
|
||||
startingKeyframe[prop] = this.previousStyles[prop];
|
||||
if (!isPresent(startingKeyframe[prop])) {
|
||||
missingStyleProps.push(prop);
|
||||
}
|
||||
startingKeyframe[prop] = this.previousStyles[prop];
|
||||
});
|
||||
|
||||
if (missingStyleProps.length) {
|
||||
for (let i = 1; i < keyframes.length; i++) {
|
||||
let kf = keyframes[i];
|
||||
missingStyleProps.forEach(prop => { kf[prop] = _computeStyle(this.element, prop); });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this._player = this._triggerWebAnimation(this.element, keyframes, this.options);
|
||||
@ -180,17 +189,3 @@ function _copyKeyframeStyles(styles: {[style: string]: string | number}):
|
||||
});
|
||||
return newStyles;
|
||||
}
|
||||
|
||||
function findStartingKeyframe(keyframes: {[prop: string]: string | number}[]):
|
||||
{[prop: string]: string | number} {
|
||||
let startingKeyframe = keyframes[0];
|
||||
// it's important that we find the LAST keyframe
|
||||
// to ensure that style overidding is final.
|
||||
for (let i = 1; i < keyframes.length; i++) {
|
||||
const kf = keyframes[i];
|
||||
const offset = kf['offset'];
|
||||
if (offset !== 0) break;
|
||||
startingKeyframe = kf;
|
||||
}
|
||||
return startingKeyframe;
|
||||
}
|
||||
|
Reference in New Issue
Block a user