詳細ガイド
アニメーション

animate.enteranimate.leaveを使ったアプリケーションのアニメーション

適切に設計されたアニメーションは、アプリケーションをより楽しく、分かりやすく使用できるようにしますが、単なる装飾ではありません。 アニメーションは、いくつかの方法でアプリケーションとユーザー体験を向上させることができます。

  • アニメーションがないと、ウェブページの遷移は突然で不快に感じられることがあります
  • モーションはユーザー体験を大幅に向上させるため、アニメーションはユーザーが自分のアクションに対するアプリケーションの応答を検出する機会を与えます
  • 優れたアニメーションは、ワークフロー全体でユーザーの注意をスムーズに誘導できます

Angularは、アプリケーションの要素をアニメーション化するためにanimate.enteranimate.leaveを提供します。これら2つの機能は、適切なタイミングでenterおよびleaveのCSSクラスを適用するか、サードパーティライブラリからアニメーションを適用する関数を呼び出します。animate.enteranimate.leaveはディレクティブではありません。これらはAngularコンパイラによって直接サポートされる特別なAPIです。これらは要素に直接使用できるほか、ホストバインディングとしても使用できます。

animate.enter

animate.enterはDOMに_入る_要素をアニメーション化するために使用できます。CSSクラスと、transformまたはキーフレームアニメーションのいずれかを使用して、enterアニメーションを定義できます。

src/app/enter.ts

import {Component, signal} from '@angular/core';@Component({  selector: 'app-enter',  templateUrl: 'enter.html',  styleUrls: ['enter.css'],})export class Enter {  isShown = signal(false);  toggle() {    this.isShown.update((isShown) => !isShown);  }}

src/app/enter.html

<h2><code>animate.enter</code> Example</h2><button type="button" (click)="toggle()">Toggle Element</button>@if (isShown()) {  <div class="enter-container" animate.enter="enter-animation">    <p>The box is entering.</p>  </div>}

src/app/enter.css

:host {  display: block;  height: 200px;}.enter-container {  border: 1px solid #dddddd;  margin-top: 1em;  padding: 20px 20px 0px 20px;  font-weight: bold;  font-size: 20px;}.enter-animation {  animation: slide-fade 1s;}@keyframes slide-fade {  from {    opacity: 0;    transform: translateY(20px);  }  to {    opacity: 1;    transform: translateY(0);  }}

アニメーションが完了すると、Angularはanimate.enterで指定したクラスをDOMから削除します。アニメーションクラスは、アニメーションがアクティブな間のみ存在します。

NOTE: 要素で複数のキーフレームアニメーションまたはtransitionプロパティを使用している場合、Angularは最も長いアニメーションが完了した_後にのみ_すべてのクラスを削除します。

animate.enterは、制御フローや動的式など、他のAngular機能と組み合わせて使用できます。animate.enterは、単一のクラス文字列(複数のクラスがスペースで区切られているもの)またはクラス文字列の配列を受け入れます。

src/app/enter-binding.ts

import {Component, signal} from '@angular/core';@Component({  selector: 'app-enter-binding',  templateUrl: 'enter-binding.html',  styleUrls: ['enter-binding.css'],})export class EnterBinding {  isShown = signal(false);  toggle() {    this.isShown.update((isShown) => !isShown);  }  enterClass = signal('enter-animation');}

src/app/enter-binding.html

<h2><code>animate.enter</code> Binding Example</h2><button type="button" (click)="toggle()">Toggle Element</button>@if (isShown()) {  <div class="enter-container" [animate.enter]="enterClass()">    <p>The box is entering.</p>  </div>}

src/app/enter-binding.css

:host {  display: block;  height: 200px;}.enter-container {  border: 1px solid #dddddd;  margin-top: 1em;  padding: 20px 20px 0px 20px;  font-weight: bold;  font-size: 20px;}.enter-animation {  animation: slide-fade 1s;}@keyframes slide-fade {  from {    opacity: 0;    transform: translateY(20px);  }  to {    opacity: 1;    transform: translateY(0);  }}

animate.leave

animate.leave を使用して、要素がDOMから_離れる_ときにアニメーションを適用できます。CSSクラスと、transformまたはキーフレームアニメーションのいずれかを使用して、離脱アニメーションを定義できます。

src/app/leave.ts

import {Component, signal} from '@angular/core';@Component({  selector: 'app-leave',  templateUrl: 'leave.html',  styleUrls: ['leave.css'],})export class Leave {  isShown = signal(false);  toggle() {    this.isShown.update((isShown) => !isShown);  }}

src/app/leave.html

<h2><code>animate.leave</code> Example</h2><button type="button" (click)="toggle()">Toggle Element</button>@if (isShown()) {  <div class="leave-container" animate.leave="leaving">    <p>Goodbye</p>  </div>}

src/app/leave.css

:host {  display: block;  height: 200px;}.leave-container {  border: 1px solid #dddddd;  margin-top: 1em;  padding: 20px 20px 0px 20px;  font-weight: bold;  font-size: 20px;  opacity: 1;  transition: opacity 200ms ease-in;  @starting-style {    opacity: 0;  }}.leaving {  opacity: 0;  transform: translateY(20px);  transition: opacity 500ms ease-out, transform 500ms ease-out;}

アニメーションが完了すると、Angularはアニメーション化された要素をDOMから自動的に削除します。

NOTE: 要素に複数のキーフレームアニメーションまたはtransitionプロパティを使用する場合、Angularはそれらのアニメーションの中で最も長いものが完了した_後にのみ_要素を削除します。

animate.leave はsignalsやその他のbindingでも使用できます。animate.leave は単一のクラスまたは複数のクラスで使用できます。スペースで区切られた単純な文字列として指定するか、文字列配列として指定します。

src/app/leave-binding.ts

import {Component, signal} from '@angular/core';@Component({  selector: 'app-leave-binding',  templateUrl: 'leave-binding.html',  styleUrls: ['leave-binding.css'],})export class LeaveBinding {  isShown = signal(false);  toggle() {    this.isShown.update((isShown) => !isShown);  }  farewell = signal('leaving');}

src/app/leave-binding.html

<h2><code>animate.leave</code> Binding Example</h2><button type="button" (click)="toggle()">Toggle Element</button>@if (isShown()) {  <div class="leave-container" [animate.leave]="farewell()">    <p>Goodbye</p>  </div>}

src/app/leave-binding.css

:host {  display: block;  height: 200px;}.leave-container {  border: 1px solid #dddddd;  margin-top: 1em;  padding: 20px 20px 0px 20px;  font-weight: bold;  font-size: 20px;  opacity: 1;  transition: opacity 200ms ease-in;  @starting-style {    opacity: 0;  }}.leaving {  opacity: 0;  transform: translateY(20px);  transition: opacity 500ms ease-out, transform 500ms ease-out;}

イベントバインディング、関数、およびサードパーティライブラリ

animate.enteranimate.leaveはどちらも、関数呼び出しを可能にするイベントバインディング構文をサポートしています。この構文を使用して、コンポーネントコード内の関数を呼び出したり、GSAPanime.jsなどのサードパーティのアニメーションライブラリ、またはその他のJavaScriptアニメーションライブラリを利用したり可能です。

src/app/leave-event.ts

import {AnimationCallbackEvent, Component, signal} from '@angular/core';@Component({  selector: 'app-leave-binding',  templateUrl: 'leave-event.html',  styleUrls: ['leave-event.css'],})export class LeaveEvent {  isShown = signal(false);  toggle() {    this.isShown.update((isShown) => !isShown);  }  leavingFn(event: AnimationCallbackEvent) {    // Example of calling GSAP    // gsap.to(event.target, {    //   duration: 1,    //   x: 100,    //   // arrow functions are handy for concise callbacks    //   onComplete: () => event.animationComplete()    // });    event.animationComplete();  }}

src/app/leave-event.html

<h2><code>animate.leave</code> Function Example</h2><button type="button" (click)="toggle()">Toggle Element</button>@if (isShown()) {  <div class="leave-container" (animate.leave)="leavingFn($event)">    <p>Goodbye</p>  </div>}

src/app/leave-event.css

:host {  display: block;  height: 200px;}.leave-container {  border: 1px solid #dddddd;  margin-top: 1em;  padding: 20px 20px 0px 20px;  font-weight: bold;  font-size: 20px;  opacity: 1;  transition: opacity 200ms ease-in;  @starting-style {    opacity: 0;  }}.leaving {  opacity: 0;  transform: translateY(20px);  transition: opacity 500ms ease-out, transform 500ms ease-out;}

$eventオブジェクトはAnimationCallbackEvent型です。これにはtargetとして要素が含まれ、アニメーションが終了したときにフレームワークに通知するためのanimationComplete()関数を提供します。

IMPORTANT: Angularが要素を削除するためには、animate.leaveを使用する際にanimationComplete()関数を必ず呼び出す必要があります。

animate.leaveを使用する際にanimationComplete()を呼び出さない場合、Angularは4秒の遅延後に自動的にその関数を呼び出します。遅延の期間は、MAX_ANIMATION_TIMEOUTトークンをミリ秒単位で提供することにより設定できます。

  { provide: MAX_ANIMATION_TIMEOUT, useValue: 6000 }

テスト

TestBedは、テスト環境でアニメーションを有効または無効にするための組み込みサポートを提供します。CSSアニメーションはブラウザでの実行が必要であり、多くのAPIはテスト環境では利用できません。デフォルトでは、TestBedはテスト環境でアニメーションを無効にします。

ブラウザテスト、例えばエンドツーエンドテストでアニメーションが動作していることをテストしたい場合は、テスト設定でanimationsEnabled: trueを指定することで、TestBedをアニメーションを有効にするように設定できます。

  TestBed.configureTestingModule({animationsEnabled: true});

これにより、テスト環境でのアニメーションが通常通りに動作するように設定されます。

NOTE: 一部のテスト環境では、animationstartanimationendのようなアニメーションイベントや、それらに相当するトランジションイベントを発行しません。