代码之家  ›  专栏  ›  技术社区  ›  Dolan

角度路由器过渡动画有条件地左右滑动

  •  10
  • Dolan  · 技术社区  · 6 年前

    我已经阅读了这篇关于角度路由器过渡动画的文章:

    https://medium.com/google-developer-experts/angular-supercharge-your-router-transitions-using-new-animation-features-v4-3-3eb341ede6c8

    以及:

    Angular 2 "slide in animation" of a routed component

    然而,这太静态了。我想让它向左滑动 右侧,具体取决于选项卡的顺序。

    是否可以为此创建路由器动画?我的意思示例如下:

    https://material.angular.io/components/tabs/examples

    看它是如何滑动的 两者都有 左边 很自然地,这取决于你在哪个选项卡上。

    这必须是动态的,因为选项卡将在运行时添加。

    3 回复  |  直到 6 年前
        1
  •  8
  •   Michal.S    5 年前

    现在事情变得更简单了,因为新的动画别名 :增量 :递减 . Angular 5中引入了别名。

    因此,我修改后的解决方案是:

        @Component({
          selector: 'app-workspace-container',
          templateUrl: './workspace-container.component.html',
          styleUrls: ['./workspace-container.component.scss'],
          animations: [
            trigger('animRoutes', [
              transition(':increment', right),
              transition(':decrement', left),
            ]),
          ],
      })
      export class ComponentContainingRouterOutlet implements OnDestroy, OnInit {
        //... ngOnInit,ngOnDestroy
    
        constructor( private route: ActivatedRoute ) { }
    
        animationState: number;
    
        onActivate($event) {
          this.animationState = this.route.firstChild.snapshot.data['routeIdx'];
        }
      }
    

    在路由器出口位置调用动画:

    <div [@animRoutes]="animationState">
      <router-outlet (activate)="onActivate($event)"></router-outlet>
    </div>
    

    修改管线定义作为示例,请参见 data: { routeIdx: X } :

        const routes: Routes = [
          {
            path: 'routeOne',
            component: ComponentOne,
            data: { routeIdx: 0 }
          },
          {
            path: 'routeTwo',
            component: ComponentTwo,
            data: { routeIdx: 1}
          },
          {
            path: 'routeThree',
            component: ComponentThree,
            data: { routeIdx: 2 }
          },
          {
            path: 'routeFour',
            component: ComponentFour,
            data: { routeIdx: 3 }
          },
          {
            path: '',
            redirectTo: 'routeOne',
            pathMatch: 'full'
          }
        ]
    

    和转换与中的相同 Dolan's 职位:

    const left = [
        query(':enter, :leave', style({ position: 'fixed', width: '100%' }), { optional: true }),
        group([
            query(':enter', [style({ transform: 'translateX(-100%)' }), animate('.3s ease-out', style({ transform: 'translateX(0%)' }))], {
                optional: true,
            }),
            query(':leave', [style({ transform: 'translateX(0%)' }), animate('.3s ease-out', style({ transform: 'translateX(100%)' }))], {
                optional: true,
            }),
        ]),
    ];
    
    const right = [
        query(':enter, :leave', style({ position: 'fixed', width: '100%' }), { optional: true }),
        group([
            query(':enter', [style({ transform: 'translateX(100%)' }), animate('.3s ease-out', style({ transform: 'translateX(0%)' }))], {
                optional: true,
            }),
            query(':leave', [style({ transform: 'translateX(0%)' }), animate('.3s ease-out', style({ transform: 'translateX(-100%)' }))], {
                optional: true,
            }),
        ]),
    ];
    
        2
  •  1
  •   Dolan    6 年前

    我通过“伪装”它所处的状态,成功地实现了这一目标。

    component.html :

    <div [@animRoutes]="pageState">
       <router-outlet></router-outlet>
    </div>
    

    pageState 是一个 变量 component.ts 文件

    每当我单击要向右移动的选项卡时,我将设置 页面状态 right ,与相同 left ,并让 有棱角的 接管其余部分。

    注: 您必须创建 正当 right1 状态为 乱劈 ,因为Angular当前不支持 right => right 状态转换!!同样适用于 左边 当然

    我的 @Component 注释如下:

    @Component({
        selector: 'app-workspace-container',
        templateUrl: './workspace-container.component.html',
        styleUrls: ['./workspace-container.component.scss'],
        animations: [
            trigger('animRoutes', [
                transition('* => right', right),
                transition('* => left', left),
                transition('* => right1', right),
                transition('* => left1', left),
            ]),
        ],
        changeDetection: ChangeDetectionStrategy.OnPush,
    })
    

    哪里 左边 , left1 , 正当 , 右侧1 是:

    const left = [
        query(':enter, :leave', style({ position: 'fixed', width: '100%' }), { optional: true }),
        group([
            query(':enter', [style({ transform: 'translateX(-100%)' }), animate('.3s ease-out', style({ transform: 'translateX(0%)' }))], {
                optional: true,
            }),
            query(':leave', [style({ transform: 'translateX(0%)' }), animate('.3s ease-out', style({ transform: 'translateX(100%)' }))], {
                optional: true,
            }),
        ]),
    ];
    
    const right = [
        query(':enter, :leave', style({ position: 'fixed', width: '100%' }), { optional: true }),
        group([
            query(':enter', [style({ transform: 'translateX(100%)' }), animate('.3s ease-out', style({ transform: 'translateX(0%)' }))], {
                optional: true,
            }),
            query(':leave', [style({ transform: 'translateX(0%)' }), animate('.3s ease-out', style({ transform: 'translateX(-100%)' }))], {
                optional: true,
            }),
        ]),
    ];
    

    TL;博士: 让你的状态变成 变量 ,这样您就可以动态地设置希望进入的状态。

        3
  •  0
  •   Ron Jonk    3 年前

    Michal提供的绝佳解决方案。S、 因此,我也可以在没有Routechange的情况下使用它,但也可以在您自己的选项卡组件上使用它。

    如果您有自定义选项卡控件,则可以按如下方式执行:

    第一步:在上面添加动画

    const left = [
      query(':enter, :leave', style({ position: 'absolute', width: '100%' }), { optional: true }), // or fixed
      group([
        query(':enter', [style({ transform: 'translateX(-100%)' }), animate('.4s ease-out', style({ transform: 'translateX(0%)' }))], {
          optional: true,
        }),
        query(':leave', [style({ transform: 'translateX(0%)' }), animate('.4s ease-out', style({ transform: 'translateX(100%)' }))], {
          optional: true,
        }),
      ]),
    ];
    
    const right = [
      query(':enter, :leave', style({ position: 'absolute', width: '100%' }), { optional: true }),
      group([
        query(':enter', [style({ transform: 'translateX(100%)' }), animate('.4s ease-out', style({ transform: 'translateX(0%)' }))], {
          optional: true,
        }),
        query(':leave', [style({ transform: 'translateX(0%)' }), animate('.4s ease-out', style({ transform: 'translateX(-100%)' }))], {
          optional: true,
        }),
      ]),
    ];
    

    步骤2:在模板中,将触发器添加到动画项的容器中。相对或柔性定位。

    <div [@animStep]="currentStep">
        <app-step1 *ngIf=“currentStep === 1”></app-step1>
        <app-step2 *ngIf=“currentStep === 2”></app-step2>
        <app-step3 *ngIf=“currentStep === 3”></app-step3>
    </div>
    

    步骤3:在组件装饰器中添加动画

    // component
    animations: [
      trigger('animStep', [
        transition(':increment', right),
        transition(':decrement', left),
      ]),
    ],
    

    步骤3:触发值的更改

    currentStep += 1;