typescript 如何在Ionic4中添加标签动画?

q8l4jmvw  于 2022-12-30  发布在  TypeScript
关注(0)|答案(3)|浏览(129)

我想在切换选项卡时添加向前和向后导航动画。
我想复制Facebook的应用程序选项卡导航动画的当前状态。
我目前尝试在单个选项卡上添加一个方法来调用向前导航的函数。

<ion-tab-bar slot="bottom">
  <ion-tab-button (click)="goToListTab()" mode="md">
    <ion-icon name="list"></ion-icon>
    <ion-label>Orders</ion-label>
  </ion-tab-button>

  <ion-tab-button (click)="goToNewTab()" mode="md">
    <ion-icon name="add"></ion-icon>
    <ion-label>New Order</ion-label>
  </ion-tab-button>

  <ion-tab-button (click)="goToAccountTab()" mode="md">
    <ion-icon name="person"></ion-icon>
    <ion-label>Account</ion-label>
  </ion-tab-button>
</ion-tab-bar>

而且我的.ts文件有调用navigate的函数。为了简化,我只包含了一个。

goToAccountTab() {
    this.router.navigateBack('/tabs/account');
}

在goToAccountTab上,我期望它导航到带有navigateBack动画的帐户选项卡,但它成功地转到帐户选项卡,但没有执行navigateBack动画。

7vux5j2d

7vux5j2d1#

Ionic 方式是通过使用native page transitions插件,这是**no longer maintained**,你得到了一个错误,我无法修复(当做动画,你看到两个页面),但这是最好的解决方案,我发现直到知道,因为离子没有做正确的(目前)。
所以,我把代码放在这里,它可能会有帮助,也许你会找到解决办法;)
1.跑

ionic cordova plugin add com.telerik.plugins.nativepagetransitions
npm install @ionic-native/native-page-transitions

1.导入到app. module. ts

import { NativePageTransitions } from '@ionic-native/native-page-transitions/ngx'

@NgModule({
  imports: [
    NativePageTransitions,
  ]
}

1.添加到你的tabs. page. ts动画逻辑

import {
  NativePageTransitions,
  NativeTransitionOptions,
} from '@ionic-native/native-page-transitions/ngx'

export class TabsPage {
loaded: boolean = false
tabIndex: number = 0

constructor(private nativePageTransitions: NativePageTransitions) {

  //Look the index to see which direction to go (if you have more than 3 tabs)
  private getAnimationDirection(e: any): string {
    var currentIndex = this.tabIndex

    this.tabIndex = e.index
    // or 
    // this.tabIndex = Object.keys(this.tabs).indexOf(e.tab)

    switch (true) {
      case currentIndex < e.index:
        return 'left'
      case currentIndex > e.index:
        return 'right'
    }
  }

  transition(e: any): void {
    let options: NativeTransitionOptions = {
      direction: this.getAnimationDirection(e),
      duration: 250,
      slowdownfactor: -1,
      slidePixels: 0,
      iosdelay: 20,
      androiddelay: 0,
      fixedPixelsTop: 0,
      fixedPixelsBottom: 48,
    }

    if (!this.loaded) {
      this.loaded = true
      return
    }

    this.nativePageTransitions.slide(options)
  }
}

1.在tabs. page. html中

<ion-tabs (ionTabsWillChange)="transition($event)">
 /*...*/
</ion-tabs>
  • 注:

1.对于我来说,$event返回了一个类似{tab: 'home'}的对象,因为我是通过一个选项卡数组的循环来创建选项卡的,所以可以使用Object.keys(tabs).indexOf($event.tab)找到索引
2.我还尝试使用一个简单的Angular 路线动画,但由于离子 Package 内的离子标签的逻辑,它似乎不工作 *

aij0ehis

aij0ehis2#

使用Ionicv4时,我无法从选项卡控制器获取索引,但我通过保留选项卡的列表对象并以这种方式获取数字索引来解决这个问题。
package.json

"@ionic/angular": "^4.9.1"
"@angular/core": "^8.2.7"
"com.telerik.plugins.nativepagetransitions": "^0.6.5",

Tabs.ts:

import { Component, OnInit, ViewChild } from '@angular/core';

import { IonTabs } from '@ionic/angular';

import {
  NativePageTransitions,
  NativeTransitionOptions,
} from '@ionic-native/native-page-transitions/ngx';

@Component({
  selector: 'app-tabs',
  templateUrl: 'tabs.page.html',
  styleUrls: ['tabs.page.scss']
})
export class TabsPage implements OnInit {

  @ViewChild('navTabs', { static: false }) navTabs: IonTabs;

  private tabs = {
    events: 0,
    notifications: 1,
    profile: 2
  };
  loaded = false;
  tabIndex = 0;

  constructor(
    private nativePageTransitions: NativePageTransitions
  ) { }

  private getAnimationDirection(e: any): string {

    const currentIndex = this.tabIndex;
    this.tabIndex = this.tabs[e.tab];

    switch (true) {
      case currentIndex > this.tabs[e.tab]:
        return 'left';
      case currentIndex < this.tabs[e.tab]:
        return 'right';
    }
  }

  transition(e: any): void {

    const options: NativeTransitionOptions = {
      direction: this.getAnimationDirection(e),
      duration: 250,
      slowdownfactor: -1,
      slidePixels: 0,
      iosdelay: 20,
      androiddelay: 0,
      fixedPixelsTop: 0,
      fixedPixelsBottom: 48,
    };

    if (!this.loaded) {
      this.loaded = true;
      return;
    }

    this.nativePageTransitions.slide(options);
  }

}

Tabs.html

<ion-tabs #navTabs (ionTabsWillChange)="transition($event)">

  <ion-tab-bar color="dark" slot="bottom">

    <ion-tab-button tab="events">
      <ion-icon name="calendar"></ion-icon>
      <ion-label>Events</ion-label>
    </ion-tab-button>

    <ion-tab-button tab="notifications">
      <ion-icon name="notifications"></ion-icon>
      <ion-label>Notification</ion-label>
    </ion-tab-button>

    <ion-tab-button tab="profile">
      <ion-icon name="barcode"></ion-icon>
      <ion-label>Profile</ion-label>
    </ion-tab-button>

  </ion-tab-bar>

</ion-tabs>
q3qa4bjr

q3qa4bjr3#

你可以使用css来制作动画。
它是一个动画,可以播放离子类,而不需要安装任何东西。
在组件中:

export class HomePage implements OnInit, OnDestroy {

  componentElement: HTMLElement;

  constructor(
    private nativeComponent: ElementRef
  ) {
    this.componentElement = this.nativeComponent.nativeElement;
  }
  ngOnDestroy(): void {
  }

  ngOnInit() {
  }

}

和另一组分:

export class NotificationsPage implements OnInit, OnDestroy {

  componentElement: HTMLElement;

  constructor(
    private nativeComponent: ElementRef
  ) {
    this.componentElement = this.nativeComponent.nativeElement;
  }
  ngOnDestroy(): void {
  }

  ngOnInit() {
  }

}

接下来,在您的选项卡路由:

const routes: Routes = [
  {
    path: '',
    component: TabsPage,
    children: [
      {
        path: '',
        redirectTo: 'home',
        pathMatch: 'full'
      },
      {
        path: 'home',
        loadChildren: () => import('./home/home.module').then(m => m.HomePageModule),
        data: {
          index: 0
        }
      },
      {
        path: 'notifications',
        loadChildren: () => import('./notifications/notifications.module').then(m => m.notificationsPageModule),
        data: {
          index: 1
        }
      },
    ]
  }
];

接下来,在您的选项卡页面中:

export class TabsPage implements OnInit, OnDestroy, AfterViewInit {

  @ViewChild('tabs', { static: true }) tabs: IonTabs;
  routerOutletTabs: IonRouterOutlet;

  last_component: HTMLElement;
  last_component_index: number;

  constructor() {
  }
  ngAfterViewInit(): void {
    this.routerOutletTabs = this.tabs.outlet;

    this.routerOutletTabs.activateEvents.subscribe((e: any) => {
      if(!this.last_component){
        this.last_component = e.componentElement;
      this.last_component_index = this.routerOutletTabs.activatedRouteData.index;
        return;
      }

      const data_router = this.routerOutletTabs.activatedRouteData;

      if(this.last_component_index < data_router.index){
        this.last_component.classList.add('toLeft');
        this.last_component.classList.remove('toRight');

        e.componentElement.classList.add('toLeft');
        e.componentElement.classList.remove('toRight');
      }else{
        this.last_component.classList.remove('toLeft');
        this.last_component.classList.add('toRight');

        e.componentElement.classList.remove('toLeft');
        e.componentElement.classList.add('toRight');
      }

      this.last_component = e.componentElement;
      this.last_component_index = data_router.index;
    })
  }
}

tabs.page.html

<ion-tabs #tabs>
    <ion-tab-bar slot="bottom">
      <ion-tab-button tab="home">
        <ion-icon name="calendar"></ion-icon>
      </ion-tab-button>
      <ion-tab-button tab="notifications">
        <ion-icon name="notifications"></ion-icon>
      </ion-tab-button>
    </ion-tab-bar>
  </ion-tabs>

最后,在全局样式文件中:

ion-router-outlet[tabs=true] > .ion-page {
  --velocity-transition: 0.2s;
}

ion-router-outlet[tabs=true] > .ion-page.toRight:not(.ion-page-hidden) {
  animation: route_enter_right var(--velocity-transition) ease forwards;
}

ion-router-outlet[tabs=true] > .ion-page.toLeft:not(.ion-page-hidden) {
  animation: route_enter_left var(--velocity-transition) ease forwards;
}

ion-router-outlet[tabs=true] > .ion-page.ion-page-hidden.toLeft {
  animation: route_leave_left var(--velocity-transition) ease forwards;
  display: flex !important;
}

ion-router-outlet[tabs=true] > .ion-page.ion-page-hidden.toRight {
  animation: route_leave_right var(--velocity-transition) ease forwards;
  display: flex !important;
}

@keyframes route_enter_left {
  from{
    transform: translateX(100%);
  }
  to{
    transform: translateX(0%);
  }
}

@keyframes route_enter_right {
  from{
    transform: translateX(-100%);
  }
  to{
    transform: translateX(0%);
  }
}

@keyframes route_leave_left {
  from{
    transform: translateX(0%);
  }
  to{
    transform: translateX(-100%);
  }
}

@keyframes route_leave_right {
  from{
    transform: translateX(0%);
  }
  to{
    transform: translateX(100%);
  }
}

对不起,我的英语:3
这对我很有效,我不需要向我的项目添加包:3
希望对你有帮助。

相关问题