拡張エコシステム
レガシーアニメーション

Angularアニメーションの概要

IMPORTANT: @angular/animationsパッケージは現在非推奨です。Angularチームは、新しく書くコードのアニメーションにはanimate.enteranimate.leaveを使ったネイティブCSSの利用を推奨します。詳しくは、新しいenterとleaveのアニメーションガイドを参照してください。また、アプリケーションで純粋なCSSアニメーションへの移行を始める方法については、AngularのAnimationsパッケージからの移行も参照してください。

アニメーションは動いているように見せる効果を生み出します。HTML要素のスタイルは時間の経過とともに変化します。 適切に設計されたアニメーションは、アプリケーションをより楽しく、分かりやすく使えるようにしますが、単なる装飾ではありません。 アニメーションは、いくつかの方法でアプリケーションとユーザー体験を向上させます。

  • アニメーションがないと、ウェブページの遷移は唐突でぎこちなく感じられることがあります
  • モーションはユーザー体験を大きく向上させるため、アニメーションはユーザーが自分の操作に対するアプリケーションの応答を把握する機会を与えます
  • 優れたアニメーションは、必要な場所へユーザーの注意を直感的に向けます

一般的に、アニメーションには時間の経過に沿った複数のスタイルの_変化_が含まれます。 HTML要素は移動、色の変更、拡大や縮小、フェード、ページ外へのスライドができます。 これらの変化は同時にも順番にも発生します。各変化のタイミングは制御できます。

AngularのアニメーションシステムはCSSの機能の上に構築されているため、ブラウザがアニメーション可能と見なす任意のプロパティをアニメーション化できます。 これには、位置、サイズ、transform、色、境界線などが含まれます。 W3Cは、アニメーション可能なプロパティの一覧をCSS Transitionsページで管理しています。

このガイドについて

このガイドでは、プロジェクトにAngularアニメーションを追加するための基本機能を紹介します。

はじめに

アニメーションに関する主なAngularモジュールは@angular/animations@angular/platform-browserです。

