在Angular 4中实现路由动画

6

我正在尝试在Angular 4中实现路由过渡动画,当页面首次加载和刷新时,动画可以正常工作,因此我知道动画是有效的,但是在切换路由时无法正常工作。我漏掉了什么?

以下是代码...

// 组件元数据

animations: [fadeInAnimation]

// 模板

<div class="route-container" [@fadeInAnimation]>
    <router-outlet></router-outlet>
</div>

// 样式

.route-container {
  position:relative;
}
.route-container>* {
  display:block;
}

// 动画

trigger('fadeInAnimation', [

    // route 'enter' transition
    transition(':enter', [

        // css styles at start of transition
        style({ opacity: 0 }),

        // animation and styles at end of transition
        animate('6s cubic-bezier(.35,0,.25,1)', style({ opacity: 1 }))
    ]),
]);

1
你需要为每个路由设置触发器。目前它仅在“router-outlet”出现时设置,这通常只会发生一次(当应用程序加载时)。 - Z. Bagley
哦,那很有道理。我在哪里添加路由组件的触发器,只需要元数据吗?我知道这很基础,但路由动画总是让我困扰。 - Mel Pacheco
我指的是每个路由的过渡,而不是触发器。过渡的第一个参数将是 transition('route1 => route2', ....,你需要为不同的路由查询 query(':enter',...query(':leave', ...。如果需要,我可以在下面添加更详细的答案。 - Z. Bagley
1个回答

2
为确保在每个路由上都运行路由动画,您需要在每个路由之间定义过渡效果。以下是我用于在“主页”路由和“账户”路由之间创建抽屉效果的示例:
import { trigger, animate, style, group, query, transition } from '@angular/animations';

export const baseAnimation =
    trigger('baseAnimation', [
      transition('acct => home', [
        query(':enter, :leave', style({ position: 'absolute', top: 0, left: 0, right: 0 })),
        query(':leave', style({ height: '*'})),
        query('.acct', [
            animate('300ms',
            style({ height: 0 }))
        ])
      ]),
      transition('home => acct', [
        query(':enter, :leave',
          style({ position: 'absolute', top: 0, left: 0, right: 0 })),
        query(':enter .acct', [
          style({ height: 0 }),
          animate('300ms', style({ height: '*' }))
        ])
      ])
    ])

请注意,.acct 是帐户页面路由的类标签,可能对您的应用程序不必要(或需要相应更改)。通过这种方式,您可以在路由更改时动画化每个路由的子元素。
我在app.component.html中使用一个函数来处理路由动画:
<div [@baseAnimation]="prepareRouteTransition(outlet)">
  <router-outlet #outlet="outlet"></router-outlet>
</div>
</div>

app.component.ts 应该加载动画并为路由声明动画:

import { Component } from '@angular/core';
import { Router } from '@angular/router';
import { baseAnimation } from './anim/base.animation';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss'],
  animations: [ baseAnimation ]
})

export class AppComponent {

  constructor() { }

  prepareRouteTransition(outlet) {
    const animation = outlet.activatedRouteData['animation'] || {};
    return animation['value'] || null;
  }
}

我需要在组件本身做任何更改吗?在这种情况下是“home”还是“acct”,我需要在属性中传递查询吗?[@baseAnimation]= - Mel Pacheco
除非你是通过类进行动画,否则不需要这样做。在上面的情况下,当我想要对从“acct”子路由加载的整个组件进行动画时,我会将其包装在<div class="acct">中。如果我不想让它们动画,我只需省略该类即可使它们以标准方式加载。我也会更新我的app.component.html答案。 - Z. Bagley
@MelPacheco 已更新答案 - Z. Bagley

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接