【问题标题】:How to customize side menu animation如何自定义侧边菜单动画
【发布时间】:2019-08-05 23:26:12
【问题描述】:

我正在开发 Ionic 4 应用程序,我想使用这样的自定义侧边菜单动画:

但 Ionic 只有 3 个选项:推送、覆盖和显示。

我已经有了我的 3dmenu.ts 文件,但我不知道如何注入它以将它与 Ion-menu 组件一起使用,就像其他 3 个选项一样,有人可以提供有关如何执行此操作的提示吗?

【问题讨论】:

    标签: ionic-framework ionic4


    【解决方案1】:

    我终于可以做到了,使用 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 天后发现的唯一方法,我希望这对其他人有帮助,如果有人可以改进这一点,请随时发表评论:-)

    【讨论】:

    • 我尝试了您的方法但无法继续,因为 VScode 抱怨“找不到名称'HTMLStencilElement'”并且构造函数不期望第一个文件中的“文档”参数。我认为原因是因为我使用的是 Ionic 5。你有解决方案吗?
    猜你喜欢
    • 1970-01-01
    • 2020-10-24
    • 2013-04-22
    • 1970-01-01
    • 2016-11-29
    • 1970-01-01
    • 2015-12-17
    • 2019-11-07
    • 2021-09-23
    相关资源
    最近更新 更多