mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-18 11:17:19 +08:00

committed by
Brandy Carney

parent
1b9d61bfa8
commit
dbf6a448ff
@ -1,8 +1,8 @@
|
|||||||
import { Animation, Side } from '../../interface';
|
import { Animation, Side } from '../../interface';
|
||||||
|
|
||||||
export interface MenuI {
|
export interface MenuI {
|
||||||
|
|
||||||
el: HTMLIonMenuElement;
|
el: HTMLIonMenuElement;
|
||||||
|
mode: string;
|
||||||
side: Side;
|
side: Side;
|
||||||
menuId?: string;
|
menuId?: string;
|
||||||
disabled: boolean;
|
disabled: boolean;
|
||||||
|
@ -7,4 +7,4 @@
|
|||||||
$menu-md-background: $background-color !default;
|
$menu-md-background: $background-color !default;
|
||||||
|
|
||||||
/// @prop - Box shadow of the menu
|
/// @prop - Box shadow of the menu
|
||||||
$menu-md-box-shadow: 0 2px 22px 0 rgba(0, 0, 0, 0.09), 4px 0 16px 0 rgba(0, 0, 0, 0.18) !default;
|
$menu-md-box-shadow: 4px 0px 16px rgba(0, 0, 0, 0.18) !default;
|
||||||
|
@ -8,6 +8,11 @@ import { GESTURE_CONTROLLER } from '../../utils/gesture';
|
|||||||
import { assert, isEndSide as isEnd } from '../../utils/helpers';
|
import { assert, isEndSide as isEnd } from '../../utils/helpers';
|
||||||
import { menuController } from '../../utils/menu-controller';
|
import { menuController } from '../../utils/menu-controller';
|
||||||
|
|
||||||
|
const iosEasing = 'cubic-bezier(0.32,0.72,0,1)';
|
||||||
|
const mdEasing = 'cubic-bezier(0.0,0.0,0.2,1)';
|
||||||
|
const iosEasingReverse = 'cubic-bezier(1, 0, 0.68, 0.28)';
|
||||||
|
const mdEasingReverse = 'cubic-bezier(0.4, 0, 0.6, 1)';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
tag: 'ion-menu',
|
tag: 'ion-menu',
|
||||||
styleUrls: {
|
styleUrls: {
|
||||||
@ -23,7 +28,10 @@ export class Menu implements ComponentInterface, MenuI {
|
|||||||
private gesture?: Gesture;
|
private gesture?: Gesture;
|
||||||
private blocker = GESTURE_CONTROLLER.createBlocker({ disableScroll: true });
|
private blocker = GESTURE_CONTROLLER.createBlocker({ disableScroll: true });
|
||||||
|
|
||||||
private mode = getIonMode(this);
|
mode = getIonMode(this);
|
||||||
|
|
||||||
|
private easing: string = this.mode === 'ios' ? iosEasing : mdEasing;
|
||||||
|
private easingReverse: string = this.mode === 'ios' ? iosEasingReverse : mdEasingReverse;
|
||||||
|
|
||||||
isAnimating = false;
|
isAnimating = false;
|
||||||
width!: number; // TODO
|
width!: number; // TODO
|
||||||
@ -138,7 +146,7 @@ export class Menu implements ComponentInterface, MenuI {
|
|||||||
|
|
||||||
async connectedCallback() {
|
async connectedCallback() {
|
||||||
if (this.type === undefined) {
|
if (this.type === undefined) {
|
||||||
this.type = config.get('menuType', this.mode === 'ios' ? 'reveal' : 'overlay');
|
this.type = config.get('menuType', 'overlay');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Build.isBrowser) {
|
if (!Build.isBrowser) {
|
||||||
@ -329,12 +337,12 @@ AFTER:
|
|||||||
const isReversed = !shouldOpen;
|
const isReversed = !shouldOpen;
|
||||||
const ani = (this.animation as IonicAnimation)!
|
const ani = (this.animation as IonicAnimation)!
|
||||||
.direction((isReversed) ? 'reverse' : 'normal')
|
.direction((isReversed) ? 'reverse' : 'normal')
|
||||||
.easing((isReversed) ? 'cubic-bezier(0.4, 0.0, 0.6, 1)' : 'cubic-bezier(0.0, 0.0, 0.2, 1)');
|
.easing((isReversed) ? this.easingReverse : this.easing);
|
||||||
|
|
||||||
if (animated) {
|
if (animated) {
|
||||||
await ani.playAsync();
|
await ani.play();
|
||||||
} else {
|
} else {
|
||||||
ani.playSync();
|
ani.play({ sync: true });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -532,7 +540,7 @@ AFTER:
|
|||||||
|
|
||||||
this.isAnimating = true;
|
this.isAnimating = true;
|
||||||
const ani = (this.animation as IonicAnimation)!.direction('reverse');
|
const ani = (this.animation as IonicAnimation)!.direction('reverse');
|
||||||
ani.playSync();
|
ani.play({ sync: true });
|
||||||
this.afterAnimation(false);
|
this.afterAnimation(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -93,7 +93,7 @@
|
|||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<script type="module">
|
<script>
|
||||||
const menuCtrl = document.querySelector('ion-menu-controller');
|
const menuCtrl = document.querySelector('ion-menu-controller');
|
||||||
|
|
||||||
async function openFirst() {
|
async function openFirst() {
|
||||||
|
@ -7,14 +7,13 @@ import { createAnimation } from '../../animation/animation';
|
|||||||
* type will provide their own animations for open and close
|
* type will provide their own animations for open and close
|
||||||
* and registers itself with Menu.
|
* and registers itself with Menu.
|
||||||
*/
|
*/
|
||||||
export const baseAnimation = (): IonicAnimation => {
|
export const baseAnimation = (isIos: boolean): IonicAnimation => {
|
||||||
// https://material.io/guidelines/motion/movement.html#movement-movement-in-out-of-screen-bounds
|
// https://material.io/guidelines/motion/movement.html#movement-movement-in-out-of-screen-bounds
|
||||||
// https://material.io/guidelines/motion/duration-easing.html#duration-easing-natural-easing-curves
|
// https://material.io/guidelines/motion/duration-easing.html#duration-easing-natural-easing-curves
|
||||||
|
|
||||||
// "Apply the sharp curve to items temporarily leaving the screen that may return
|
// "Apply the sharp curve to items temporarily leaving the screen that may return
|
||||||
// from the same exit point. When they return, use the deceleration curve. On mobile,
|
// from the same exit point. When they return, use the deceleration curve. On mobile,
|
||||||
// this transition typically occurs over 300ms" -- MD Motion Guide
|
// this transition typically occurs over 300ms" -- MD Motion Guide
|
||||||
return createAnimation()
|
|
||||||
.easing('cubic-bezier(0.0, 0.0, 0.2, 1)') // Deceleration curve (Entering the screen)
|
return createAnimation().duration(isIos ? 400 : 300);
|
||||||
.duration(300);
|
|
||||||
};
|
};
|
||||||
|
@ -11,9 +11,7 @@ import { baseAnimation } from './base';
|
|||||||
export const menuOverlayAnimation = (menu: MenuI): IonicAnimation => {
|
export const menuOverlayAnimation = (menu: MenuI): IonicAnimation => {
|
||||||
let closedX: string;
|
let closedX: string;
|
||||||
let openedX: string;
|
let openedX: string;
|
||||||
|
const width = menu.width + 8;
|
||||||
const BOX_SHADOW_WIDTH = 8;
|
|
||||||
const width = menu.width + BOX_SHADOW_WIDTH;
|
|
||||||
const menuAnimation = createAnimation();
|
const menuAnimation = createAnimation();
|
||||||
const backdropAnimation = createAnimation();
|
const backdropAnimation = createAnimation();
|
||||||
|
|
||||||
@ -32,9 +30,12 @@ export const menuOverlayAnimation = (menu: MenuI): IonicAnimation => {
|
|||||||
.addElement(menu.menuInnerEl!)
|
.addElement(menu.menuInnerEl!)
|
||||||
.fromTo('transform', `translateX(${closedX})`, `translateX(${openedX})`);
|
.fromTo('transform', `translateX(${closedX})`, `translateX(${openedX})`);
|
||||||
|
|
||||||
|
const isIos = menu.mode === 'ios';
|
||||||
|
const opacity = isIos ? 0.2 : 0.25;
|
||||||
|
|
||||||
backdropAnimation
|
backdropAnimation
|
||||||
.addElement(menu.backdropEl!)
|
.addElement(menu.backdropEl!)
|
||||||
.fromTo('opacity', 0.01, 0.32);
|
.fromTo('opacity', 0.01, opacity);
|
||||||
|
|
||||||
return baseAnimation().addAnimation([menuAnimation, backdropAnimation]);
|
return baseAnimation(isIos).addAnimation([menuAnimation, backdropAnimation]);
|
||||||
};
|
};
|
||||||
|
@ -35,5 +35,5 @@ export const menuPushAnimation = (menu: MenuI): IonicAnimation => {
|
|||||||
.addElement(menu.backdropEl!)
|
.addElement(menu.backdropEl!)
|
||||||
.fromTo('opacity', 0.01, 0.32);
|
.fromTo('opacity', 0.01, 0.32);
|
||||||
|
|
||||||
return baseAnimation().addAnimation([menuAnimation, backdropAnimation, contentAnimation]);
|
return baseAnimation(menu.mode === 'ios').addAnimation([menuAnimation, contentAnimation, backdropAnimation]);
|
||||||
};
|
};
|
||||||
|
@ -15,5 +15,5 @@ export const menuRevealAnimation = (menu: MenuI): IonicAnimation => {
|
|||||||
.addElement(menu.contentEl!) // REVIEW
|
.addElement(menu.contentEl!) // REVIEW
|
||||||
.fromTo('transform', 'translateX(0px)', `translateX(${openedX})`);
|
.fromTo('transform', 'translateX(0px)', `translateX(${openedX})`);
|
||||||
|
|
||||||
return baseAnimation().addAnimation(contentOpen);
|
return baseAnimation(menu.mode === 'ios').addAnimation(contentOpen);
|
||||||
};
|
};
|
||||||
|
@ -216,7 +216,7 @@ const overlayAnimation = async (
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
const animationResult = await animation.playAsync();
|
const animationResult = await animation.play();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO: Remove AnimationBuilder
|
* TODO: Remove AnimationBuilder
|
||||||
|
Reference in New Issue
Block a user