【发布时间】:2019-08-05 23:26:12
【问题描述】:
我正在开发 Ionic 4 应用程序,我想使用这样的自定义侧边菜单动画:
但 Ionic 只有 3 个选项:推送、覆盖和显示。
我已经有了我的 3dmenu.ts 文件,但我不知道如何注入它以将它与 Ion-menu 组件一起使用,就像其他 3 个选项一样,有人可以提供有关如何执行此操作的提示吗?
【问题讨论】:
我正在开发 Ionic 4 应用程序,我想使用这样的自定义侧边菜单动画:
但 Ionic 只有 3 个选项:推送、覆盖和显示。
我已经有了我的 3dmenu.ts 文件,但我不知道如何注入它以将它与 Ion-menu 组件一起使用,就像其他 3 个选项一样,有人可以提供有关如何执行此操作的提示吗?
【问题讨论】:
我终于可以做到了,使用 workaruond 而不是我在这里找到的 here。诀窍是扩展菜单控制器类以创建一个新方法 registerAnimation:
第一步:新建一个ts文件(扩展名.ts或者你想要的名字),把这段代码放进去:
import { DOCUMENT } from '@angular/common';
import { Inject, Injectable } from '@angular/core';
import { MenuController } from '@ionic/angular';
import { AnimationBuilder } from '@ionic/core';
function proxyMethod(ctrlName: string, doc: Document, methodName: string, ...args: any[]) {
const controller = ensureElementInBody(ctrlName, doc);
return controller.componentOnReady()
.then(() => (controller as any)[methodName].apply(controller, args));
}
function ensureElementInBody(elementName: string, doc: Document) {
let element = doc.querySelector(elementName);
if (!element) {
element = doc.createElement(elementName);
doc.body.appendChild(element);
}
return element as HTMLStencilElement;
}
const CTRL = 'ion-menu-controller';
@Injectable({
providedIn: 'root',
})
export class EloMenuController extends MenuController {
constructor(@Inject(DOCUMENT) private document: any) {
super(document)
}
/**
* Registers a new animation that can be used with any `ion-menu` by
* passing the name of the animation in its `type` property.
*
* @param name The name of the animation to register.
* @param animation The animation function to register.
*/
registerAnimation(name: string, animation: AnimationBuilder) {
return proxyMethod(CTRL, this.document, 'registerAnimation', name, animation);
}
}
第 2 步:使用动画创建一个新的 ts 文件,在我的例子中我使用这个:
import { Animation, MenuI } from '@ionic/core';
export function menu3D (AnimationC: Animation, baseEl: HTMLElement, menu: MenuI):
Promise<Animation> {
let contentOpenedX: string;
let menuClosedX: string;
const width = menu.width;
const baseAnimation = new AnimationC();
if (menu.isEndSide) {
contentOpenedX = -width + 'px';
menuClosedX = width + 'px';
}
else {
contentOpenedX = width + 'px';
menuClosedX = -width + 'px';
}
const menuAnimation = new AnimationC()
.addElement(menu.menuInnerEl)
.fromTo('z-index', '0', '0')
.fromTo('translateX', menuClosedX, '0px');
const contentAnimation = new AnimationC()
.addElement(menu.contentEl)
.fromTo('translateX', '0px', contentOpenedX)
.fromTo('scale', '1', '0.7');
const backdropAnimation = new AnimationC()
.addElement(menu.backdropEl)
.fromTo('opacity', 0.01, 0.32);
return Promise.resolve(baseAnimation
.addElement(baseEl)
.easing('cubic-bezier(0.0, 0.0, 0.2, 1)')
.easingReverse('cubic-bezier(0.4, 0.0, 0.6, 1)')
.duration(300)
.add(contentAnimation)
.add(menuAnimation)
.add(backdropAnimation));
};
第 3 步:在您的 app.component.ts 中导入扩展类和动画并注册您的动画以便能够使用它:
import { Component, OnInit, Input } from '@angular/core';
import { Extend } from './animations/extend
import { menu3D } from './animations/menu3D';
@Component({
selector: 'app-root',
templateUrl: 'app.component.html',
})
export class AppComponent implements OnInit {
@Input() name: string;
constructor(
private menu: Extend
) {
this.menu.registerAnimation('menu3d', menu3D);
}
ngOnInit() {}
}
第 4 步:为您的 ion-menu 组件配置类型
<ion-menu side="start" type="menu3d" style="z-index: 10;">
........
</ion-menu>
第 5 步:不要忘记感谢来自 github 的 svallory 并享受它 :-)
我不知道这是否是最好的方法,但它是我搜索 5 天后发现的唯一方法,我希望这对其他人有帮助,如果有人可以改进这一点,请随时发表评论:-)
【讨论】: