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(); } }
한 단계만 남았습니다. 지시문을 가져와서 요소에 적용한 다음 템플릿 변수로 가져오고 버튼을 눌렀을 때 메서드를 호출해야 합니다!
@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 ] })
이전에 importAs를 사용하여 지시문을 내보냈기 때문에 지시문의 인스턴스를 가져와 로컬 변수에 넣을 수 있습니다. 그게 핵심이에요!
이제 버튼을 클릭해 보세요. 요소가 올바르게 애니메이션될 것입니다!
운동은 끝났지만 이는 빙산의 일각에 불과합니다! 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 중국어 웹사이트의 기타 관련 기사를 참조하세요!