심화 가이드
애니메이션

animate.enter와 animate.leave로 애플리케이션에 애니메이션 적용하기

잘 설계된 애니메이션은 애플리케이션을 더 직관적이고 매력적으로 만듭니다. 하지만 애니메이션은 단순한 장식에 그치지 않습니다. 애니메이션은 여러 방식으로 애플리케이션과 사용자 경험을 개선할 수 있습니다:

  • 애니메이션이 없으면 웹 페이지의 전환이 갑작스럽고 부자연스럽게 느껴질 수 있습니다.
  • 움직임은 사용자 경험을 크게 향상시킵니다. 애니메이션을 통해 사용자는 자신의 행동에 애플리케이션이 어떻게 반응하는지 알아차릴 수 있습니다.
  • 좋은 애니메이션은 작업 흐름 전체에서 사용자의 시선을 자연스럽게 유도할 수 있습니다.

Angular는 애플리케이션의 엘리먼트에 애니메이션을 적용하는 animate.enter와 animate.leave를 제공합니다. 두 기능은 적절한 시점에 진입 및 퇴장 CSS 클래스를 적용하거나, 서드 파티 라이브러리의 애니메이션을 적용하는 함수를 호출합니다. animate.enter와 animate.leave는 디렉티브가 아닙니다. Angular 컴파일러가 직접 지원하는 특별한 API이며, 엘리먼트에 직접 사용하거나 호스트 바인딩으로 사용할 수 있습니다.

animate.enter

animate.enter를 사용하면 엘리먼트가 DOM에 진입 할 때 애니메이션을 적용할 수 있습니다. 전환이나 키프레임 애니메이션을 지정한 CSS 클래스로 진입 애니메이션을 정의할 수 있습니다.

애니메이션이 완료되면 Angular는 animate.enter에 지정한 클래스를 DOM에서 제거합니다. 애니메이션 클래스는 애니메이션이 실행되는 동안에만 존재합니다.

참고: 엘리먼트에 여러 키프레임 애니메이션이나 전환 프로퍼티를 사용하면 Angular는 가장 긴 애니메이션이 완료된 뒤에 모든 클래스를 제거합니다.

animate.enter는 제어 흐름이나 동적 표현식 같은 다른 Angular 기능과 함께 사용할 수 있습니다. animate.enter에는 클래스 문자열 하나를 전달하거나, 클래스 문자열의 배열을 전달할 수 있습니다. 문자열 하나에 여러 클래스를 지정할 때는 공백으로 구분합니다.

CSS 전환을 사용할 때는 한 가지 유의할 점이 있습니다. 키프레임 애니메이션 대신 전환을 사용하면 animate.enter로 추가한 클래스는 전환의 도착 상태를 나타냅니다. 엘리먼트의 기본 CSS는 애니메이션이 실행되지 않을 때의 모습을 정의하며, 대개 CSS 전환의 최종 상태와 비슷합니다. 따라서 전환이 동작할 수 있도록 @starting-style을 함께 사용해서 적절한 시작 상태를 지정해야 합니다.

animate.leave

animate.leave를 사용하면 엘리먼트가 DOM에서 퇴장 할 때 애니메이션을 적용할 수 있습니다. 변형이나 키프레임 애니메이션을 지정한 CSS 클래스로 퇴장 애니메이션을 정의할 수 있습니다.

애니메이션이 완료되면 Angular는 애니메이션이 적용된 엘리먼트를 DOM에서 자동으로 제거합니다.

참고: 엘리먼트에 여러 키프레임 애니메이션이나 전환 프로퍼티를 사용하면 Angular는 가장 긴 애니메이션이 완료된 뒤에 엘리먼트를 제거합니다.

animate.leave는 시그널이나 다른 바인딩과 함께 사용할 수도 있습니다. animate.leave에는 클래스 하나 또는 여러 개를 사용할 수 있으며, 공백으로 구분한 문자열이나 문자열 배열로 지정하면 됩니다.

엘리먼트 제거 순서