プロジェクトでAngularアニメーションを使い始めるには、標準のAngular機能とあわせてアニメーション専用モジュールをインポートします。

  1. アニメーションモジュールを有効にする

    @angular/platform-browser/animations/asyncからprovideAnimationsAsyncをインポートし、bootstrapApplication関数呼び出しのprovidersリストに追加します。

    Enabling Animations

    1bootstrapApplication(AppComponent, {2  providers: [provideAnimationsAsync()],3});

    アプリケーションで即時のアニメーションが必要な場合

    アプリケーションの読み込み直後にアニメーションを実行したい場合は、 即時読み込みされるアニメーションモジュールへ切り替える必要があります。代わりにprovideAnimations@angular/platform-browser/animationsからインポートし、bootstrapApplication 関数呼び出しではprovideAnimationsAsync代わりにprovideAnimationsを使用します。

    NgModuleベースのアプリケーションでは、BrowserAnimationsModuleをインポートします。これにより、アプリケーションのルートモジュールでアニメーション機能を利用できます。

    app.module.ts

    import {NgModule} from '@angular/core';import {BrowserModule} from '@angular/platform-browser';import {BrowserAnimationsModule} from '@angular/platform-browser/animations';@NgModule({  imports: [BrowserModule, BrowserAnimationsModule],  declarations: [],  bootstrap: [],})export class AppModule {}
  2. コンポーネントファイルにアニメーション関数をインポートする

    コンポーネントファイルで特定のアニメーション関数を使用する予定がある場合は、それらの関数を@angular/animationsからインポートします。

    app.ts

    import {Component, HostBinding, inject} from '@angular/core';import {  trigger,  state,  style,  animate,  transition,  // ...} from '@angular/animations';

    このガイドの末尾で、利用可能なすべてのアニメーション関数を確認できます。

  3. アニメーションメタデータプロパティを追加する

    コンポーネントファイルで、@Component()デコレーター内にanimations:というメタデータプロパティを追加します。 アニメーションを定義するトリガーは、animationsメタデータプロパティ内に配置します。

    app.ts

    @Component({  selector: 'app-root',  templateUrl: 'app.html',  styleUrls: ['app.css'],  imports: [RouterLink, RouterOutlet],  animations: [    // animation triggers go here  ],})

トランジションをアニメーション化する

1つのHTML要素をある状態から別の状態へ変化させるトランジションを、アニメーション化してみましょう。 たとえば、ユーザーの直前の操作に応じて、ボタンにOpenまたはClosedのどちらかを表示するように指定できます。 ボタンがopen状態のときは表示され、黄色です。 closed状態のときは半透明で、青色です。

HTMLでは、これらの属性は色や不透明度などの通常のCSSスタイルで設定します。 Angularでは、アニメーションで使用するCSSスタイルのセットを指定するためにstyle()関数を使用します。 スタイルのセットをアニメーション状態としてまとめ、openclosedのような名前を付けます。

HELPFUL: 単純なトランジションでアニメーション化する新しいopen-closeコンポーネントを作成しましょう。

コンポーネントを生成するには、ターミナルで次のコマンドを実行します:

ng g component open-close

これにより、src/app/open-close.tsにコンポーネントが作成されます。

アニメーションの状態とスタイル

Angularのstate()関数を使用して、各トランジションの終了時に適用する状態を定義します。 この関数は2つの引数を取ります: openclosedのような一意の名前と、style()関数です。

style()関数を使用して、指定した状態名に関連付けるスタイルのセットを定義します。 backgroundColorのようにダッシュを含むスタイル属性には_camelCase_を使うか、'background-color'のように引用符で囲む必要があります。

Angularのstate()関数が、CSSスタイル属性を設定するstyle()関数とどのように連携するかを見てみましょう。 このコードスニペットでは、その状態に対して複数のスタイル属性を同時に設定しています。 open状態では、ボタンの高さは200ピクセル、不透明度は1、背景色は黄色です。

open-close.ts

// ...      state(        'open',        style({          height: '200px',          opacity: 1,          backgroundColor: 'yellow',        }),      ),

続くclosed状態では、ボタンの高さは100ピクセル、不透明度は0.8、背景色は青です。

open-close.ts

state(        'closed',        style({          height: '100px',          opacity: 0.8,          backgroundColor: 'blue',        }),      ),

トランジションとタイミング

Angularでは、アニメーションなしでも複数のスタイルを設定できます。 ただし、さらに調整しなければ、ボタンはフェードや縮小などの変化を示さないまま瞬時に変形します。

変化をそれほど唐突にしないためには、2つの状態の間で一定時間かけて起こる変化を指定するアニメーション_トランジション_を定義する必要があります。 transition()関数は2つの引数を受け取ります: 1つ目の引数は2つのトランジション状態の方向を定義する式で、2つ目の引数は1つ以上のanimate()ステップです。

animate()関数では、トランジションの長さ、遅延、イージングを定義し、トランジション中のスタイルを指定します。 animate()関数を使って、複数ステップのアニメーションのためのkeyframes()関数も定義できます。 これらの定義は、animate()関数の2つ目の引数に配置します。

アニメーションメタデータ: 継続時間、遅延、イージング

animate()関数 (トランジション関数の2つ目の引数) は、timingsstylesの入力パラメーターを受け取ります。

timingsパラメーターは、数値または3つの部分で定義された文字列を取ります。

animate(duration);

または

animate('duration delay easing');

最初の部分であるdurationは必須です。 継続時間は、引用符なしの数値でミリ秒として表すか、引用符付きで時間指定子を付けた秒として表せます。 たとえば、10分の1秒の継続時間は次のように表せます:

  • 単なる数値で、ミリ秒として: 100

  • 文字列で、ミリ秒として: '100ms'

  • 文字列で、秒として: '0.1s'

2つ目の引数delayは、durationと同じ構文です。 例:

  • 100ms待ってから200ms実行する: '0.2s 100ms'

3つ目の引数easingは、アニメーションが実行中にどのように加速および減速するかを制御します。 たとえば、ease-inはアニメーションをゆっくり開始させ、進行するにつれて速度を上げます。

  • 100ms待って、200ms実行する。 減速カーブを使用して高速に開始し、停止点に向かってゆっくり減速します: '0.2s 100ms ease-out'

  • 200ms実行し、遅延はなし。 標準カーブを使用してゆっくり開始し、中盤で加速し、終盤でゆっくり減速します: '0.2s ease-in-out'

  • すぐに開始して、200ms実行する。 加速カーブを使用してゆっくり開始し、最大速度で終わります: '0.2s ease-in'

HELPFUL: イージングカーブの一般情報については、Material DesignのNatural easing curvesを参照してください。

この例では、openからclosedへの状態トランジションを、状態間で1秒かけて行います。

open-close.ts

transition('open => closed', [animate('1s')]),

上のコードスニペットでは、=>演算子は単方向トランジションを示し、<=>は双方向です。 トランジション内では、animate()がトランジションにかかる時間を指定します。 この場合、openからclosedへの状態変化は1秒で、ここでは1sと表現しています。

この例では、closed状態からopen状態への状態トランジションを、0.5秒のトランジションアニメーションで追加しています。

open-close.ts

transition('closed => open', [animate('0.5s')]),

HELPFUL: state()関数とtransition()関数内でスタイルを使用する際の補足です。

  • state()を使用すると、各トランジションの終了時に適用されるスタイルを定義できます。これらはアニメーション完了後も保持されます
  • transition()を使用すると、中間スタイルを定義でき、アニメーション中に動いているような錯覚を生み出します
  • アニメーションが無効な場合、transition()のスタイルはスキップされることがありますが、state()のスタイルはスキップされません
  • 同じtransition()引数内に複数の状態ペアを含めます:
    transition('on => off, off => void');

アニメーションをトリガーする

アニメーションには、いつ開始すべきかを知るための_トリガー_が必要です。 trigger()関数は状態とトランジションをまとめ、アニメーションに名前を付けることで、HTMLテンプレート内の対象要素に関連付けられるようにします。

trigger()関数は、変化を監視するプロパティ名を記述します。 変化が発生すると、トリガーはその定義に含まれるアクションを開始します。 これらのアクションは、後で見るように、トランジションやその他の関数です。

この例では、トリガーにopenCloseという名前を付け、button要素に関連付けます。 トリガーは、open状態とclosed状態、および2つのトランジションのタイミングを記述します。

HELPFUL:trigger()関数呼び出しの中では、要素は任意の時点で1つの状態にしかなれません。 ただし、複数のトリガーを同時にアクティブにできます。

アニメーションを定義してHTMLテンプレートにアタッチする

アニメーションは、アニメーション化するHTML要素を制御するコンポーネントのメタデータで定義します。 アニメーションを定義するコードは、@Component()デコレーター内のanimations:プロパティの下に配置します。

open-close.ts

@Component({  selector: 'app-open-close',  animations: [    trigger('openClose', [      // ...      state(        'open',        style({          height: '200px',          opacity: 1,          backgroundColor: 'yellow',        }),      ),      state(        'closed',        style({          height: '100px',          opacity: 0.8,          backgroundColor: 'blue',        }),      ),      transition('open => closed', [animate('1s')]),      transition('closed => open', [animate('0.5s')]),    ]),  ],  templateUrl: 'open-close.html',  styleUrls: ['open-close.css'],})export class OpenClose {  isOpen = true;  toggle() {    this.isOpen = !this.isOpen;  }}

コンポーネントのアニメーショントリガーを定義したら、そのコンポーネントのテンプレート内の要素に、トリガー名を角括弧で囲み、先頭に@記号を付けて関連付けます。 その後、次に示すように、標準のAngularプロパティバインディング構文を使ってトリガーをテンプレート式にバインドできます。ここで、triggerNameはトリガー名、expressionは定義済みのアニメーション状態に評価されます。

<div [@triggerName]="expression">…</div>

式の値が新しい状態に変化すると、アニメーションが実行されます。

次のコードスニペットでは、トリガーをisOpenプロパティの値にバインドしています。

open-close.html

<nav>  <button type="button" (click)="toggle()">Toggle Open/Close</button></nav><div [@openClose]="isOpen ? 'open' : 'closed'" class="open-close-container">  <p>The box is now {{ isOpen ? 'Open' : 'Closed' }}!</p></div>

この例では、isOpen式の値が定義済みのopenまたはclosed状態になると、トリガーopenCloseに状態変化を通知します。 その後は、openCloseのコードが状態変化を処理し、状態変化アニメーションを開始します。

ページに出入りする要素 (DOMに挿入またはDOMから削除される要素) では、アニメーションを条件付きにできます。 たとえば、HTMLテンプレートでアニメーショントリガーと一緒に*ngIfを使用します。

HELPFUL: コンポーネントファイルでは、アニメーションを定義するトリガーを、@Component()デコレーター内のanimations:プロパティの値として設定します。

HTMLテンプレートファイルでは、トリガー名を使って、定義したアニメーションをアニメーション化するHTML要素に関連付けます。

コードレビュー

次のコードファイルが、トランジションの例で説明した内容です。

まとめ

style()state()、およびタイミングのためのanimate()を使用して、2つの状態間のトランジションにアニメーションを追加する方法を学びました。

より高度な機能については、transition and triggersから読み進めてください。

Animations APIの概要

@angular/animationsモジュールが提供する関数型APIは、Angularアプリケーションでアニメーションを作成および制御するためのドメイン固有言語 (DSL) を提供します。 コア関数と関連データ構造の完全な一覧と構文の詳細については、APIリファレンスを参照してください。

関数名 役割
trigger() アニメーションを開始し、他のすべてのアニメーション関数呼び出しのコンテナーとして機能します。HTMLテンプレートはtriggerNameにバインドします。最初の引数を使って一意のトリガー名を宣言します。配列構文を使用します。
style() アニメーションで使用する1つ以上のCSSスタイルを定義します。アニメーション中のHTML要素の見た目を制御します。オブジェクト構文を使用します。
state() 指定した状態へのトランジションが成功したときに適用される、名前付きのCSSスタイルセットを作成します。この状態は、他のアニメーション関数内で名前で参照できます。
animate() トランジションのタイミング情報を指定します。delayeasingは省略可能です。内部にstyle()呼び出しを含められます。
transition() 2つの名前付き状態間のアニメーションシーケンスを定義します。配列構文を使用します。
keyframes() 指定した時間範囲内で順次スタイルを変化させます。animate()の中で使用します。各keyframe()の内側に複数のstyle()呼び出しを含められます。配列構文を使用します。
group() 並列に実行するアニメーションステップのグループ(内側のアニメーション)を指定します。すべての内側のアニメーションステップが完了した後でのみ、アニメーションは続行されます。sequence()またはtransition()内で使用します。
query() 現在の要素の内側にある1つ以上のHTML要素を検索します。
sequence() 順番に1つずつ実行されるアニメーションステップのリストを指定します。
stagger() 複数要素のアニメーション開始時刻をずらします。
animation() 別の場所から呼び出せる再利用可能なアニメーションを生成します。useAnimation()と併用します。
useAnimation() 再利用可能なアニメーションを有効化します。animation()と併用します。
animateChild() 子コンポーネントのアニメーションを、親と同じ時間枠で実行できるようにします。

Angularアニメーションについてさらに詳しく

HELPFUL: 2017年11月のAngularConnectカンファレンスで紹介されたこのプレゼンテーションと、付属するソースコードも確認してください。

以下の項目にも興味があるかもしれません: