diff --git a/CHANGELOG.md b/CHANGELOG.md index a0f68f2cfb..0d84562475 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,15 @@ +## [4.8.1](https://github.com/ionic-team/ionic/compare/v4.8.0...v4.8.1) (2019-08-27) + + +### Bug Fixes + +* **animation:** enable backwards compatibility for overlay animations ([#19160](https://github.com/ionic-team/ionic/issues/19160)) ([fb70980](https://github.com/ionic-team/ionic/commit/fb70980)) +* **gesture:** account for negative step values with Web Animations ([#19196](https://github.com/ionic-team/ionic/issues/19196)) ([b3c7436](https://github.com/ionic-team/ionic/commit/b3c7436)) +* **ios:** clear opacity on toolbar background after iOS transition ([#19169](https://github.com/ionic-team/ionic/issues/19169)) ([fa958a5](https://github.com/ionic-team/ionic/commit/fa958a5)) +* **md:** set fill mode on MD transition to `both` ([#19161](https://github.com/ionic-team/ionic/issues/19161)) ([0e8ab49](https://github.com/ionic-team/ionic/commit/0e8ab49)) + + + # [4.8.0 Oxygen](https://github.com/ionic-team/ionic/compare/v4.7.4...v4.8.0) (2019-08-21) diff --git a/angular/package.json b/angular/package.json index 75e0fef7f2..2cc5e5c9a5 100644 --- a/angular/package.json +++ b/angular/package.json @@ -1,6 +1,6 @@ { "name": "@ionic/angular", - "version": "4.8.0", + "version": "4.8.1", "description": "Angular specific wrappers for @ionic/core", "keywords": [ "ionic", @@ -49,7 +49,7 @@ "css/" ], "dependencies": { - "@ionic/core": "4.8.0", + "@ionic/core": "4.8.1", "tslib": "^1.9.3" }, "peerDependencies": { diff --git a/core/package.json b/core/package.json index 68bb49129e..1c47c847ee 100644 --- a/core/package.json +++ b/core/package.json @@ -1,6 +1,6 @@ { "name": "@ionic/core", - "version": "4.8.0", + "version": "4.8.1", "description": "Base components for Ionic", "keywords": [ "ionic", diff --git a/core/src/components/menu/menu.tsx b/core/src/components/menu/menu.tsx index 68aa6ceee4..8d4eeeb09f 100644 --- a/core/src/components/menu/menu.tsx +++ b/core/src/components/menu/menu.tsx @@ -415,6 +415,14 @@ export class Menu implements ComponentInterface, MenuI { // Account for rounding errors in JS let newStepValue = (shouldComplete) ? 0.001 : -0.001; + /** + * TODO: stepValue can sometimes return a negative + * value, but you can't have a negative time value + * for the cubic bezier curve (at least with web animations) + * Not sure if the negative step value is an error or not + */ + const adjustedStepValue = (stepValue <= 0) ? 0.01 : stepValue; + /** * Animation will be reversed here, so need to * reverse the easing curve as well @@ -423,7 +431,7 @@ export class Menu implements ComponentInterface, MenuI { * to the new easing curve, as `stepValue` is going to be given * in terms of a linear curve. */ - newStepValue += getTimeGivenProgression(new Point(0, 0), new Point(0.4, 0), new Point(0.6, 1), new Point(1, 1), stepValue); + newStepValue += getTimeGivenProgression(new Point(0, 0), new Point(0.4, 0), new Point(0.6, 1), new Point(1, 1), adjustedStepValue); this.animation .easing('cubic-bezier(0.4, 0.0, 0.6, 1)') diff --git a/core/src/utils/animation/animation.ts b/core/src/utils/animation/animation.ts index dd1d8337f5..0f6b016059 100644 --- a/core/src/utils/animation/animation.ts +++ b/core/src/utils/animation/animation.ts @@ -64,6 +64,8 @@ export const createAnimation = () => { elements.length = 0; childAnimations.length = 0; + _keyframes.length = 0; + clearOnFinish(); initialized = false; @@ -1033,13 +1035,8 @@ export const createAnimation = () => { if (firstFrame != null && (firstFrame.offset === undefined || firstFrame.offset === 0)) { firstFrame[property] = value; } else { - const object: any = { - offset: 0 - }; - object[property] = value; - _keyframes = [ - object, + { offset: 0, [property]: value }, ..._keyframes ]; } @@ -1051,20 +1048,13 @@ export const createAnimation = () => { const lastFrame = _keyframes[_keyframes.length - 1]; if (lastFrame != null && (lastFrame.offset === undefined || lastFrame.offset === 1)) { - lastFrame[property] = value; + lastFrame[property] = value; } else { - - const object: any = { - offset: 1 - }; - object[property] = value; - _keyframes = [ ..._keyframes, - object + { offset: 1, [property]: value } ]; } - return ani; }; diff --git a/core/src/utils/animation/old-animation/index.ts b/core/src/utils/animation/old-animation/index.ts index afecd60466..19fd3d5312 100644 --- a/core/src/utils/animation/old-animation/index.ts +++ b/core/src/utils/animation/old-animation/index.ts @@ -4,7 +4,7 @@ import { Animator } from './animator'; export const create = (animationBuilder?: AnimationBuilder, baseEl?: any, opts?: any): Promise => { if (animationBuilder) { - return animationBuilder(baseEl, opts); + return animationBuilder(Animator as any, baseEl, opts); } return Promise.resolve(new Animator() as any); }; diff --git a/core/src/utils/animation/test/animation.spec.ts b/core/src/utils/animation/test/animation.spec.ts index b10d432252..a6f3fcf79a 100644 --- a/core/src/utils/animation/test/animation.spec.ts +++ b/core/src/utils/animation/test/animation.spec.ts @@ -81,6 +81,68 @@ describe('Animation Class', () => { expect(animation.getKeyframes().length).toEqual(3); }); + + it('should set the from keyframe properly', () => { + animation + .from('opacity', 0) + .from('background', 'red') + .from('color', 'purple'); + + const keyframes = animation.getKeyframes(); + + expect(keyframes.length).toEqual(1); + expect(keyframes[0]).toEqual({ + opacity: 0, + color: 'purple', + background: 'red', + offset: 0 + }); + }); + + it('should set the to keyframe properly', () => { + animation + .to('opacity', 0) + .to('background', 'red') + .to('color', 'purple'); + + const keyframes = animation.getKeyframes(); + expect(keyframes.length).toEqual(1); + expect(keyframes[0]).toEqual({ + opacity: 0, + color: 'purple', + background: 'red', + offset: 1 + }); + }); + + it('should mix keyframes and fromTo properly', () => { + animation + .keyframes([ + { offset: 0, background: 'red' }, + { offset: 0.99, background: 'blue' }, + { offset: 1, background: 'green' } + ]) + .fromTo('opacity', 0, 1) + + const keyframes = animation.getKeyframes(); + expect(keyframes.length).toEqual(3); + expect(keyframes[0]).toEqual({ + opacity: 0, + background: 'red', + offset: 0 + }); + + expect(keyframes[1]).toEqual({ + background: 'blue', + offset: 0.99 + }); + + expect(keyframes[2]).toEqual({ + opacity: 1, + background: 'green', + offset: 1 + }); + }); }); describe('Animation Config Methods', () => { diff --git a/core/src/utils/gesture/swipe-back.ts b/core/src/utils/gesture/swipe-back.ts index 5c7a96afd6..3ac10df3a3 100644 --- a/core/src/utils/gesture/swipe-back.ts +++ b/core/src/utils/gesture/swipe-back.ts @@ -37,7 +37,13 @@ export const createSwipeBackGesture = ( realDur = Math.min(dur, 540); } - onEndHandler(shouldComplete, stepValue, realDur); + /** + * TODO: stepValue can sometimes return a negative + * value, but you can't have a negative time value + * for the cubic bezier curve (at least with web animations) + * Not sure if the negative step value is an error or not + */ + onEndHandler(shouldComplete, (stepValue <= 0) ? 0.01 : stepValue, realDur); }; return createGesture({ diff --git a/core/src/utils/overlays.ts b/core/src/utils/overlays.ts index 1b0a732726..9477528bae 100644 --- a/core/src/utils/overlays.ts +++ b/core/src/utils/overlays.ts @@ -190,11 +190,15 @@ const overlayAnimation = async ( /** * TODO: Remove AnimationBuilder */ - const animation = await import('./animation/old-animation').then(mod => mod.create(animationBuilder as AnimationBuilder, aniRoot, opts)); - const isAnimationBuilder = (animation as any).fill === undefined; - - if (!isAnimationBuilder) { - (animation as any).fill('both'); + let animation; + let isAnimationBuilder = true; + try { + const mod = await import('./animation/old-animation'); + animation = await mod.create(animationBuilder as AnimationBuilder, aniRoot, opts); + } catch (err) { + animation = (animationBuilder as IonicAnimationInterface)(aniRoot, opts); + animation.fill('both'); + isAnimationBuilder = false; } overlay.animation = animation; diff --git a/core/src/utils/transition/index.ts b/core/src/utils/transition/index.ts index 2f8f940359..da153894be 100644 --- a/core/src/utils/transition/index.ts +++ b/core/src/utils/transition/index.ts @@ -85,7 +85,8 @@ const animation = async (animationBuilder: IonicAnimationInterface | AnimationBu let trans: Animation | IonicAnimation; try { - trans = await import('../animation/old-animation').then(mod => mod.create(animationBuilder as AnimationBuilder, opts.baseEl, opts)); + const mod = await import('../animation/old-animation'); + trans = await mod.create(animationBuilder as AnimationBuilder, opts.baseEl, opts); } catch (err) { trans = (animationBuilder as IonicAnimationInterface)(opts.baseEl, opts); } diff --git a/core/src/utils/transition/ios.transition.ts b/core/src/utils/transition/ios.transition.ts index a934967ce6..81d94a6237 100644 --- a/core/src/utils/transition/ios.transition.ts +++ b/core/src/utils/transition/ios.transition.ts @@ -138,7 +138,12 @@ export const iosTransitionAnimation = (navEl: HTMLElement, opts: TransitionOptio enteringToolBarBg .beforeClearStyles([OPACITY]) - .fromTo(OPACITY, 0.01, 1); + .keyframes([ + { offset: 0, opacity: 0.01 }, + { offset: 0.99, opacity: 1 }, + { offset: 1, opacity: 'var(--opacity)' } + // TODO: Find a way to support clearing properties from Web Animations + ]); // forward direction, entering page has a back button enteringBackButton.fromTo(OPACITY, 0.01, 1); diff --git a/core/src/utils/transition/md.transition.ts b/core/src/utils/transition/md.transition.ts index 17d9d937cb..86548ae344 100644 --- a/core/src/utils/transition/md.transition.ts +++ b/core/src/utils/transition/md.transition.ts @@ -16,6 +16,7 @@ export const mdTransitionAnimation = (_: HTMLElement, opts: TransitionOptions): rootTransition .addElement(ionPageElement) + .fill('both') .beforeRemoveClass('ion-page-invisible'); // animate the component itself diff --git a/docs/package.json b/docs/package.json index 94257da652..e159b705b2 100644 --- a/docs/package.json +++ b/docs/package.json @@ -1,6 +1,6 @@ { "name": "@ionic/docs", - "version": "4.8.0", + "version": "4.8.1", "description": "Pre-packaged API documentation for the Ionic docs.", "main": "core.json", "files": [