web-dev-qa-db-ja.com

Angular 2ルーティングされたコンポーネントの「アニメーションのスライド」

それらをルーティングするために、固定ナビゲーションバーに2つのルーティングコンポーネントと2つのルーターリンクがあるとします。ルーターリンクをクリックすると、右からスライドインしてほしい。

コンポーネントをcssでオフセットし、タイムアウト関数を使用してcssクラスを変更し、それをスライドインさせたくありません(たとえば、ngStyleまたはngClassを使用)。

Angular 2でそれを達成するよりエレガントな方法はありますか?

ありがとう!

7
Han Che

Angular 4.1を使用すると、特定のルートアニメーションを作成できるようになりました。これは、コンポーネントが表示されるときにアニメーションをトリガーすることとは異なります。スムーズなトランジションで、コンポーネントの出入りに応じてトランジションを変更できます。つまり、コンテンツにドリルダウンしてコンポーネントを右からスライドインして左からスライドインするような複雑なトランジションを実行できます。別のコンポーネントから「戻る」ボタンを介して入力する場合。

  1. まず、ルーターのアウトレットに注釈を付けます(例:_app.component.html_):

    _<div class="page" [@routerAnimations]="prepareRouteTransition(outlet)">
        <router-outlet #outlet="outlet"></router-outlet>
    </div>
    _
  2. 対応するコンポーネント定義にprepareRouteTransition(outlet)関数を実装します(例:_app.component.js_)。

    _prepareRouteTransition(outlet) {
        const animation = outlet.activatedRouteData['animation'] || {};
        return animation['value'] || null;
    }
    _
  3. アニメーションを定義します(例:_app.component.js_):

    _  const slideLeft = [
        query(':leave', style({ position: 'absolute', left: 0, right: 0 ,transform: 'translate3d(0%,0,0)' }), {optional:true}),
        query(':enter', style({ position: 'absolute', left: 0, right: 0, transform: 'translate3d(-100%,0,0)' }), {optional:true}),
        group([
          query(':leave', group([
            animate('500ms cubic-bezier(.35,0,.25,1)', style({ transform: 'translate3d(100%,0,0)' })), // y: '-100%'
          ]), {optional:true}),
          query(':enter', group([
            animate('500ms cubic-bezier(.35,0,.25,1)', style({ transform: 'translate3d(0%,0,0)' })),
          ]), {optional:true})
        ])
      ]
    
      const slideRight = [
        query(':leave', style({ position: 'absolute', left: 0, right: 0 , transform: 'translate3d(0%,0,0)'}), {optional:true}),
        query(':enter', style({ position: 'absolute', left: 0, right: 0, transform: 'translate3d(100%,0,0)'}), {optional:true}),
    
        group([
          query(':leave', group([
            animate('500ms cubic-bezier(.35,0,.25,1)', style({ transform: 'translate3d(-100%,0,0)' })), // y: '-100%'
          ]), {optional:true}),
          query(':enter', group([
            animate('500ms cubic-bezier(.35,0,.25,1)', style({ transform: 'translate3d(0%,0,0)' })),
          ]), {optional:true})
        ])
      ]
    _
  4. アニメーションメタデータをルート定義に追加します(例:_app.routing.ts_):

    _const routes: Routes = [
      {
        path: 'products',
        component: ProductsComponent,
        data: {
          animation: {
            value: 'products',
          }
        }
      },
      {
        path: 'products/:id',
        component: ProductDetailComponent,
        data: {
           animation: {
            value: 'product-detail',
          }
        }
      }
    _
  5. 最後に、コンポーネントの「routerAnimations」アニメーショントリガーを、定義したアニメーションとルートメタデータ(例:_app.component.js_)で登録します。

    _@Component({
      selector: 'app-root',
      templateUrl: './app.component.html',
      styleUrls: ['./app.component.css'],
      animations: [
        trigger('routerAnimations', [
          transition('products => product-detail', slideRight),
          transition('product-detail => products', slideLeft),
        ])
      ]
    })
    _

古いブラウザをターゲットとするためにWebアニメーションAPIをポリフィルすることを忘れないでください

Matias Niemelaがng-confでルートアニメーションについて詳しく説明しています(デモ付き): https://youtu.be/Oh9wj-1p2BM?t=12m21s

彼のプレゼンテーションコード: https://github.com/matsko/ng4-animations-preview

14
SpaceFozzy

スライドインの点では、非常に簡単です。

Official Angular 2 Animate docs を参照できます。

これもチェックできます Plunker 新しいルーターv3を使用して、簡単なショーケースを作成しました

トリガーされた要素がビューから破棄されようとしているときに、実際にLeave/Exit/void遷移をどのように行うかを理解するのに苦労していることを覚えておいてください。

私は別のスレッドを開いた Angular 2 Animate-ルート/コンポーネントを変更するときに「* => void」遷移の目に見える効果がない ルーターがアニメーション/遷移の終了に気付くようにする方法を理解しようとする時間。

@Component({
  selector: 'home',
  directives: [ROUTER_DIRECTIVES],
  template: `
  <div @flyInOut="'active'" class="radibre">
  </div>
  `,
  styles: ['.radibre { width: 200px; height: 100px; background: red; }'],
  animations: [
    trigger('flyInOut', [
      state('in', style({transform: 'translateX(0)'})),
      transition('void => *', [
        style({transform: 'translateX(-100%)'}),
        animate(100)
      ]),
      transition('* => void', [
        animate(100, style({transform: 'translateX(100%)'}))
      ])
    ])
  ]
})

export class Home {
  constructor() { }
}
@Component({
  selector: 'page',
  template: `
  <div @testingBottom="'active'" class="page"></div>`,
  styles: ['.page { width: 300px; height: 50px; background: green; }'],
  animations: [
    trigger('testingBottom', [
      state('active', style({transform: 'scale(1)'})),
      transition('void => *', [
        style({transform: 'scale(0)'}),
        animate(100)
      ]),
      transition('* => void', [
        animate(100, style({transform: 'scale(0)'}))
      ])
    ])
  ]
})
7