Chromium 84의 Web Animations API 개선사항

약속으로 애니메이션 조정, 교체 가능한 애니메이션으로 성능 개선, 복합 모드로 더 부드러운 애니메이션 등

게시일: 2020년 5월 27일

애니메이션을 올바르게 사용하면 브랜드에 대한 사용자 인식과 기억을 개선하고, 사용자 작업을 안내하며, 사용자가 애플리케이션을 탐색하는 데 도움을 주어 디지털 공간에서 맥락을 제공할 수 있습니다.

Web Animations API는 개발자가 JavaScript로 명령형 애니메이션을 작성할 수 있는 도구입니다. CSS 애니메이션과 전환 구현을 모두 뒷받침하고 향후 효과를 개발할 수 있도록 하며 기존 효과를 구성하고 타이밍을 지정할 수 있도록 작성되었습니다.

FirefoxSafari는 이미 전체 사양 기능을 구현했지만 Chromium 84에서는 이전에 지원되지 않았던 여러 기능을 Chrome 및 Edge에 도입하여 교차 브라우저 상호 운용성을 지원합니다.

Web Animations API는 2014년 7월 버전 36에서 Chromium에 처음 등장했습니다. 이제 2020년 7월에 출시되는 버전 84에서 사양이 완성될 예정입니다.
Chromium의 Web Animations API의 오랜 역사

시작하기

@keyframe 규칙을 사용해 본 적이 있다면 Web Animations API를 사용하여 애니메이션을 만드는 것이 매우 익숙할 것입니다. 먼저 키프레임 객체를 만들어야 합니다. CSS에서는 다음과 같이 표시될 수 있습니다. 이렇게

@keyframes openAnimation {
  0% {
    transform: scale(0);
  }
  100% {
    transform: scale(1);
  }
}

JavaScript에서는 이렇게 표시됩니다.

const openAnimation = [
  { transform: 'scale(0)' },
  { transform: 'scale(1)' },
];

CSS에서 애니메이션 매개변수를 설정하는 위치:

.modal {
  animation: openAnimation 1s 1 ease-in;
}

JS에서 다음과 같이 설정합니다.

document.querySelector('.modal').animate(
    openAnimation, {
      duration: 1000, // 1s
      iterations: 1, // single iteration
      easing: 'ease-in' // easing function
    }
);

코드의 양은 거의 비슷하지만 JavaScript를 사용하면 CSS만으로는 할 수 없는 몇 가지 강력한 기능을 사용할 수 있습니다. 여기에는 효과 시퀀스 기능과 재생 상태의 향상된 제어 기능이 포함됩니다.

element.animate() 초과

그러나 이번 업데이트로 Web Animations API는 더 이상 element.animate()를 사용하여 만든 애니메이션으로 제한되지 않습니다. CSS 애니메이션과 전환도 조작할 수 있습니다.

getAnimations()element.animate()를 사용하여 생성되었는지 또는 CSS 규칙 (CSS 애니메이션 또는 전환)을 사용하여 생성되었는지와 관계없이 요소의 모든 애니메이션을 반환하는 메서드입니다. 다음은 이러한 출력의 예시입니다.

먼저 전환의 키프레임을 "get"하여 전환의 출발점을 결정합니다. 그런 다음 두 가지 새로운 불투명도 애니메이션을 만들어 크로스 페이드 효과를 사용 설정합니다. 크로스페이드가 완료되면 사본을 삭제합니다.

프라미스로 애니메이션을 조정하는 방법

이제 Chromium 84에서는 프로미스와 함께 사용할 수 있는 두 가지 메서드(animation.readyanimation.finished)가 있습니다.

  • animation.ready를 사용하면 대기 중인 변경사항이 적용될 때까지 기다릴 수 있습니다 (즉, 재생 및 일시중지와 같은 재생 컨트롤 방법 간에 전환).
  • animation.finished는 애니메이션이 완료될 때 커스텀 JavaScript 코드를 실행하는 수단을 제공합니다.

예시를 계속 진행하여 animation.finished로 조정된 애니메이션 체인을 만듭니다. 여기서는 세로 변환 (scaleY) 다음에 가로 변환 (scaleX)이 적용되고 하위 요소의 불투명도가 변경됩니다.

열리는 모달 요소에 변환 및 불투명도를 적용합니다. Codepen에서 데모 보기
const transformAnimation = modal.animate(openModal, openModalSettings);
transformAnimation.finished.then(() => { text.animate(fadeIn, fadeInSettings)});

체인의 다음 애니메이션 세트를 실행하기 전에 animation.finished.then()를 사용하여 이러한 애니메이션을 연결했습니다. 이렇게 하면 애니메이션이 순서대로 표시되고 속도 및 이징과 같은 다양한 옵션을 설정하여 서로 다른 타겟 요소에 효과를 적용할 수도 있습니다.

CSS 내에서 이를 다시 만드는 것은 번거로울 수 있으며, 특히 고유하지만 순서가 지정된 애니메이션을 여러 요소에 적용하는 경우 더욱 그렇습니다. 시퀀스에서 애니메이션을 트리거하기 전에 @keyframe를 사용하고, 애니메이션을 배치할 올바른 타이밍 비율을 정렬하고, animation-delay를 사용해야 합니다.

예: 재생, 일시중지, 되감기

열 수 있는 것은 닫을 수 있어야 합니다. 다행히 Chromium 39부터 Web Animations API를 통해 애니메이션을 재생, 일시중지, 역재생할 수 있습니다.

이전에 표시된 애니메이션을 가져와 .reverse()를 사용하여 버튼을 다시 클릭할 때 원활하게 역방향으로 애니메이션을 적용할 수 있습니다. 이렇게 하면 모달에 더 원활하고 문맥에 맞는 상호작용을 만들 수 있습니다.

버튼 클릭 시 모달이 열리고 닫히는 예시입니다. Glitch에서 데모 보기

재생 대기 중인 애니메이션 2개 (openModal 및 인라인 불투명도 변환)를 만든 다음 애니메이션 중 하나를 일시중지하여 다른 애니메이션이 완료될 때까지 지연시킬 수 있습니다. 그런 다음 프로미스를 사용하여 재생하기 전에 각 작업이 완료될 때까지 기다릴 수 있습니다. 마지막으로 플래그가 설정되어 있는지 확인한 다음 각 애니메이션을 역전시킬 수 있습니다.

예: 부분 키프레임과의 동적 상호작용

마우스 클릭으로 애니메이션이 새 위치로 조정되는 재타겟팅 예시 Glitch에서 데모 보기
selector.animate([{transform: `translate(${x}px, ${y}px)`}],
    {duration: 1000, fill: 'forwards'});

이 예시에는 키프레임이 하나만 있고 지정된 시작 위치가 없습니다. 다음은 부분 키프레임을 사용하는 예입니다. 마우스 핸들러는 여기서 몇 가지 작업을 실행합니다. 새 종료 위치를 설정하고 새 애니메이션을 트리거합니다. 새 시작 위치는 현재 기본 위치에서 추론됩니다.

기존 전환이 실행 중일 때 새 전환을 트리거할 수 있습니다. 즉, 현재 전환이 중단되고 새 전환이 생성됩니다.

교체 가능한 애니메이션을 통한 성능 개선

'mousemove'와 같이 이벤트를 기반으로 애니메이션을 만들 때는 매번 새 애니메이션이 생성되므로 메모리가 빠르게 소모되고 성능이 저하될 수 있습니다. 이 문제를 해결하기 위해 Chromium 83에서 교체 가능한 애니메이션이 도입되어 자동 정리가 가능해졌습니다. 여기서 완료된 애니메이션은 교체 가능한 것으로 플래그가 지정되고 다른 완료된 애니메이션으로 교체되면 자동으로 삭제됩니다. 다음 예를 참고하세요.

마우스를 움직이면 혜성의 꼬리가 애니메이션으로 표시됩니다. Glitch에서 데모 보기
elem.addEventListener('mousemove', evt => {
  rectangle.animate(
    { transform: translate(${evt.clientX}px, ${evt.clientY}px) },
    { duration: 500, fill: 'forwards' }
  );
});

마우스가 움직일 때마다 브라우저는 혜성의 궤적에 있는 각 공의 위치를 다시 계산하고 이 새로운 지점으로 애니메이션을 만듭니다. 이제 브라우저는 다음과 같은 경우 이전 애니메이션을 삭제 (교체 사용 설정)하도록 인식합니다.

  1. 애니메이션이 완료됩니다.
  2. 컴포지션 순서에서 더 높은 위치에 있는 애니메이션이 하나 이상 있으며 이 애니메이션도 완료되었습니다.
  3. 새 애니메이션은 동일한 속성을 애니메이션 처리합니다.

anim.onremove를 사용하여 카운터를 트리거하고 삭제된 각 애니메이션의 카운터를 집계하여 대체되는 애니메이션의 수를 정확하게 확인할 수 있습니다.

애니메이션 제어를 한층 더 강화할 수 있는 몇 가지 추가 속성과 메서드가 있습니다.

  • animation.replaceState는 애니메이션이 활성 상태인지, 유지되는지 또는 삭제되었는지 추적하는 수단을 제공합니다.
  • animation.commitStyles()는 기본 스타일을 기반으로 요소의 스타일을 업데이트하고 요소의 모든 애니메이션을 복합 순서로 업데이트합니다.
  • animation.persist()는 애니메이션을 교체 불가능으로 표시합니다.

합성 모드로 더 부드러운 애니메이션

이제 Web Animations API를 사용하여 애니메이션의 합성 모드를 설정할 수 있습니다. 즉, 기본 모드인 'replace' 외에도 애니메이션을 더하거나 누적할 수 있습니다. 합성 모드를 사용하면 개발자가 고유한 애니메이션을 작성하고 효과가 결합되는 방식을 제어할 수 있습니다. 이제 'replace' (기본 모드), 'add', 'accumulate'의 세 가지 컴포지트 모드가 지원됩니다.

애니메이션을 합성하면 개발자가 짧고 고유한 효과를 작성하고 이러한 효과가 결합된 모습을 확인할 수 있습니다. 다음 예에서는 각 상자에 회전 및 크기 조정 키프레임을 적용하고 있으며, 유일하게 조정된 것은 옵션으로 추가된 합성 모드입니다.

합성 모드의 기본, 추가, 누적을 보여주는 데모입니다. Glitch에서 데모 보기

기본 'replace' 컴포지션 모드에서 최종 애니메이션은 변환 속성을 대체하고 rotate(360deg) scale(1.4)에서 종료됩니다. 'add'의 경우 합성은 회전을 추가하고 크기를 곱하여 최종 상태 rotate(720deg) scale(1.96)를 만듭니다. 'accumulate'는 변환을 결합하여 rotate(720deg) scale(1.8)를 생성합니다. 이러한 합성 모드의 세부정보는 웹 애니메이션 사양의 CompositeOperation 및 CompositeOperationOrAuto 열거형을 참고하세요.

다음 UI 요소 예시를 살펴보세요.

두 개의 합성 애니메이션이 적용된 탄력 있는 드롭다운 메뉴입니다. Glitch에서 데모 보기

여기서는 두 개의 top 애니메이션이 합성됩니다. 첫 번째는 드롭다운을 페이지 상단에서 슬라이드 인 효과로 메뉴 자체의 전체 높이만큼 이동하는 매크로 애니메이션이고, 두 번째는 드롭다운이 하단에 도달할 때 약간의 탄성을 적용하는 마이크로 애니메이션입니다. 'add' 복합 모드를 사용하면 더 원활한 전환이 가능합니다.

const dropDown = menu.animate(
    [
      { top: `${-menuHeight}px`, easing: 'ease-in' },
      { top: 0 }
    ], { duration: 300, fill: 'forwards' });

  dropDown.finished.then(() => {
    const bounce = menu.animate(
      [
        { top: '0px', easing: 'ease-in' },
        { top: '10px', easing: 'ease-out' },
        { ... }
      ], { duration: 300, composite: 'add' });
  });

Web Animations API의 향후 계획

이러한 기능은 모두 오늘날 브라우저의 애니메이션 기능에 추가된 흥미로운 기능이며, 앞으로 더 많은 기능이 추가될 예정입니다. 향후 출시될 사양을 확인하여 다음에 출시될 기능에 대해 자세히 알아보세요.