mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2026-03-13 10:22:08 +08:00
fix issue with onFinish being called out of order. added tests
This commit is contained in:
@@ -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();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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());
|
||||
});
|
||||
*/
|
||||
|
||||
@@ -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' });
|
||||
|
||||
@@ -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) => {
|
||||
|
||||
Reference in New Issue
Block a user