animate.leave 애니메이션의 실행 방식과 시점에는 알아둘 세부 사항이 있습니다. 제거되는 엘리먼트에 animate.leave가 지정되어 있으면 애니메이션이 실행됩니다. 같은 컴포넌트 템플릿 안에서 제거되는 엘리먼트의 하위 엘리먼트에 animate.leave가 지정되어 있으면, 자식 animate.leave 애니메이션은 부모 노드가 DOM에서 제거되기 전에 실행됩니다. 따라서 부모 노드가 너무 일찍 사라지는 일을 걱정하지 않고 자식 엘리먼트의 퇴장 애니메이션을 적용할 수 있습니다.

중요: 자식 애니메이션은 같은 컴포넌트 템플릿 안의 엘리먼트에 대해서만 실행됩니다. 제거할 엘리먼트에 자식 컴포넌트가 있으면, 자식 컴포넌트 템플릿 안에 정의된 animate.leave 애니메이션은 부모가 제거되기 전에 실행되지 않습니다. 자식 컴포넌트를 제거할 때 애니메이션을 실행하려면 부모 템플릿에서 자식 컴포넌트의 호스트 엘리먼트에 animate.leave를 직접 적용하세요. 또는 코드로 자식 컴포넌트의 애니메이션을 실행하고, 애니메이션이 끝날 때까지 부모 제거를 지연할 수 있습니다.

이벤트 바인딩, 함수, 서드 파티 라이브러리

animate.enter와 animate.leave는 모두 함수를 호출할 수 있는 이벤트 바인딩 문법을 지원합니다. 이 문법으로 컴포넌트 코드의 함수를 호출하거나, GSAP, anime.js 또는 다른 JavaScript 애니메이션 라이브러리를 사용할 수 있습니다.

$event 객체의 타입은 AnimationCallbackEvent입니다. 이 객체는 엘리먼트를 target으로 포함하며, 애니메이션이 끝났음을 프레임워크에 알리는 animationComplete() 함수를 제공합니다.

중요: animate.leave를 사용할 때 Angular가 엘리먼트를 제거하도록 하려면 animationComplete() 함수를 반드시 호출해야 합니다.

animate.leave를 사용하면서 animationComplete()를 호출하지 않으면 Angular가 4초 뒤에 이 함수를 자동으로 호출합니다. MAX_ANIMATION_TIMEOUT 토큰에 밀리초 단위의 값을 제공하면 지연 시간을 설정할 수 있습니다.

{ provide: MAX_ANIMATION_TIMEOUT, useValue: 6000 }

기존 Angular 애니메이션과의 호환성

같은 컴포넌트 안에서 기존 애니메이션과 animate.enter, animate.leave를 함께 사용할 수 없습니다. 함께 사용하면 진입 클래스가 엘리먼트에 남아 있거나 퇴장 노드가 제거되지 않는 문제가 생깁니다. 그 외에는 같은 애플리케이션 안에서 기존 애니메이션과 새로운 animate.enter, animate.leave 애니메이션을 함께 사용해도 됩니다. 다만 콘텐츠 프로젝션은 주의해야 합니다. 기존 애니메이션을 사용하는 컴포넌트의 콘텐츠를 animate.enter나 animate.leave를 사용하는 다른 컴포넌트에 투영하거나 그 반대로 투영하면, 같은 컴포넌트에서 함께 사용한 것과 같은 문제가 발생합니다. 이 방식은 지원하지 않습니다.

테스트하기

TestBed는 테스트 환경에서 애니메이션을 활성화하거나 비활성화하는 기능을 기본으로 제공합니다. CSS 애니메이션을 실행하려면 브라우저가 필요하며, 관련 API 중 상당수는 테스트 환경에서 사용할 수 없습니다. TestBed는 기본적으로 테스트 환경의 애니메이션을 비활성화합니다.

엔드 투 엔드 테스트처럼 브라우저에서 실행하는 테스트에서 애니메이션 동작을 확인하려면, 테스트 설정에 animationsEnabled: true를 지정해서 TestBed의 애니메이션을 활성화할 수 있습니다.

TestBed.configureTestingModule({animationsEnabled: true});

이렇게 설정하면 테스트 환경에서도 애니메이션이 정상적으로 동작합니다.

참고: 일부 테스트 환경은 animationstart, animationend와 같은 애니메이션 이벤트나 이에 대응하는 전환 이벤트를 발생시키지 않습니다.

Angular 애니메이션 더 알아보기

다음 문서도 참고해 보세요: