fix issue with onFinish being called out of order. added tests

This commit is contained in:
Liam DeBeasi
2019-07-29 12:45:27 -04:00
parent 085f5df0b7
commit b3f6219e03
5 changed files with 79 additions and 103 deletions

View File

@@ -50,7 +50,7 @@ export const createAnimation = () => {
const _afterAddReadFunctions: any[] = [];
const _afterAddWriteFunctions: any[] = [];
const supportsWebAnimations = !!(window as any).Animation && _forceCSSAnimations !== null;
const supportsWebAnimations = !!(window as any).Animation && _forceCSSAnimations === null;
/**
* Destroy this animation and all child animations.
@@ -445,10 +445,10 @@ export const createAnimation = () => {
if (numAnimationsRunning === 0) {
afterAnimation();
}
if (parentAnimation) {
parentAnimation.animationFinish();
if (parentAnimation) {
parentAnimation.animationFinish();
}
}
};

View File

@@ -11,7 +11,6 @@ test(`animation:web: basic`, async () => {
const ANIMATION_FINISHED = 'onIonAnimationFinished';
const animationFinishedCount: any = { count: 0 };
await page.exposeFunction(ANIMATION_FINISHED, () => {
console.log('yay');
animationFinishedCount.count += 1;
});
@@ -30,9 +29,6 @@ test(`animation:web: basic`, async () => {
test(`animation:css: basic`, async () => {
const page = await newE2EPage({ url: '/src/utils/animation/test/basic?ionic:_forceCSSAnimations=true' });
page.evaluate(() => window.Ionic.config._forceCSSAnimations = true);
const screenshotCompares = [];
screenshotCompares.push(await page.compareScreenshot());

View File

@@ -9,63 +9,45 @@ test(`animation:web: multiple`, async () => {
screenshotCompares.push(await page.compareScreenshot());
const ANIMATION_FINISHED = 'onIonAnimationFinished';
const animationStatus: any = {
'AnimationRootFinished': false,
'AnimationAFinished': false,
'AnimationBFinished': false,
'AnimationCFinished': false,
'AnimationCSubAFinished': false
};
const animationStatus = [];
await page.exposeFunction(ANIMATION_FINISHED, (ev: any) => {
console.log(ev.detail)
// need to check state of animations for on each event
animationStatus[ev.detail] = true;
console.log(animationStatus)
animationStatus.push(ev.detail);
});
const squareA = await page.$('.square-a');
await listenForEvent(page, 'ionAnimationFinished', squareA, ANIMATION_FINISHED)
await listenForEvent(page, 'ionAnimationFinished', squareA, ANIMATION_FINISHED);
await page.click('.play');
await page.waitForSelector('.play');
await waitForFunctionTestContext((payload: any) => {
return payload.animationStatus['AnimationRootFinished'] === true;
}, { animationStatus });
// need to ensure all other animations resolved
await waitForFunctionTestContext((payload: any) => {
return payload.animationStatus.join(', ') === ['AnimationBFinished', 'AnimationCSubAFinished', 'AnimationCFinished', 'AnimationAFinished', 'AnimationRootFinished'].join(', ');
}, { animationStatus });
screenshotCompares.push(await page.compareScreenshot());
});
/*
test(`animation:css: basic`, async () => {
const page = await newE2EPage({ url: '/src/utils/animation/test/basic?ionic:_forceCSSAnimations=true' });
page.evaluate(() => window.Ionic.config._forceCSSAnimations = true);
test(`animation:css: multiple`, async () => {
const page = await newE2EPage({ url: '/src/utils/animation/test/multiple?ionic:_forceCSSAnimations=true' });
const screenshotCompares = [];
screenshotCompares.push(await page.compareScreenshot());
const ANIMATION_FINISHED = 'onIonAnimationFinished';
const animationFinishedCount: any = { count: 0 };
await page.exposeFunction(ANIMATION_FINISHED, () => {
animationFinishedCount.count += 1;
const animationStatus = [];
await page.exposeFunction(ANIMATION_FINISHED, (ev: any) => {
animationStatus.push(ev.detail);
});
const square = await page.$('.square-a');
await listenForEvent(page, 'ionAnimationFinished', square, ANIMATION_FINISHED);
const squareA = await page.$('.square-a');
await listenForEvent(page, 'ionAnimationFinished', squareA, ANIMATION_FINISHED);
await page.click('.play');
await page.waitForSelector('.play');
await waitForFunctionTestContext((payload: any) => {
return payload.animationFinishedCount.count === 1;
}, { animationFinishedCount });
return payload.animationStatus.join(', ') === ['AnimationBFinished', 'AnimationCSubAFinished', 'AnimationCFinished', 'AnimationAFinished', 'AnimationRootFinished'].join(', ');
}, { animationStatus });
screenshotCompares.push(await page.compareScreenshot());
});
*/

View File

@@ -20,16 +20,15 @@
const squareCText = document.querySelectorAll('.square-c .text');
const rootAnimation = createAnimation();
const animationA = createAnimation('animation-a');
const animationB = createAnimation('animation-b');
const animationC = createAnimation('animation-c');
const animationCSubA = createAnimation('animation-c-sub-a');
const animationA = createAnimation();
const animationB = createAnimation();
const animationC = createAnimation();
const animationCSubA = createAnimation();
animationA
.addElement(squareA)
.duration(2000)
.delay(5000)
.duration(500)
.delay(3500)
.easing('linear')
.iterations(1)
.keyframes([
@@ -51,7 +50,7 @@
animationB
.addElement(squareB)
.duration(500)
.delay(2000)
.delay(1000)
.easing('ease-in-out')
.iterations(1)
.keyframes([
@@ -72,7 +71,7 @@
animationC
.addElement(squareC)
.duration(2000)
.duration(1000)
.delay(500)
.easing('ease-in-out')
.iterations(1)
@@ -94,8 +93,8 @@
animationCSubA
.addElement(squareCText)
.duration(1000)
.delay(3000)
.duration(500)
.delay(2000)
.fromTo('color', 'red', 'blue')
.onFinish(() => {
const ev = new CustomEvent('ionAnimationFinished', { detail: 'AnimationCSubAFinished' });

View File

@@ -2,61 +2,60 @@ import { IonicAnimation } from '../../interface';
import { createAnimation } from '../animation/animation';
import { TransitionOptions } from '../transition';
export const mdTransitionAnimation = (opts: TransitionOptions): IonicAnimation => {
try {
const OFF_BOTTOM = '40px';
const CENTER = '0px';
export const mdTransitionAnimation = (_: HTMLElement, opts: TransitionOptions): IonicAnimation => {
const OFF_BOTTOM = '40px';
const CENTER = '0px';
const rootAnimation = createAnimation();
const backDirection = (opts.direction === 'back');
const enteringEl = opts.enteringEl;
const leavingEl = opts.leavingEl;
const enteringEl = opts.enteringEl;
const leavingEl = opts.leavingEl;
const backDirection = (opts.direction === 'back');
const ionPageElement = getIonPageElement(enteringEl);
const enteringToolbarEle = ionPageElement.querySelector('ion-toolbar');
const rootTransition = createAnimation();
const ionPageElement = getIonPageElement(enteringEl);
const enteringToolbarEle = ionPageElement.querySelector('ion-toolbar');
rootTransition
.addElement(ionPageElement)
.beforeRemoveClass('ion-page-invisible');
rootAnimation
.addElement(ionPageElement)
.beforeRemoveClass('ion-page-invisible')
.fill('both');
// animate the component itself
if (backDirection) {
rootTransition
.duration(opts.duration || 200)
.easing('cubic-bezier(0.47,0,0.745,0.715)');
if (backDirection) {
rootAnimation
.duration(opts.duration || 200)
.easing('cubic-bezier(0.47,0,0.745,0.715)');
} else {
rootAnimation
.duration(opts.duration || 280)
.easing('cubic-bezier(0.36,0.66,0.04,1)')
.fromTo('transform', `translateY(${OFF_BOTTOM})`, `translateY(${CENTER})`)
.fromTo('opacity', 0.01, 1);
}
if (enteringToolbarEle) {
const enteringToolBarAnimation = createAnimation();
enteringToolBarAnimation.addElement(enteringToolbarEle);
rootAnimation.addAnimation(enteringToolBarAnimation);
}
if (leavingEl && backDirection) {
rootAnimation
.duration(opts.duration || 200)
.easing('cubic-bezier(0.47,0,0.745,0.715)');
const leavingPageAnimation = createAnimation();
leavingPageAnimation
.addElement(getIonPageElement(leavingEl))
.fromTo('transform', `translateY(${CENTER})`, `translateY(${OFF_BOTTOM})`)
.fromTo('opacity', 1, 0);
rootAnimation.addAnimation(leavingPageAnimation);
}
return rootAnimation;
} catch (err) {
throw err;
} else {
rootTransition
.duration(opts.duration || 280)
.easing('cubic-bezier(0.36,0.66,0.04,1)')
.fromTo('transform', `translateY(${OFF_BOTTOM})`, `translateY(${CENTER})`)
.fromTo('opacity', 0.01, 1);
}
// Animate toolbar if it's there
if (enteringToolbarEle) {
const enteringToolBar = createAnimation();
enteringToolBar.addElement(enteringToolbarEle);
rootTransition.addAnimation(enteringToolBar);
}
// setup leaving view
if (leavingEl && backDirection) {
// leaving content
rootTransition
.duration(opts.duration || 200)
.easing('cubic-bezier(0.47,0,0.745,0.715)');
const leavingPage = createAnimation();
leavingPage
.addElement(getIonPageElement(leavingEl))
.fromTo('transform', `translateY(${CENTER})`, `translateY(${OFF_BOTTOM})`)
.fromTo('opacity', 1, 0);
rootTransition.addAnimation(leavingPage);
}
return rootTransition;
};
const getIonPageElement = (element: HTMLElement) => {