ホームページ > 記事 > ウェブフロントエンド > Angular LAB: リストのアニメーション化と命令型アニメーション用のAnimationBuilderの使用
Angular には複雑なアニメーション システムが含まれていることをご存知ですか?要素が画面に入ったとき、または要素が破壊されたときにアニメーション化したい場合に特に便利です!
また、AnimationBuilder を使用して、一部のカスタム アニメーションを強制的に再生、一時停止、または停止することもできます。それがどのように行われるかを見てみましょう。
この演習では、次のようなリストを作成することから始めます:
@Component({ selector: 'app-root', standalone: true, template: ` <button (click)="addUser()">Add user</button> <ul> @for (user of users(); track user.id) { <li>{{ user.name }}</li> } </ul> `, }) export class AppComponent { users = signal<User[]>([ { id: Math.random(), name: 'Michele' } ]); addUser() { this.users.update(users => [...users, { id: Math.random(), name: 'New user' }]); } }
リストにユーザーを追加するボタンが含まれていることに注意してください!
では、追加される新しいユーザーをアニメーション化したい場合はどうすればよいでしょうか?まず、メイン設定でアニメーション システムを提供することで、Angular にアニメーション システムを使用したいことを伝えます。
import { provideAnimationsAsync } from '@angular/platform-browser/animations/async'; bootstrapApplication(AppComponent, { providers: [ provideAnimationsAsync(), ] });
次に、アニメーションを作成します。
import { trigger, transition, style, animate } from '@angular/animations'; const fadeInAnimation = trigger('fadeIn', [ transition(':enter', [ style({ transform: 'scale(0.5)', opacity: 0 }), animate( '.3s cubic-bezier(.8, -0.6, 0.2, 1.5)', style({ transform: 'scale(1)', opacity: 1 }) ) ]) ])
これらのヘルパーを使用して、次のことを行います。
アニメーションの書き方の詳細については、素晴らしい公式ガイドを参照してください。
次に、このアニメーションをリスト内の各要素に適用しましょう:
@Component({ ..., template: ` <button (click)="addUser()">Add user</button> <ul> @for (user of users(); track user.id) { <li @fadeIn>{{ user.name }}</li> <!-- Notice here --> } </ul> `, // Also, add the animation to the metadata of the component animations: [fadeInAnimation] })
新しいアイテムが追加されると、アニメーションが表示されます。最初のステップは完了しました。
アニメーションが正しく動作するためには、Angular for 内の各要素を追跡する必要があることに注意してください。そうしないと、テンプレートの更新時に同じ要素が再作成されてしまい、望ましくない結果が生じる可能性があるためです。アニメーション。新しい制御フロー構文では、track プロパティが必須であるため、これは無料で提供されますが、*ngFor ディレクティブで古いバージョンの Angular を使用している場合は、次のように trackBy オプションを使用する必要があります。
<li *ngFor="let user of users; trackBy: trackByUserId" @fadeIn >{{ user.name }}</li>
// A class method in your component: trackByUserId(index, user: User) { return user.id; }
次に、別のタイプのアニメーションをリストに追加しましょう。
リストの各要素にボタンを追加しましょう:
<li @fadeIn> {{ user.name }} <button>Make me blink</button> </li>
これを想像してください。ボタンを押したときに要素を点滅させたいと考えています。それはいいですね!ここで、AnimationBuilder サービスが登場します。
まず、すべての要素に適用されるディレクティブを作成しましょう。このディレクティブでは、ElementRef とAnimationBuilder の両方を挿入します:
import { AnimationBuilder, style, animate } from '@angular/animations'; @Directive({ selector: '[blink]', exportAs: 'blink', // <--- Notice standalone: true }) export class BlinkDirective { private animationBuilder = inject(AnimationBuilder); private el = inject(ElementRef); }
ディレクティブをエクスポートしたことに注目してください。理由は数秒でわかります。
次に、次のようなカスタム アニメーションを作成できます:
export class BlinkDirective { ... private animation = this.animationBuilder.build([ style({ transform: 'scale(1)', opacity: 1 }), animate(150, style({ transform: 'scale(1.1)', opacity: .5 })), animate(150, style({ transform: 'scale(1)', opacity: 1 })) ]); }
スタイルが異なるだけで、前のアニメーションで使用したのと同じ関数を使用しています。
次に、要素でアニメーションを実行する プレーヤー を作成します。
export class BlinkDirective { ... private player = this.animation.create(this.el.nativeElement); }
それでは、実際にアニメーションを開始するメソッドを公開しましょう!
export class BlinkDirective { ... start() { this.player.play(); } }
残っているステップは 1 つだけです。ディレクティブをインポートし、要素に適用し、テンプレート変数 で取得して、ボタンが押されたときにメソッドを呼び出す必要があります。
@Component({ selector: 'app-root', standalone: true, template: ` <button (click)="addUser()">Add user</button> <ul> @for (user of users(); track user.id) { <li @fadeIn blink #blinkDir="blink"> {{ user.name }} <button (click)="blinkDir.start()">Make me blink</button> </li> } </ul> `, imports: [BlinkDirective], animations: [ fadeInAnimation ] })
以前にexportAsを使用してディレクティブをエクスポートしたため、ディレクティブのインスタンスを取得してローカル変数に入れることができます。それが重要な部分です!
それでは、ボタンをクリックしてみてください。要素は正しくアニメーション化されるはずです!
演習は完了しましたが、これは氷山の一角にすぎません。 AnimationPlayer には、アニメーションを停止、一時停止、再開するために使用できるコマンドが多数あります。とてもクールです!
interface AnimationPlayer { onDone(fn: () => void): void; onStart(fn: () => void): void; onDestroy(fn: () => void): void; init(): void; hasStarted(): boolean; play(): void; pause(): void; restart(): void; finish(): void; destroy(): void; reset(): void; setPosition(position: number): void; getPosition(): number; parentPlayer: AnimationPlayer; readonly totalTime: number; beforeDestroy?: () => any; }
実際に試してみたい場合は、完全な例を次に示します。main.ts ファイルに入れて、実際の動作を確認してください。
import { Component, signal, Directive, ElementRef, inject } from '@angular/core'; import { bootstrapApplication } from '@angular/platform-browser'; import { trigger, transition, style, animate, AnimationBuilder } from '@angular/animations'; import { provideAnimationsAsync } from '@angular/platform-browser/animations/async'; interface User { id: number; name: string; } @Directive({ selector: '[blink]', exportAs: 'blink', standalone: true }) export class BlinkDirective { private animationBuilder = inject(AnimationBuilder); private el = inject(ElementRef); private animation = this.animationBuilder.build([ style({ transform: 'scale(1)', opacity: 1 }), animate(150, style({ transform: 'scale(1.1)', opacity: .5 })), animate(150, style({ transform: 'scale(1)', opacity: 1 })) ]); private player = this.animation.create(this.el.nativeElement); start() { this.player.play(); } } const fadeInAnimation = trigger('fadeIn', [ transition(':enter', [ style({ transform: 'scale(0.5)', opacity: 0 }), animate( '.3s cubic-bezier(.8, -0.6, 0.2, 1.5)', style({ transform: 'scale(1)', opacity: 1 }) ) ]) ]) @Component({ selector: 'app-root', standalone: true, template: ` <button (click)="addUser()">Add user</button> <ul> @for (user of users(); track user.id) { <li @fadeIn blink #blinkDir="blink"> {{ user.name }} <button (click)="blinkDir.start()">Make me blink</button> </li> } </ul> `, imports: [BlinkDirective], animations: [ fadeInAnimation ] }) export class App { users = signal([ { id: Math.random(), name: 'Michele' } ]); addUser() { this.users.update(users => [...users, { id: Math.random(), name: 'New user' }]); } } bootstrapApplication(App, { providers: [ provideAnimationsAsync() ] });
以上がAngular LAB: リストのアニメーション化と命令型アニメーション用のAnimationBuilderの使用の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。