From ef96763fa4c2ad94e1890e272a6e3a9fbe50f550 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matias=20Niemel=C3=A4?= Date: Mon, 21 Nov 2016 15:46:59 -0800 Subject: [PATCH] fix(animations): blend in all previously transitioned styles into next animation if interrupted (#13014) Closes #13013 Closes #13014 --- .../src/dom/web_animations_driver.ts | 4 +-- .../src/dom/web_animations_player.ts | 29 ++++++++----------- .../test/dom/web_animations_player_spec.ts | 26 +++++++++++++++++ 3 files changed, 39 insertions(+), 20 deletions(-) diff --git a/modules/@angular/platform-browser/src/dom/web_animations_driver.ts b/modules/@angular/platform-browser/src/dom/web_animations_driver.ts index 0ee68f936c..ab6cfb41dc 100644 --- a/modules/@angular/platform-browser/src/dom/web_animations_driver.ts +++ b/modules/@angular/platform-browser/src/dom/web_animations_driver.ts @@ -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) => { diff --git a/modules/@angular/platform-browser/src/dom/web_animations_player.ts b/modules/@angular/platform-browser/src/dom/web_animations_player.ts index 627a8055c6..89fd3fa83f 100644 --- a/modules/@angular/platform-browser/src/dom/web_animations_player.ts +++ b/modules/@angular/platform-browser/src/dom/web_animations_player.ts @@ -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); @@ -176,17 +185,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; -} diff --git a/modules/@angular/platform-browser/test/dom/web_animations_player_spec.ts b/modules/@angular/platform-browser/test/dom/web_animations_player_spec.ts index 8072279501..3092ee9365 100644 --- a/modules/@angular/platform-browser/test/dom/web_animations_player_spec.ts +++ b/modules/@angular/platform-browser/test/dom/web_animations_player_spec.ts @@ -202,6 +202,32 @@ export function main() { ]); }); + it('should allow previous styles to be merged into the starting keyframe of the animation that were not apart of the animation to begin with', + () => { + if (!getDOM().supportsWebAnimation()) return; + + const elm = el('
'); + document.body.appendChild(elm); + elm.style.color = 'rgb(0,0,0)'; + + const previousStyles = {color: 'red'}; + const previousPlayer = + new ExtendedWebAnimationsPlayer(elm, [previousStyles, previousStyles], {}, []); + previousPlayer.play(); + previousPlayer.finish(); + + const player = new ExtendedWebAnimationsPlayer( + elm, [{opacity: '0'}, {opacity: '1'}], {duration: 1000}, [previousPlayer]); + + player.init(); + + const data = player.domPlayer.captures['trigger'][0]; + expect(data['keyframes']).toEqual([ + {opacity: '0', color: 'red'}, + {opacity: '1', color: 'rgb(0, 0, 0)'}, + ]); + }); + it('should properly calculate the previous styles for the player even when its currently playing', () => { if (!getDOM().supportsWebAnimation()) return;