Angular LAB: menyenaraikan animasi dan menggunakan AnimationBuilder untuk animasi imperatif

Barbara Streisand
Lepaskan: 2024-10-10 06:18:29
asal
810 orang telah melayarinya

Angular LAB: animating lists and using AnimationBuilder for imperative animations

Tahukah anda bahawa Angular termasuk sistem animasi yang kompleks? Saya mendapati ia amat berguna apabila saya ingin menghidupkan elemen apabila ia memasuki skrin atau apabila ia dimusnahkan!

Selain itu, anda boleh menggunakan AnimationBuilder untuk memainkan, menjeda atau menghentikan beberapa animasi tersuai secara mustahak! Mari lihat bagaimana ia dilakukan.

Mencipta senarai

Dalam latihan ini kita mulakan dengan mencipta senarai, seperti ini:

@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' }]);
  }
}
Salin selepas log masuk

Perhatikan bahawa kami telah menyertakan butang yang menambahkan pengguna pada senarai!

Menghidupkan senarai

Sekarang, bagaimana jika kita mahu menghidupkan pengguna baharu yang akan ditambah? Pertama, kami ingin memberitahu Angular bahawa kami ingin menggunakan sistem animasinya dengan menyediakannya dalam konfigurasi utama anda:

import { provideAnimationsAsync } from '@angular/platform-browser/animations/async';

bootstrapApplication(AppComponent, {
  providers: [
    provideAnimationsAsync(),
  ]
});
Salin selepas log masuk

Kemudian, kami boleh mencipta animasi kami:

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 })
    )
  ])
])
Salin selepas log masuk

Dengan pembantu ini kami:

  • Mencipta pencetus animasi yang dipanggil fadeIn
  • Menambahkan peralihan apabila elemen memasuki skrin
  • Menggunakan gaya awal
  • Segera memulakan animasi yang akan menghasilkan gaya baharu yang digunakan pada elemen

Untuk mendapatkan maklumat lanjut tentang cara menulis animasi, anda boleh merujuk kepada panduan rasmi yang hebat!

Sekarang mari gunakan animasi ini pada setiap elemen kami dalam senarai:

@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]
}) 
Salin selepas log masuk

Kini, apabila item baharu ditambahkan, ia akan dianimasikan! Langkah pertama kami telah selesai.

Perhatikan bahawa agar animasi kami berfungsi dengan betul, Angular perlu menjejaki setiap elemen dalam untuk kami, kerana jika tidak, ia mungkin akan mencipta semula elemen yang sama apabila mengemas kini templat, mengakibatkan yang tidak diingini animasi. Ini datang secara percuma dengan sintaks Aliran Kawalan baharu kerana sifat trek adalah wajib, tetapi jika anda menggunakan versi lama Angular dengan arahan *ngFor, anda mesti menggunakan pilihan trackBy seperti ini:

<li
  *ngFor="let user of users; trackBy: trackByUserId"
  @fadeIn
>{{ user.name }}</li>
Salin selepas log masuk
// A class method in your component:
trackByUserId(index, user: User) {
  return user.id;
}
Salin selepas log masuk

Sekarang, mari tambah satu lagi jenis animasi pada senarai kami.

Pembina Animasi

Mari tambahkan butang pada setiap elemen senarai kami:

<li @fadeIn>
  {{ user.name }}
  <button>Make me blink</button>
</li>
Salin selepas log masuk

Bayangkan ini: kita mahu membuat elemen berkelip apabila kita menekan butang. Itu pasti keren! Di sinilah perkhidmatan AnimationBuilder masuk.

Pertama, mari buat Arahan yang akan digunakan pada setiap elemen. Dalam arahan ini, kami akan menyuntik kedua-dua ElementRef dan 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);
}
Salin selepas log masuk

Perhatikan bahawa kami mengeksport arahan: kami akan mengetahui sebabnya dalam beberapa saat.

Kemudian, kita boleh mencipta animasi tersuai seperti ini:

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 }))
  ]);
}
Salin selepas log masuk

Kami menggunakan fungsi yang sama yang kami gunakan dalam animasi sebelumnya, hanya dengan gaya yang berbeza.

Sekarang kami ingin mencipta pemain yang akan melaksanakan animasi pada elemen kami:

export class BlinkDirective {

  ...

  private player = this.animation.create(this.el.nativeElement);
}
Salin selepas log masuk

Dan sekarang mari kita dedahkan kaedah yang sebenarnya akan memulakan animasi!

export class BlinkDirective {

  ...

  start() {
    this.player.play();
  }
}
Salin selepas log masuk

Hanya ada satu langkah lagi: kita mesti mengimport arahan, gunakannya pada elemen kita, ambil dengan pembolehubah templat dan panggil kaedah apabila butang ditekan!

@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
  ]
})
Salin selepas log masuk

Kami boleh mengambil contoh arahan dan meletakkannya dalam pembolehubah tempatan kerana kami sebelum ini mengeksport arahan dengan exportAs. Itulah bahagian penting!

Sekarang, cuba klik pada butang: elemen yang akan dianimasikan dengan betul!

Senaman sudah selesai, tetapi ini hanyalah puncak gunung ais! AnimationPlayer mempunyai banyak arahan yang boleh anda gunakan untuk menghentikan, menjeda dan menyambung semula animasi. Sangat keren!

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;
}
Salin selepas log masuk

Inilah contoh penuh kami jika anda mahu bermain dengannya: cuma masukkannya ke dalam fail main.ts anda dan lihat ia beraksi!

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()
  ]
});
Salin selepas log masuk

Atas ialah kandungan terperinci Angular LAB: menyenaraikan animasi dan menggunakan AnimationBuilder untuk animasi imperatif. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

sumber:dev.to
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Artikel terbaru oleh pengarang
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan