웹 애니메이션

W3C 워킹 드래프트,

이 문서에 대한 자세한 정보
이 버전:
https://www.w3.org/TR/2023/WD-web-animations-1-20230605/
최신 공개 버전:
https://www.w3.org/TR/web-animations-1/
편집자 초안:
https://drafts.csswg.org/web-animations-1/
이전 버전:
히스토리:
https://www.w3.org/standards/history/web-animations-1
테스트 스위트:
https://github.com/web-platform-tests/wpt/tree/master/web-animations
피드백:
CSSWG 이슈 저장소
명세 내 인라인
편집자:
(초대 전문가)
(Google)
(Google)
(Apple Inc)
이전 편집자:
(Google)
(Google)
(Google)
(Google)
명세 수정 제안:
GitHub 편집자
참여:
GitHub에서 텍스트 수정
"waapi" 채널에 참여: Animation at Work 슬랙
IRC: #webanimations W3C IRC에서

요약

이 명세서는 웹 페이지의 표현에 대한 변경 사항의 동기화와 타이밍을 위한 모델을 정의합니다. 또한 이 명세서는 이 모델과 상호작용할 수 있는 응용 프로그래밍 인터페이스를 정의하며, 추가적인 명세에서 이러한 기능을 선언적으로 노출하는 방법을 정의할 것으로 예상됩니다.

CSS는 구조화된 문서(HTML 및 XML 등)가 화면, 종이 등에서 렌더링되는 방식을 기술하는 언어입니다.

이 문서의 상태

이 섹션은 문서가 발행된 시점의 상태를 설명합니다. W3C의 최신 발행물 목록과 이 기술 보고서의 최신 개정판은 W3C 기술 보고서 인덱스 https://www.w3.org/TR/에서 확인할 수 있습니다.

이 문서는 CSS 워킹 그룹에서 워킹 드래프트권고 트랙을 사용하여 발행되었습니다. 워킹 드래프트로 발행되었다고 해서 W3C 및 회원사의 승인됨을 의미하지는 않습니다.

이 문서는 초안 문서이며, 언제든지 다른 문서로 업데이트, 대체 또는 폐기될 수 있습니다. 진행 중인 작업 외의 용도로 인용하는 것은 적절하지 않습니다.

피드백은 GitHub 이슈 등록(권장)으로 보내주시고, 제목에 사양 코드 “web-animations”를 포함해 아래와 같이 작성해 주세요: “[web-animations] …의견 요약…”. 모든 이슈와 의견은 아카이브에 보관됩니다. 또는 (아카이브됨) 공개 메일링 리스트 www-style@w3.org로도 보낼 수 있습니다.

이 문서는 2021년 11월 2일 W3C 프로세스 문서에 따라 관리됩니다.

이 문서는 W3C 특허 정책에 따라 운영되는 그룹에서 작성되었습니다. W3C는 해당 그룹 산출물과 관련하여 공개된 특허 공개 목록을 유지합니다. 해당 페이지에는 특허를 공개하는 방법에 대한 안내도 포함되어 있습니다. 어떤 개인이 해당 특허가 필수 청구항을 포함한다고 판단되는 경우, W3C 특허 정책 6절에 따라 정보를 공개해야 합니다.

1. 소개

이 섹션은 규범적이지 않습니다

웹 애니메이션은 웹 플랫폼에서 애니메이션과 동기화를 지원하기 위한 모델을 정의합니다. 다른 명세들이 이 모델을 기반으로 선언적 방식으로 기능을 노출할 수 있도록 설계되었습니다. 또한, 이 명세서는 스크립팅을 지원하는 사용자 에이전트가 구현할 수 있는 모델의 프로그래밍 인터페이스도 정의합니다.

1.1. 사용 사례

웹 애니메이션 모델은 CSS 트랜지션 [CSS-TRANSITIONS-1], CSS 애니메이션 [CSS-ANIMATIONS-1], 그리고 SVG [SVG11]을 표현하는 데 필요한 기능을 제공하기 위해 설계되었습니다. 따라서 웹 애니메이션 모델의 사용 사례는 이 세 가지 명세의 사용 사례의 합집합입니다.

프로그래밍 인터페이스의 사용 사례는 다음과 같습니다:

실행 중인 애니메이션 검사

웹 애플리케이션은 종종 특정 애니메이션 효과가 완료될 때까지 상태를 업데이트하지 않아야 할 필요가 있습니다. 이 명세서의 프로그래밍 인터페이스는 CSS 트랜지션, CSS 애니메이션, SVG 애니메이션, 또는 프로그래밍 인터페이스로 직접 생성된 애니메이션에 관계없이 현재 실행 중인 모든 애니메이션이 완료될 때까지 기다릴 수 있게 해줍니다.

// 모든 애니메이션이 끝난 후 요소를 제거
Promise.all(
  elem.getAnimations().map(animation => animation.finished)
).then(() => elem.remove());

또한, 애플리케이션은 대기하지 않고 애니메이션의 재생 상태를 조회할 수도 있습니다.

const isAnimating = elem.getAnimations().some(
  animation => animation.playState === 'running'
);
실행 중인 애니메이션 제어

때로는 애니메이션이 외부 입력에 반응할 수 있도록 재생 제어를 하는 것이 유용합니다. 예를 들어, 사용자 주의를 방해하지 않도록 모달 다이얼로그를 표시하기 전에 모든 애니메이션을 일시정지해야 할 수 있습니다.

// 문서 내의 모든 애니메이션 일시정지
for (const animation of document.getAnimations()) {
  animation.pause()
}
스크립트로 애니메이션 생성

ECMAScript를 이용해 requestAnimationFrame [HTML]으로 애니메이션을 수행하는 것도 가능하지만, 이러한 애니메이션은 CSS 캐스케이드에서의 표현 방식이나, 별도 스레드에서 애니메이션을 수행하는 등 성능 최적화 측면에서 선언적 애니메이션과 다르게 동작합니다. 웹 애니메이션 프로그래밍 인터페이스를 사용하면, 선언적 애니메이션과 동일한 동작 및 성능 특성을 가진 스크립트 기반 애니메이션을 생성할 수 있습니다.

// 빠르게 페이드 아웃
elem.animate({ transform: 'scale(0)', opacity: 0 }, 300);
애니메이션 디버깅

복잡한 애플리케이션에서는 요소가 현재 상태에 도달한 경로를 파악하기 어려울 수 있습니다. 웹 애니메이션 프로그래밍 인터페이스를 사용하여 실행 중인 애니메이션을 검사하고, "왜 이 요소의 투명도가 변하고 있을까?"와 같은 질문에 답할 수 있습니다.

// elem에서 opacity 애니메이션의 id를 출력
for (const animation of elem.getAnimations()) {
  if (
    animation.effect instanceof KeyframeEffect &&
    animation.effect
      .getKeyframes()
      .some(frame => frame.hasOwnProperty('opacity'))
  ) {
    console.log(animation.id);
  }
}

또한 애니메이션을 미세 조정하려면 재생 속도를 낮추고 반복해서 재생해야 할 때가 많습니다.

// transform 애니메이션을 느리게 하고 재생
const transformAnimations = elem.getAnimations().filter(
  animation =>
    animation.effect instanceof KeyframeEffect &&
    animation.effect.getKeyframes().some(
      frame => frame.hasOwnProperty('transform')
    )
);

for (const animation of transformAnimations) {
  animation.currentTime = 0;
  animation.updatePlaybackRate(0.5);
}
애니메이션 테스트

애니메이션을 사용하는 애플리케이션을 테스트할 때, 애니메이션이 완전히 끝날 때까지 기다리는 것은 비효율적일 수 있습니다. 대신, 애니메이션을 특정 시간으로 이동시키는 것이 바람직합니다.

// 애니메이션 중간 지점으로 이동한 뒤 opacity가 50%인지 확인
for (const animation of elem.getAnimations()) {
  const { delay, activeDuration } = animation.effect.getComputedTiming();
  animation.currentTime = delay + activeDuration / 2;
}
assert.strictEqual(getComputedStyle(elem).opacity, '0.5');

// 애니메이션이 끝난 후 로딩 화면이 숨겨지는지 확인
for (const animation of elem.getAnimations()) {
  animation.finish();
}
// 이벤트 핸들러가 실행될 수 있도록 한 프레임 대기
requestAnimationFrame(() => {
  assert.strictEqual(
    getComputedStyle(document.querySelector('#loading')).display, 'none');
});

1.2. 다른 명세와의 관계

CSS 트랜지션 [CSS-TRANSITIONS-1], CSS 애니메이션 [CSS-ANIMATIONS-1], 그리고 SVG [SVG11] 모두 웹 페이지에서 애니메이션 콘텐츠를 생성하는 메커니즘을 제공합니다. 이 세 가지 명세는 많은 유사한 기능을 제공하지만, 각각 다른 용어로 설명되어 있습니다. 이 명세서는 세 가지 명세의 공통 기능을 포괄하는 추상적 애니메이션 모델을 제안합니다. 이 모델은 기존 명세의 동작과 호환되어 관찰 가능한 변화 없이 이 모델로 정의될 수 있습니다.

SVG 1.1의 애니메이션 기능은 SMIL 애니메이션 [SMIL-ANIMATION]을 기반으로 정의되어 있습니다. 웹 애니메이션 모델로 SVG의 애니메이션 기능을 정의하면, SVG와 SMIL 애니메이션 간의 의존성을 제거할 수 있습니다.

애니메이션 프레임 콜백(일반적으로 "requestAnimationFrame"이라 불리는) [HTML]과 마찬가지로, 이 명세서의 프로그래밍 인터페이스 구성요소는 스크립트로 애니메이션을 생성할 수 있게 해줍니다. 그러나 이 명세서에서 정의된 인터페이스를 사용해 생성된 애니메이션은 한 번 생성되면 전적으로 사용자 에이전트에 의해 실행되므로, 마크업에서 정의된 애니메이션과 동일한 성능 특성을 갖습니다. 이 인터페이스를 사용하면 스크립트로 더 간단하고 효율적으로 애니메이션을 만들 수 있습니다.

프로그래밍 인터페이스에서 사용되는 시간 값은 애니메이션 프레임 콜백 [HTML]에서 사용되는 값과 일치하며, 실행 순서는 두 인터페이스를 동시에 사용해도 충돌이 없도록 정의되어 있습니다.

이 명세서의 프로그래밍 인터페이스 구성요소는 HTML [HTML]에서 정의된 인터페이스에 일부 기능을 추가합니다.

1.3. 이 명세서 개요

이 명세서는 먼저 애니메이션을 위한 추상 모델을 정의합니다. 그 다음, 추상 모델을 바탕으로 정의된 프로그래밍 인터페이스를 설명합니다. 프로그래밍 인터페이스는 추상 모델을 기반으로 정의되며, 스크립팅을 지원하는 사용자 에이전트에만 관련이 있습니다.

2. 명세 규약

이 명세서는 애니메이션애니메이션 효과 등과 같은 추상 개념과, 그에 속한 재생 속도반복 지속 시간과 같은 속성들을 먼저 설명합니다. 이러한 속성 외에도, 재생 속도 설정이나 시작 시간 설정과 같이, 이러한 속성을 업데이트하는 구체적인 절차가 자주 존재합니다.

이 명세서가 특정 절차에 연결하지 않은 경우, 예를 들어 "make animation’s start time unresolved"과 같이 사용자 에이전트가 속성을 업데이트해야 하는 텍스트는 관련 절차를 호출하지 않고 직접적으로 해당 속성을 업데이트하는 것을 의미합니다.

이 명세에 국한되지 않는 추가적인 문서 규약은 문서 규약에서 설명합니다.

3. 웹 애니메이션 모델 개요

이 섹션은 규범적이지 않습니다

웹 애니메이션 모델은 크게 두 가지 독립적인 부분, 즉 타이밍 모델애니메이션 모델로 구성됩니다. 각 부분의 역할은 다음과 같습니다:

타이밍 모델

어떤 순간의 시간을 받아서, 반복 진행도라 불리는 애니메이션의 한 반복 내 비례적 거리를 계산합니다. 또한 반복 인덱스도 기록하는데, 이는 일부 애니메이션이 반복될 때마다 달라질 수 있기 때문입니다.

애니메이션 모델

타이밍 모델에서 생성된 반복 진행도 값과 반복 인덱스를 받아서, 대상 속성에 적용할 일련의 값들로 변환합니다.

이 흐름은 그래픽적으로 다음과 같이 표현할 수 있습니다:

웹 애니메이션 모델의 작동 개요.
웹 애니메이션 모델의 작동 개요.
현재 시간이 타이밍 모델에 입력되어 반복 진행도 값과 반복 인덱스를 생성합니다.
이 파라미터들은 애니메이션 모델에 입력되어 적용할 값을 생성하는 데 사용됩니다.

예를 들어, 다음과 같은 애니메이션을 생각해봅시다:

첫 세 항목은 타이밍 모델에 적용됩니다. 6초 시점에는 애니메이션이 두 번째 반복의 중간 지점임을 계산하고 결과값 0.5를 생성합니다. 애니메이션 모델은 이 정보를 사용하여 너비를 계산합니다.

이 명세서는 타이밍 모델부터 시작해 애니메이션 모델로 이어집니다.

4. 타이밍 모델

이 섹션에서는 웹 애니메이션 타이밍 모델의 동작을 설명하고 정의합니다.

4.1. 타이밍 모델 개요

이 섹션은 규범적이지 않습니다

웹 애니메이션 타이밍 모델의 특징은 무상태계층적이라는 두 가지입니다.

4.1.1. 무상태

웹 애니메이션 타이밍 모델은 입력된 시간을 받아서 반복 진행도를 출력합니다. 출력은 오직 입력 시간만을 기준으로 이전 입력과는 무관하게 결정되므로, 이 모델은 무상태로 설명할 수 있습니다. 이는 모델에 다음과 같은 특성을 부여합니다:

프레임 속도 독립적

출력이 이전 입력에 독립적이기 때문에, 모델의 업데이트 속도는 진행도에 영향을 미치지 않습니다. 입력 시간이 실제 시간의 진행에 비례한다면, 애니메이션은 실행되는 기기의 성능과 관계없이 동일한 속도로 진행됩니다.

방향 무관

입력의 순서가 중요하지 않기 때문에, 모델은 방향성이 없습니다. 즉, 모델을 임의의 시점으로 업데이트해도 별도의 처리가 필요하지 않습니다.

상수 시간 탐색

각 입력이 이전 입력과 독립적이므로, 탐색(seek) 연산을 수행하는 데 필요한 처리는 먼 미래라도 최소한 상수 시간으로 가능할 수 있습니다.

타이밍 모델의 무상태 동작에는 몇 가지 예외가 있습니다.

첫째, 모델의 프로그래밍 인터페이스에서 정의된 여러 메서드는 애니메이션 일시정지 등 재생 제어를 제공합니다. 이러한 메서드는 호출된 시점의 시간에 따라 동작하므로 상태성을 가집니다. 이 메서드들은 편의를 위해 제공되는 것이며 핵심 타이밍 모델의 일부가 아니라 그 위에 계층적으로 추가된 것입니다.

마찬가지로, 애니메이션의 완료 동작은 애니메이션의 미디어(연관 효과)의 종료 시간을 동적으로 변경할 경우, 변경 시점에 따라 결과가 달라질 수 있습니다. 이 동작은 다소 아쉽지만 직관적이고 HTML과 일관되기 때문에 채택되었습니다. 따라서 모델은 타이밍 속성에 동적 변경이 없을 때에만 무상태로 설명될 수 있습니다.

마지막으로, 모델이 업데이트될 때마다 일시적 상태가 형성된다고 볼 수 있습니다. 이 일시적 상태는 프로그래밍 인터페이스에서 반환되는 값에 영향을 주지만, 이후 업데이트에는 영향을 미치지 않으므로 앞서 설명한 무상태 특성과 충돌하지 않습니다.

4.1.2. 계층적

타이밍 모델의 또 다른 특징은 시간이 상속된다는 점입니다. 시간은 타임라인에서 시작하여 여러 단계에 걸쳐 각 애니메이션 효과로 전달됩니다. 각 단계에서 시간은 뒤로 또는 앞으로 이동, 스케일 조정, 반전, 일시정지, 반복될 수 있습니다.

타이밍 노드의 계층 구조
타이밍 노드의 계층 구조. 트리의 각 노드는 부모 노드에서 시간을 상속받습니다.

이 명세서의 이 단계에서는 계층 구조가 얕습니다. 이후 단계에서 그룹 효과 개념이 도입되어 더 깊은 타이밍 계층 구조가 가능해집니다.

4.2. 시간 값

타이밍은 타이밍 노드 간의 시간 관계 계층 구조에 기반합니다. 부모 노드는 자식 노드에 시간 값의 형태로 타이밍 정보를 제공합니다.

시간 값은 일반적으로 어떤 시점부터 경과한 밀리초 수를 의미하는 실수입니다. 시간 값과 실제 벽시계 밀리초와의 연결은 시간 계층을 거치며 적용되는 다양한 변환에 의해 흐려질 수 있습니다.

앞으로 스크롤 위치나 UI 제스처를 기반으로 한 타임라인이 도입될 수 있으며, 이 경우 시간 값과 밀리초의 연결은 더욱 약해질 수 있습니다.

시간 값은 또한 미해결일 수도 있습니다. 예를 들어, 타이밍 노드가 시간 값을 생성할 수 없는 상태일 때 그렇습니다.

4.3. 타임라인

타임라인은 동기화 목적을 위한 시간 값의 소스를 제공합니다.

어느 한 순간에, 타임라인은 단일 현재 시간 값을 가지며, 이를 단순히 타임라인의 현재 시간이라고 합니다.

타임라인은 항상 의미 있는 시간 값을 반환할 수 있는 것은 아니며, 때로는 미해결 시간 값만 반환할 수 있습니다. 예를 들어, 아직 발생하지 않은 순간(예: 문서의 load 이벤트 발생 등)을 기준으로 정의될 수 있습니다. 타임라인비활성 타임라인으로 간주되며, 시간 값미해결일 때입니다.

타임라인은, 그 현재 시간이 항상 이전에 보고된 현재 시간과 같거나 클 때 단조 증가 타임라인입니다.

특정 종류의 타임라인타임라인 시간을 원점 기준 시간으로 변환하는 절차를 시간 값 time에 대해 정의할 수 있으며, 벽시계 기반 타임라인에서 생성된 시간 값을 비교할 수 있도록 합니다.

타임라인문서에 연결된 타임라인일 수 있습니다.

애니메이션을 업데이트하고 이벤트를 전송할 때, Document doc에서 timestamp now에 대해 아래 단계들을 실행합니다:

  1. 문서에 연결된 모든 타임라인의 현재 시간now를 timestamp로 전달하여 업데이트합니다.

    타이밍 모델의 계층적 특성 때문에, 타임라인의 현재 시간을 업데이트하면 다음도 포함됩니다:

  2. 교체된 애니메이션 제거doc에 대해 실행합니다.

  3. 마이크로태스크 체크포인트 실행를 합니다.

    참고: 이는 이전 단계에서 타임라인 업데이트의 일부로 Promise 객체를 해결하거나 거부한 결과로 큐에 추가된 마이크로태스크가 애니메이션 이벤트 디스패치 이전에 콜백을 실행할 수 있도록 하는 것입니다.

  4. events to dispatchdoc대기 중인 애니메이션 이벤트 큐의 복사본으로 설정합니다.

  5. doc대기 중인 애니메이션 이벤트 큐를 비웁니다.

  6. events to dispatch 내의 애니메이션 이벤트를 다음 방식으로 안정적으로 정렬합니다:

    1. 이벤트의 예정 이벤트 시간 기준으로, 먼저 발생해야 하는 이벤트가 뒤에 발생하는 이벤트보다 앞에 오도록 정렬합니다. 그리고 예정 이벤트 시간이 미해결인 이벤트가 해결됨인 이벤트보다 앞에 오도록 정렬합니다.

    2. 예정 이벤트 시간이 동일한 이벤트 내에서는, 합성 순서로 정렬합니다.

    참고: 이벤트 정렬 목적은, 기기별 프레임률이 달라도 이벤트가 일관된 순서로 디스패치되도록 최대한 보장하기 위함입니다.

    참고: 정렬이 안정적이어야 하는 이유는, 동일한 예정 이벤트 시간으로 이벤트가 큐에 추가될 수 있기 때문입니다. 예를 들어, 0초짜리 CSS 애니메이션은 animationstartanimationend 이벤트를 모두 디스패치할 수 있으며, 이 두 이벤트의 순서는 유지되어야 합니다.

  7. 이벤트 디스패치events to dispatch의 각 이벤트에 대해 해당 타겟에서, 앞 단계에서 정해진 순서대로 실행합니다.

이 절차가 호출될 때마다 새로운 애니메이션 프레임이 생성된다고 설명하는 것이 편리할 때가 많습니다. 애니메이션이나 애니메이션 효과의 타이밍 속성 변경, 객체 추가 및 제거 등은 타이밍 또는 애니메이션 모델의 출력을 변경할 수 있지만, 이러한 작업 자체가 새로운 애니메이션 프레임을 생성하는 것은 아니며, 단지 현재 애니메이션 프레임을 업데이트할 뿐입니다.

4.3.1. 문서 타임라인

문서 타임라인타임라인의 한 종류로, 문서에 연결되어 있으며, 현재 시간애니메이션을 업데이트하고 이벤트를 전송 절차가 실행될 때마다 제공되는 now timestamp로부터 고정 오프셋을 계산하여 결정됩니다. 이 고정 오프셋을 문서 타임라인의 원점 시간이라고 합니다.

"origin time"보다 더 나은 용어가 필요합니다— "time origin"과 너무 유사합니다. [Issue #2079]

연결된 문서의 시간 원점이 설정되기 전에는, 문서 타임라인비활성 상태입니다.

문서 타임라인활성이 된 후에는 단조 증가합니다.

문서 타임라인Document 에 연결되어 있고, 해당 문서가 활성 문서가 아니라면 비활성으로 간주됩니다.

타임라인 시간 timeline time을 원점 기준 시간으로 변환하려면, 문서 타임라인 timeline에서 timeline timetimeline원점 시간을 합산하여 반환합니다. timeline이 비활성 상태라면, 미해결 시간 값을 반환합니다.

4.3.2. 문서 기본 타임라인

Document문서 타임라인을 가지며, 이를 기본 문서 타임라인이라고 합니다. 기본 문서 타임라인은 각 문서에 대해 고유하며, document.open() [HTML] 호출을 포함하여 문서의 생명주기 동안 유지됩니다.

기본 문서 타임라인원점 시간은 0입니다.

이 섹션은 규범적이지 않습니다

문서 타임라인에 제공되는 now timestamp 값에는 스케일링이 적용되지 않으므로, 해당 타임라인이 생성하는 시간 값은 벽시계 밀리초에 비례합니다.

또한, 기본 문서 타임라인시간 값시간 원점으로부터 오프셋이 0이므로, document.timeline.currentTimePerformance.now() [HR-TIME]와 대략적으로 일치합니다. 단, document.timeline.currentTime애니메이션을 업데이트하고 이벤트를 전송 절차를 호출하는 사이에는 변경되지 않습니다.

4.4. 애니메이션

이 섹션은 규범적이지 않습니다

타임라인의 자식들은 애니메이션이라고 불립니다. 애니메이션은 애니메이션 효과를 갖는데, 이는 특정 시간 동작의 정적 기술이며, 이를 타임라인에 연결하여 실행되도록 합니다. 애니메이션은 애니메이션 효과타임라인 간의 연결을 일시정지, 탐색, 속도 제어 등 런타임 제어도 할 수 있게 해줍니다. 애니메이션과 애니메이션 효과의 관계는 DVD 플레이어와 DVD의 관계와 유사합니다.

애니메이션은 하나의 애니메이션 효과(이를 연관 효과라 함)를 타임라인에 연결하고, 재생 제어를 제공합니다. 이 두 연결은 모두 선택적이며 구성 가능하므로, 애니메이션은 특정 시점에 연관 효과타임라인이 없을 수도 있습니다.

애니메이션타이밍용 문서Document 이며, 해당 타임라인문서에 연결되어 있을 때 해당됩니다. 애니메이션이 타임라인에 연결되어 있지 않거나, 타임라인이 문서와 연결되어 있지 않으면, 타이밍용 문서가 없습니다.

애니메이션시작 시간타임라인시간 값이며, 연관 효과가 재생 시작으로 예약될 때의 값입니다. 애니메이션의 시작 시간은 처음에는 미해결 상태입니다.

애니메이션은 또한 홀드 시간 시간 값도 유지하며, 일시정지 등 상황에서 애니메이션의 출력 시간 값(현재 시간이라 함)을 고정할 때 사용됩니다. 홀드 시간 역시 처음에는 미해결입니다.

상충하는 애니메이션들의 상대적 순서를 정하기 위해, 애니메이션들은 생성된 순서대로 글로벌 애니메이션 리스트에 추가됩니다. 하지만 특정 애니메이션 클래스에서는 다른 정렬 방식도 제공할 수 있습니다 (§ 5.4.1 애니메이션 클래스 참고).

4.4.1. 애니메이션의 타임라인 설정

애니메이션의 타임라인 설정 절차(애니메이션 animationnew timeline으로, null일 수 있음)는 다음과 같습니다:

  1. old timelineanimation의 현재 타임라인(있다면)으로 설정합니다.

  2. new timelineold timeline과 동일 객체라면, 절차를 중단합니다.

  3. animation타임라인new timeline으로 설정합니다.

  4. animation시작 시간해결됨이라면, animation홀드 시간미해결로 설정합니다.

    참고: 이 단계는 animation완료 상태가 "고착"되지 않고, 갱신된 현재 시간 기준으로 재평가되도록 보장합니다.

  5. animation에 대해 애니메이션 완료 상태 업데이트 절차를 실행합니다. did seek 플래그는 false, synchronously notify 플래그도 false로 설정합니다.

4.4.2. 애니메이션의 연관 효과 설정

애니메이션의 연관 효과 설정 절차(애니메이션 animationnew effect로, null일 수 있음)는 다음과 같습니다:

  1. old effectanimation의 현재 연관 효과(있다면)로 설정합니다.

  2. new effectold effect와 동일 객체라면, 절차를 중단합니다.

  3. animation대기 중인 일시정지 작업이 있다면, animation준비됨 상태가 되자마자 해당 작업을 실행하도록 다시 예약합니다.

  4. animation대기 중인 재생 작업이 있다면, animation준비됨 상태가 되고 new effect로 재생할 수 있을 때 실행하도록 다시 예약합니다.

  5. new effectnull이 아니고, new effect가 다른 애니메이션(previous animation)의 연관 효과라면, previous animation에 대해 본 절차(애니메이션의 연관 효과 설정)를 null을 new effect로 넘겨 실행합니다.

  6. animation연관 효과new effect로 설정합니다.

  7. animation에 대해 애니메이션 완료 상태 업데이트 절차를 실행합니다. did seek 플래그는 false, synchronously notify 플래그도 false로 설정합니다.

4.4.3. 애니메이션의 현재 시간

애니메이션연관 효과시간 값을 제공하며, 이를 현재 시간이라고 합니다.

현재 시간은 아래 조건들 중 처음으로 일치하는 조건에 따라 계산됩니다:

애니메이션의 홀드 시간해결됨이라면,

현재 시간은 애니메이션의 홀드 시간입니다.

다음 중 하나라도 참인 경우:

  1. 애니메이션에 연관된 타임라인이 없거나,

  2. 연관된 타임라인비활성이거나,

  3. 애니메이션의 시작 시간미해결일 때.

현재 시간미해결 시간 값입니다.

그 밖의 경우,
현재 시간 = (timeline time - 시작 시간) × 재생 속도

timeline time은 연관된 타임라인의 현재 시간 값입니다. 재생 속도 값은 § 4.4.15 속도 제어에서 정의됩니다.

4.4.4. 애니메이션의 현재 시간 설정

애니메이션의 현재 시간은 새로운 값으로 설정되어 탐색할 수 있습니다. 현재 시간을 설정하는 절차는 두 부분으로 정의됩니다.

현재 시간 조용히 설정 절차(애니메이션 animationseek time으로)는 다음과 같습니다:

  1. seek time미해결 시간 값이라면, 아래 단계를 실행합니다.

    1. 현재 시간해결됨이라면, TypeErrorthrow합니다.

    2. 이 단계들을 중단합니다.

  2. animation홀드 시간 또는 시작 시간을 아래와 같이 업데이트합니다:

    다음 조건 중 하나라도 참이면:

    animation홀드 시간seek time으로 설정합니다.

    그 밖의 경우,

    animation시작 시간을 아래 식의 결과로 설정합니다: timeline time - (seek time / 재생 속도) 여기서 timeline timeanimation과 연관된 타임라인의 현재 시간 값입니다.

  3. animation에 연관된 타임라인이 없거나, 해당 타임라인비활성이면, animation시작 시간미해결로 설정합니다.

    이 불변식은 활성 타임라인이 없는 경우 시작 시간 또는 애니메이션의 현재 시간만 설정할 수 있음을 보장합니다.

  4. animation이전 현재 시간미해결로 설정합니다.

현재 시간 설정 절차(애니메이션 animationseek time으로)는 다음과 같습니다:

  1. animation현재 시간 조용히 설정 단계를 seek time으로 실행합니다.

  2. animation대기 중인 일시정지 작업이 있다면, 동기적으로 일시정지 작업을 완료합니다. 아래 단계를 실행하세요:

    1. animation홀드 시간seek time으로 설정합니다.

    2. 대기 중인 재생 속도 적용animation에 실행합니다.

    3. animation시작 시간미해결로 설정합니다.

    4. 대기 중인 일시정지 작업을 취소합니다.

    5. resolve animation현재 ready promiseanimation으로 해결합니다.

  3. animation에 대해 애니메이션 완료 상태 업데이트 절차를 실행합니다. did seek 플래그는 true, synchronously notify 플래그는 false로 설정합니다.

4.4.5. 애니메이션의 시작 시간 설정

시작 시간 설정 절차는 animation, animationnew start time으로 설정할 때 다음과 같습니다:

  1. timeline timeanimation이 연결된 타임라인의 현재 시간 값으로 설정합니다. animation에 연결된 타임라인이 없거나, 연결된 타임라인이 비활성 상태라면, timeline time미해결로 설정합니다.

  2. timeline time미해결이고 new start time해결됨이라면, animation홀드 시간미해결로 설정합니다.

    이 단계는 활성 타임라인이 없을 때 시작 시간 또는 애니메이션의 현재 시간만 설정할 수 있음을 보장합니다.

  3. previous current timeanimation현재 시간으로 설정합니다.

    참고: 이는 앞 단계의 변경이 적용된 이후의 현재 시간으로, 이로 인해 현재 시간이 미해결이 될 수 있습니다.

  4. 대기 중인 재생 속도 적용animation에 실행합니다.

  5. animation시작 시간new start time으로 설정합니다.

  6. 다음 중 첫 번째로 일치하는 조건에 따라 animation홀드 시간을 업데이트합니다:

    new start time해결됨인 경우,

    animation재생 속도가 0이 아니라면, animation홀드 시간미해결로 설정합니다.

    그밖의 경우(new start time미해결인 경우),

    animation홀드 시간previous current time으로 설정합니다. previous current time미해결이어도 설정합니다.

  7. animation대기 중인 재생 작업 또는 대기 중인 일시정지 작업이 있다면, 해당 작업을 취소하고 resolve를 통해 animation현재 ready promiseanimation으로 해결합니다.

  8. animation에 대해 애니메이션 완료 상태 업데이트 절차를 실행합니다. did seek 플래그는 true, synchronously notify 플래그는 false로 설정합니다.

4.4.6. 연관 효과 대기

이 섹션은 규범적이지 않습니다

애니메이션이 수행하는 일부 작업은 즉시 발생하지 않을 수 있습니다. 예를 들어, 일부 사용자 에이전트는 애니메이션의 재생을 별도의 프로세스나 특수 그래픽 하드웨어에 위임할 수 있으며, 이 과정에서 준비 시간이 발생할 수 있습니다.

이런 애니메이션이 트리거된 순간부터 타이밍이 시작된다면, 애니메이션의 첫 번째와 두 번째 프레임 사이에 준비 시간만큼의 큰 점프가 생길 수 있습니다.

이 문제를 방지하기 위해, 웹 애니메이션은 일반적으로 애니메이션의 첫 프레임이 완료되는 순간부터 타이밍을 시작합니다. 이는 애니메이션시작 시간미해결로 표시되다가, 애니메이션이 준비됨이 되면 해결됨으로 바뀌는 방식으로 나타납니다. 콘텐츠는 시작 시간해결됨 시간 값으로 설정해 이 동작을 비활성화할 수 있습니다.

애니메이션은 아래 두 조건이 모두 충족되는 최초의 순간에 준비됨 상태가 됩니다:

4.4.7. 현재 ready promise

애니메이션현재 ready promise를 가집니다. 현재 ready promise는 초기에는 Promise 객체로, 애니메이션 자체를 값으로 하여 새로 해결된 Promise 생성 절차를 사용해 생성되며, 애니메이션의 관련 Realm에서 생성됩니다.

이 객체는 애니메이션이 대기 중인 재생 작업 또는 대기 중인 일시정지 작업을 새로 큐에 추가할 때마다, 또는 애니메이션이 취소될 때마다(§ 4.4.14 애니메이션 취소 참고) 새로운 Promise 객체로 대체됩니다.

동일 객체가 재생/일시정지 모두에 사용되므로, 개발자는 Promise 객체가 해결될 때 애니메이션의 상태를 확인하는 것을 권장합니다.

예를 들어, 아래 코드에서는 현재 ready promise가 해결될 때 애니메이션의 상태는 running입니다. 이는 play 작업이 대기 중인 재생 작업이 아직 큐에 있는 동안 발생하기 때문에 현재 ready promise가 재사용되기 때문입니다.

animation.pause();
animation.ready.then(function() {
  // running이 출력됨
  alert(animation.playState);
});
animation.play();

4.4.8. 애니메이션 재생

애니메이션 재생 절차는 animation에 대해 auto-rewind 플래그가 주어졌을 때 다음과 같습니다:

  1. aborted pause를, animation대기 중 일시정지 작업이 있으면 true, 아니면 false인 불리언 플래그로 설정합니다.

  2. has pending ready promise를 초기값 false인 불리언 플래그로 설정합니다.

  3. seek time시간 값으로, 초기값은 미해결로 설정합니다.

  4. auto-rewind 플래그가 true라면, 아래 조건 중 첫 번째에 해당하는 경우의 단계를 실행합니다:

    animation실효 재생 속도가 ≥ 0이고, animation현재 시간이 아래 중 하나일 때:

    seek time을 0으로 설정합니다.

    animation실효 재생 속도가 < 0이고, animation현재 시간이 아래 중 하나일 때:

    연관 효과 종료가 양의 무한대인 경우,

    throw "InvalidStateError" DOMException 예외를 발생시키고, 절차를 중단합니다.

    그 밖의 경우,

    seek timeanimation연관 효과 종료로 설정합니다.

  5. 다음 세 조건이 모두 참이면:

    seek time을 0으로 설정합니다.

    참고: 위 단계는 auto-rewind 플래그 설정과 관계없이 이 절차가 유휴 애니메이션을 재생하도록 보장합니다.

  6. has finite timeline을, animation타임라인에 연결되어 있고, 그 타임라인이 단조 증가가 아니면 true로 설정합니다.

  7. seek time해결됨이라면,

    has finite timeline이 true인 경우,
    1. animation시작 시간seek time으로 설정합니다.

    2. animation홀드 시간미해결로 설정합니다.

    3. 대기 중 재생 속도 적용animation에 실행합니다.

    그 밖의 경우,

    animation홀드 시간seek time으로 설정합니다.

  8. animation홀드 시간해결됨이면, 시작 시간미해결로 설정합니다.

  9. animation대기 중 재생 작업 또는 대기 중 일시정지 작업이 있다면,

    1. 해당 작업을 취소합니다.

    2. has pending ready promise를 true로 설정합니다.

  10. 아래 네 조건이 모두 참이면:

    절차를 중단합니다.

  11. has pending ready promise가 false라면, animation현재 ready promise새 promise로, 관련 Realm에서 설정합니다.

  12. animation준비됨 상태가 되자마자 실행될 작업을 예약합니다. 해당 작업은 다음 단계를 실행합니다:

    1. animation시작 시간 또는 홀드 시간 중 적어도 하나가 해결됨임을 assert 합니다.

    2. ready timeanimation준비됨 상태가 된 순간의 타임라인시간 값으로 설정합니다.

    3. 아래에서 첫 번째로 일치하는 조건의 단계를 실행합니다:

      animation홀드 시간해결됨인 경우,
      1. 대기 중 재생 속도 적용animation에 실행합니다.

      2. new start timeready time - 홀드 시간 / 재생 속도로 계산합니다. 재생 속도가 0이면 new start timeready time으로 설정합니다.

      3. animation시작 시간new start time으로 설정합니다.

      4. animation재생 속도가 0이 아니면, animation홀드 시간미해결로 설정합니다.

      animation시작 시간 이 해결됨이고 animation대기 중 재생 속도가 있는 경우,
      1. current time to match(ready time - 시작 시간) × 재생 속도로 계산합니다.

      2. 대기 중 재생 속도 적용animation에 실행합니다.

      3. animation재생 속도가 0이면, animation홀드 시간current time to match로 설정합니다.

      4. new start timeready time - current time to match / 재생 속도로 계산합니다. 재생 속도가 0이면 new start timeready time으로 설정합니다.

      5. animation시작 시간new start time으로 설정합니다.

    4. resolve animation현재 ready promiseanimation으로 해결합니다.

    5. animation에 대해 애니메이션 완료 상태 업데이트 절차를 실행합니다. did seek 플래그는 false, synchronously notify 플래그도 false로 설정합니다.

      위 두 단계의 순서가 중요합니다. 즉, 길이가 0인 연관 효과를 가진 애니메이션은 현재 ready promise현재 finished promise보다 먼저 resolve됩니다.

    위 작업이 예약되어 아직 실행되지 않은 동안 animation대기 중 재생 작업을 갖는 것으로 간주합니다. 하지만 작업이 실행 중일 때는 animation대기 중 재생 작업이 없습니다.

    만약 사용자 에이전트가 animation이 즉시 준비됨이라고 판단하면, 위 작업을 마이크로태스크로 예약해 다음 마이크로태스크 체크포인트에서 실행할 수 있습니다. 하지만 동기적으로 작업을 실행하면 안 됩니다.

    위 요구사항에 따라 대기 중 재생 작업을 비동기로 실행해야 하므로 아래 코드가 구현 간에 일관되게 동작합니다:

    animation.play();
    animation.ready.then(
      () => { console.log('재생 시작'); },
      () => { console.log('재생 취소됨'); }
    );
    // 어떤 조건으로 인해 재생이 취소되어야 한다면...
    animation.cancel();
    // "재생 취소됨"이 콘솔에 출력됩니다.
    

    위 코드에서 대기 중 재생 작업이 동기적으로 실행된다면 현재 ready promise가 reject되지 않을 수 있습니다.

  13. animation에 대해 애니메이션 완료 상태 업데이트 절차를 실행합니다. did seek 플래그는 false, synchronously notify 플래그도 false로 설정합니다.

4.4.9. 애니메이션 일시정지

애니메이션미해결 시작 시간이 있을 때마다, 현재 시간이 일시적으로 중단됩니다.

애니메이션 재생과 마찬가지로, 일시정지는 즉시 발생하지 않을 수 있습니다(§ 4.4.6 연관 효과 대기 참고). 예를 들어, 애니메이션이 별도의 프로세스에서 수행되는 경우, 애니메이션 프로세스가 그린 상태를 반영하도록 현재 시간을 동기화해야 할 수도 있습니다.

애니메이션 일시정지 절차(animation)는 다음과 같습니다:

  1. animation대기 중 일시정지 작업이 있으면 이 단계를 중단합니다.

  2. animation재생 상태일시정지됨이면, 이 단계를 중단합니다.

  3. seek time시간 값으로, 초기값은 미해결로 설정합니다.

  4. has finite timeline을, animation에 연결된 타임라인단조 증가가 아니면 true로 설정합니다.

  5. animation현재 시간미해결이면, 아래에서 첫 번째로 일치하는 조건의 단계를 수행합니다:

    animation재생 속도가 ≥ 0일 때,

    seek time을 0으로 설정합니다.

    그 밖의 경우,
    연관 효과 종료가 양의 무한대인 경우,

    throw "InvalidStateError" DOMException 예외를 발생시키고 이 단계를 중단합니다.

    그 밖의 경우,

    seek timeanimation연관 효과 종료로 설정합니다.

  6. seek time해결됨이면,

    has finite timeline이 true라면,

    animation시작 시간seek time으로 설정합니다.

    그 밖의 경우,

    animation홀드 시간seek time으로 설정합니다.

  7. has pending ready promise를 초기값 false인 불리언 플래그로 설정합니다.

  8. animation대기 중 재생 작업이 있으면, 해당 작업을 취소하고 has pending ready promise를 true로 설정합니다.

  9. has pending ready promise가 false라면, animation현재 ready promise새 promise관련 Realm에 설정합니다.

  10. 아래 두 조건이 모두 충족되는 최초의 순간에 작업을 예약합니다:

    • 사용자 에이전트가 animation연관 효과 재생을 일시정지시키기 위한 모든 처리를 완료했을 때

    • 애니메이션이 타임라인에 연결되어 있고, 해당 타임라인이 비활성이 아닌 경우

    해당 작업은 아래 단계를 수행합니다:

    1. ready timeanimation이 연결된 타임라인의, 사용자 에이전트가 animation연관 효과 일시정지 처리를 완료한 순간의 시간 값으로 설정합니다.

    2. animation시작 시간해결됨이고 홀드 시간이 해결되지 않았다면, animation홀드 시간(ready time - 시작 시간) × 재생 속도 결과로 설정합니다.

      참고: 홀드 시간은 애니메이션이 완료됨 상태이거나, 대기 중 재생 작업이 있을 때 이미 설정되어 있을 수 있습니다. 두 경우 모두 홀드 시간을 일시정지 상태로 진입할 때 유지해야 합니다.

    3. 대기 중 재생 속도 적용animation에 실행합니다.

    4. animation시작 시간을 미해결로 만듭니다.

    5. resolve animation현재 ready promiseanimation으로 해결합니다.

    6. animation에 대해 애니메이션 완료 상태 업데이트 절차를 실행합니다. did seek 플래그는 false, synchronously notify 플래그도 false로 설정합니다.

    위 작업이 예약되어 아직 실행되지 않은 동안 animation대기 중 일시정지 작업을 갖는 것으로 간주합니다. 하지만 작업이 실행 중일 때는 animation대기 중 일시정지 작업이 없습니다.

    대기 중 재생 작업과 마찬가지로, 사용자 에이전트는 대기 중 일시정지 작업을 반드시 비동기로 실행해야 하며, 이는 다음 마이크로태스크 체크포인트에서 실행될 수 있습니다.

  11. animation에 대해 애니메이션 완료 상태 업데이트 절차를 실행합니다. did seek 플래그는 false, synchronously notify 플래그도 false로 설정합니다.

4.4.10. 끝에 도달

이 섹션은 규범적이지 않습니다

DVD 플레이어나 카세트 플레이어는 일반적으로 미디어의 끝에 도달할 때까지 재생을 계속하다가 멈춥니다. 이러한 플레이어가 역재생이 가능하다면, 미디어의 시작점에 도달하면 재생이 멈춥니다. 이 동작을 모방하고, HTML의 미디어 요소 [HTML]와 일관성을 제공하기 위해, 웹 애니메이션의 애니메이션들은 연관 효과종료 시간을 넘어서 앞으로 재생되지 않고, 0초 이전으로 역재생되지 않습니다.

애니메이션이 재생 범위의 자연스러운 경계에 도달하면 완료됨 상태가 되었다고 합니다.

현재 시간을 제한하는 효과는 아래 그림과 같습니다.

The effect of limiting the current time of an animation.
시작 시간이 1초이고, 연관 효과 길이가 3초이며 양수 재생 속도를 갖는 애니메이션현재 시간 제한 효과. 애니메이션의 현재 시간이 연관 효과의 끝에 도달하면 3초로 고정됩니다.

하지만 애니메이션현재 시간을 연관 효과의 끝을 넘는 시간으로 탐색하는 것도 가능합니다. 이 경우 현재 시간은 진행되지 않고, 애니메이션은 탐색된 시간에 일시정지된 것처럼 동작합니다.

예를 들어, 연관 효과가 없는 애니메이션의 현재 시간을 5초로 탐색할 수 있습니다. 이후 연관 효과가 5초보다 늦게 종료되는 종료 시간과 함께 연결된다면, 재생은 5초 시점부터 시작됩니다.

위와 유사하게, 애니메이션의 연관 효과 길이가 변경될 때도 비슷한 동작이 발생할 수 있습니다.

또한 재생 속도가 음수인 경우, 현재 시간은 0초 이전으로 진행되지 않습니다.

4.4.11. 현재 finished promise

각 애니메이션은 현재 finished promise를 가집니다. 현재 finished promise는 초기에는 pending 상태의 Promise 객체입니다.

이 객체는 애니메이션이 완료됨 재생 상태를 벗어날 때마다 새로운 promise로 대체됩니다.

4.4.12. 완료 상태 업데이트

재생 속도가 양수인 애니메이션의 경우, 현재 시간연관 효과 종료까지 계속 증가합니다.

애니메이션의 연관 효과 종료는 해당 애니메이션의 연관 효과종료 시간과 같습니다. 애니메이션에 연관 효과가 없으면, 연관 효과 종료는 0입니다.

재생 속도가 음수인 애니메이션의 경우, 현재 시간은 0까지 계속 감소합니다.

실행 중인 애니메이션이 이 경계에 도달하거나 넘어서고, 시작 시간해결됨이면 완료됨 상태라고 합니다.

이 경계의 도달 여부는 애니메이션 객체가 수정될 때마다 아래 정의된 애니메이션 완료 상태 업데이트 절차를 통해 확인됩니다. 이 절차는 애니메이션 및 이벤트 업데이트 절차의 일부로도 실행됩니다. 두 경우 모두 아래 정의된 did seek 플래그는 false로 설정됩니다.

각 애니메이션에 대해 사용자 에이전트는 이전 현재 시간 시간 값을 관리하며, 이 값은 원래 미해결입니다.

일반 재생 중에는 애니메이션현재 시간이 위에서 설명한 경계로 제한되지만, 현재 시간 설정 절차를 사용하면 이 경계를 벗어난 시간으로 탐색할 수도 있습니다.

애니메이션 완료 상태 업데이트 절차(animation, did seek 플래그(현재 시간 설정 후 업데이트 여부), synchronously notify 플래그(즉시 이벤트 큐 및 promise 처리 기대 여부))는 다음과 같습니다:

  1. unconstrained current time을 계산합니다. did seek이 false이면 홀드 시간 대신 미해결 시간 값을 사용해 현재 시간을 계산합니다. did seek이 true이면 unconstrained current time현재 시간과 같습니다.

    참고: 이는 타임라인 방향 변경을 허용하기 위함입니다. 이 정의가 없다면, 한 번 완료된 애니메이션은 타임라인이 반대 방향으로 진행되어도 계속 완료 상태로 남습니다.

  2. 아래 세 조건이 모두 참이면,

    아래에서 animation에 대해 첫 번째로 일치하는 조건에 따라 홀드 시간을 업데이트합니다:

    재생 속도 > 0이고 unconstrained current time연관 효과 종료 이상일 때,

    did seek이 true라면 홀드 시간unconstrained current time 값으로 설정합니다.

    did seek이 false라면 홀드 시간이전 현재 시간연관 효과 종료 중 큰 값으로 설정합니다. 이전 현재 시간미해결이면, 홀드 시간연관 효과 종료로 설정합니다.

    재생 속도 < 0이고 unconstrained current time이 0 이하일 때,

    did seek이 true라면 홀드 시간unconstrained current time 값으로 설정합니다.

    did seek이 false라면 홀드 시간이전 현재 시간과 0 중 작은 값으로 설정합니다. 이전 현재 시간미해결이면, 홀드 시간을 0으로 설정합니다.

    재생 속도 ≠ 0이고, animation활성 타임라인에 연결되어 있을 때,

    아래 단계를 수행합니다:

    1. did seek이 true이고 홀드 시간해결됨이면, animation시작 시간timeline time - (홀드 시간 / 재생 속도) 결과로 설정합니다. 여기서 timeline timeanimation과 연결된 타임라인의 현재 시간 값입니다.

    2. 홀드 시간미해결로 설정합니다.

  3. animation이전 현재 시간현재 시간 계산 결과로 설정합니다.

  4. current finished state를, animation재생 상태완료됨이면 true, 아니면 false로 설정합니다.

  5. current finished state가 true이고 현재 finished promise가 아직 resolve되지 않았다면, 아래 단계를 수행합니다:

    1. finish notification steps 절차는 다음과 같습니다:

      1. animation재생 상태완료됨과 다르면, 이 단계를 중단합니다.

      2. resolve animation현재 finished promise 객체를 animation으로 resolve합니다.

      3. Create AnimationPlaybackEvent 객체 finishEvent를 생성합니다.

      4. finishEventtype 속성을 finish로 설정합니다.

      5. finishEventcurrentTime 속성을 animation현재 시간으로 설정합니다.

      6. finishEventtimelineTime 속성을 animation이 연결된 타임라인의 현재 시간으로 설정합니다. 타임라인이 없다면, 또는 타임라인이 비활성이면 timelineTimenull로 설정합니다.

      7. animation타이밍용 문서가 있다면, finishEvent를 해당 타이밍용 문서대기 중 애니메이션 이벤트 큐에 타겟 animation과 함께 추가합니다. 예정 이벤트 시간변환animation연관 효과 종료를 원점 기준 시간으로 사용합니다.

        그 외의 경우, 작업을 큐에 추가하여 finishEventanimation에서 디스패치합니다. 해당 작업의 소스는 DOM 조작 작업 소스입니다.

    2. synchronously notify가 true이면, 이 animationfinish notification steps 실행을 위한 모든 큐에 있는 마이크로태스크를 취소하고, finish notification steps를 즉시 실행합니다.

      그 외에 synchronously notify가 false이면, 마이크로태스크를 큐에 추가하여 finish notification stepsanimation에 대해 실행합니다. 이미 해당 단계를 실행하기 위한 마이크로태스크가 큐에 있으면 추가하지 않습니다.

  6. current finished state가 false이고, animation현재 finished promise가 이미 resolve된 경우, animation현재 finished promise새 promise로, 관련 Realm에서 설정합니다.

일반적으로 애니메이션의 완료 상태 알림은 비동기적으로 수행됩니다. 이렇게 하면 애니메이션이 잠시 완료됨 재생 상태에 들어가도 이벤트가 트리거되거나 promise가 resolve되지 않게 됩니다.

예를 들어, 아래 코드에서 animation은 일시적으로 완료 상태가 됩니다. 만약 완료 상태 알림이 동기적으로 발생한다면, 이 코드는 finish event가 큐에 추가되고 현재 finished promise가 resolve됩니다. 하지만 두 문장의 순서를 바꿔 iterations을 먼저 업데이트하면 이런 일이 발생하지 않습니다. 이런 예기치 않은 동작을 방지하기 위해, 애니메이션의 완료 상태 알림은 일반적으로 비동기적으로 수행됩니다.

var animation = elem.animate({ left: '100px' }, 2000);
animation.playbackRate = 2;
animation.currentTime = 1000; // animation은 이제 완료됨
animation.effect.updateTiming({ iterations: 2 }); // animation은 더 이상 완료 상태가 아님

이 비동기 동작의 한 가지 예외는 애니메이션 완료 절차(보통 finish() 메서드 호출)일 때입니다. 이 경우 작성자가 명확하게 애니메이션을 완료시키려는 의도가 있으므로, 완료 상태 알림이 아래와 같이 동기적으로 발생합니다.

var animation = elem.animate({ left: '100px' }, 1000);
animation.finish(); // finish 이벤트가 즉시 큐에 추가되고 finished promise가
                    // resolve됨. 아래 문장 때문에 animation이 완료 상태를 벗어나도
animation.currentTime = 0;

애니메이션 완료 절차와 마찬가지로, 애니메이션 취소 절차도 cancel 이벤트를 큐에 추가하고 현재 finished promise현재 ready promise동기적으로 reject합니다.

4.4.13. 애니메이션 완료

애니메이션은 아래 정의된 애니메이션 완료 절차를 통해 현재 재생 방향의 자연스러운 끝으로 진행할 수 있습니다(animation에 대해):

  1. animation실효 재생 속도가 0이거나, 또는 animation실효 재생 속도 > 0이고 연관 효과 종료가 무한대라면, throw "InvalidStateError" DOMException 예외를 발생시키고 이 단계를 중단합니다.

  2. 대기 중인 재생 속도 적용animation에 실행합니다.

  3. limit을 다음과 같이 설정합니다:

    재생 속도 > 0인 경우,

    limit연관 효과 종료로 설정합니다.

    그 밖의 경우,

    limit을 0으로 설정합니다.

  4. 현재 시간 조용히 설정 절차를 limit으로 실행합니다.

  5. animation시작 시간미해결이고 animation활성 타임라인과 연결되어 있다면, 시작 시간을 다음과 같이 평가한 결과로 설정합니다: timeline time - (limit / 재생 속도) 여기서 timeline time은 연결된 타임라인의 현재 시간 값입니다.

  6. 대기 중 일시정지 작업이 있고 시작 시간해결됨이면,

    1. 홀드 시간미해결로 설정합니다.

      일반적으로 홀드 시간은 이미 미해결일 것입니다. 단, 애니메이션이 이전에 유휴 상태였을 때는 예외입니다.
    2. 대기 중 일시정지 작업을 취소합니다.

    3. resolve animation현재 ready promiseanimation으로 resolve합니다.

  7. 대기 중 재생 작업이 있고 시작 시간해결됨이면, 해당 작업을 취소하고 resolve animation현재 ready promiseanimation으로 resolve합니다.

  8. animation에 대해 애니메이션 완료 상태 업데이트 절차를 실행합니다. did seek 플래그는 true, synchronously notify 플래그는 true로 설정합니다.

4.4.14. 애니메이션 취소

애니메이션은 취소될 수 있으며, 이로 인해 현재 시간미해결이 되어 연관 효과로 인한 모든 효과가 제거됩니다.

애니메이션 취소 절차(animation에 대해)는 다음과 같습니다:

  1. animation재생 상태유휴가 아니라면, 아래 단계를 실행합니다:

    1. 애니메이션의 대기 작업 재설정 절차를 animation에 대해 실행합니다.

    2. reject animation현재 finished promise를 "AbortError"라는 이름의 DOMException으로 reject합니다.

    3. 현재 finished promise의 [[PromiseIsHandled]] 내부 슬롯을 true로 설정합니다.

    4. 현재 finished promise새 promise로, 관련 Realm에서 설정합니다.

    5. Create AnimationPlaybackEvent 객체 cancelEvent를 생성합니다.

    6. cancelEventtype 속성을 cancel로 설정합니다.

    7. cancelEventcurrentTime 속성을 null로 설정합니다.

    8. timeline timeanimation이 연결된 타임라인의 현재 시간으로 설정합니다. animation활성 타임라인과 연결되어 있지 않으면, timeline time미해결 시간 값으로 설정합니다.

    9. cancelEventtimelineTime 속성을 timeline time으로 설정합니다. timeline time미해결이면 null로 설정합니다.

    10. animation타이밍용 문서가 있다면, cancelEvent를 해당 타이밍용 문서대기 중 애니메이션 이벤트 큐에 타겟 animation과 함께 추가합니다. animation활성 타임라인과 연결되어 있고, 타임라인 시간이 원점 기준 시간으로 변환하는 절차를 정의한다면, 예정 이벤트 시간을 해당 절차의 결과로 timeline time에 대해 설정합니다. 그렇지 않으면 예정 이벤트 시간미해결 시간 값입니다.

      그 외의 경우, 작업을 큐에 추가하여 cancelEventanimation에서 디스패치합니다. 해당 작업의 소스는 DOM 조작 작업 소스입니다.

  2. animation홀드 시간미해결로 설정합니다.

  3. animation시작 시간미해결로 설정합니다.

애니메이션의 대기 작업 재설정 절차(animation에 대해)는 다음과 같습니다:

  1. animation대기 중 재생 작업이나 대기 중 일시정지 작업이 없다면, 이 절차를 중단합니다.

  2. animation대기 중 재생 작업이 있다면, 해당 작업을 취소합니다.

  3. animation대기 중 일시정지 작업이 있다면, 해당 작업을 취소합니다.

  4. 대기 중 재생 속도 적용animation에 실행합니다.

  5. reject animation현재 ready promise를 "AbortError"라는 이름의 DOMException으로 reject합니다.

  6. animation현재 ready promise의 [[PromiseIsHandled]] 내부 슬롯을 true로 설정합니다.

  7. animation현재 ready promise새로 resolve된 Promise 객체로, 값은 animation이며 관련 Realm에서 생성합니다.

4.4.15. 속도 제어

애니메이션의 재생 속도는 재생 속도를 설정하여 제어할 수 있습니다. 예를 들어, 재생 속도를 2로 설정하면 애니메이션의 현재 시간타임라인의 속도의 두 배로 증가합니다. 마찬가지로, 재생 속도가 -1이면 애니메이션의 현재 시간타임라인시간 값이 증가하는 속도만큼 감소합니다.

애니메이션재생 속도를 가지며, 이는 연결된 타임라인시간 값 변화 속도를 애니메이션의 현재 시간 변화로 변환하는 스케일 계수를 제공합니다. 재생 속도는 기본적으로 1입니다.

애니메이션의 재생 속도를 0으로 설정하면 사실상 애니메이션이 일시정지됩니다(단, 재생 상태가 반드시 일시정지됨이 되는 것은 아닙니다).

4.4.15.1. 애니메이션의 재생 속도 설정

재생 속도 설정 절차는 애니메이션 animationnew playback rate로 설정할 때 다음과 같습니다:

  1. animation대기 중 재생 속도를 모두 초기화합니다.

  2. previous time현재 시간으로, 재생 속도 변경 전의 값을 사용합니다.

  3. previous playback rateanimation의 현재 실효 재생 속도로 설정합니다.

  4. 재생 속도new playback rate로 설정합니다.

  5. 아래에서 첫 번째로 일치하는 조건의 단계를 실행합니다:

    animation단조 증가 타임라인에 연결되어 있고, previous time해결됨인 경우,

    animation현재 시간 설정 절차를 previous time으로 실행합니다.

    animation이 null이 아닌 타임라인에 연결되어 있고, 해당 타임라인이 단조 증가가 아니며, 시작 시간해결됨이고, 연관 효과 종료가 무한대가 아니며, 다음 중 하나라도 참일 때:

    • previous playback rate < 0이고 new playback rate ≥ 0, 또는

    • previous playback rate ≥ 0이고 new playback rate < 0,

    animation시작 시간연관 효과 종료 - 시작 시간 결과로 설정합니다.

    참고: 이는 단조 증가하지 않는 타임라인에서 시작/종료 시점을 뒤집어, 다른 방향에서도 시작 시간의 상대적 오프셋을 유지합니다.

4.4.15.2. 애니메이션의 재생 속도 원활하게 업데이트

다른 프로세스나 쓰레드에서 실행 중인 애니메이션의 경우, 재생 속도 설정 절차가 동기화되지 않은 상태에서 실행되면 애니메이션이 튀는 현상이 발생할 수 있습니다.

애니메이션재생 속도를 원활하게 변경하기 위해, 애니메이션은 대기 중 재생 속도를 가질 수 있으며, 이는 동기화가 필요할 때(다른 쓰레드/프로세스에서 실행 중인 애니메이션 등) 적용될 재생 속도를 의미합니다.

초기에는 애니메이션대기 중 재생 속도는 설정되지 않은 상태입니다.

animation실효 재생 속도대기 중 재생 속도가 있으면 그 값이고, 없으면 재생 속도입니다.

애니메이션 animation에 대해 대기 중 재생 속도 적용을 실행할 때는 아래 단계를 따릅니다:

  1. animation대기 중 재생 속도가 없다면, 이 단계를 중단합니다.

  2. animation재생 속도대기 중 재생 속도로 설정합니다.

  3. animation대기 중 재생 속도를 초기화합니다.

애니메이션 animation에 대해 재생 속도 원활하게 업데이트 절차(new playback rate로, 현재 시간을 유지함)는 다음과 같습니다:

  1. previous play stateanimation재생 상태로 설정합니다.

    참고: animation실효 재생 속도를 업데이트하기 전에 재생 상태를 기록해야 합니다. 아래 로직에서는 animation현재 완료됨이면, 이후 대기 중 재생 속도 적용 후 완료 상태가 아니더라도 바로 적용해야 합니다.

  2. animation대기 중 재생 속도new playback rate로 설정합니다.

  3. 아래에서 첫 번째로 일치하는 조건의 단계를 실행합니다:

    animation대기 중 재생 작업이나 대기 중 일시정지 작업이 있으면,

    이 단계를 중단합니다.

    참고: 서로 다른 종류의 대기 작업은 실행 시 대기 중 재생 속도를 적용하므로, 추가 작업이 필요하지 않습니다.

    previous play state유휴 또는 일시정지됨이거나, animation현재 시간미해결인 경우,

    대기 중 재생 속도 적용animation에 실행합니다.

    참고: 두 번째 조건은, 실행 중인 애니메이션에 대해, 현재 시간이 미해결이고 대기 중 재생 작업이 없으면 아래에서 재생을 시도하지 않도록 하기 위함입니다.

    previous play state완료됨인 경우,

    1. unconstrained current time현재 시간 계산 결과로, 홀드 시간미해결 시간 값으로 대체합니다.

    2. animation시작 시간을 아래 식의 결과로 설정합니다:

      timeline time - (unconstrained current time / 대기 중 재생 속도)

      여기서 timeline timeanimation이 연결된 타임라인의 현재 시간 값입니다.

      대기 중 재생 속도가 0이면, animation시작 시간timeline time으로 설정합니다.

    3. 대기 중 재생 속도 적용animation에 실행합니다.

    4. animation에 대해 애니메이션 완료 상태 업데이트 절차를 실행합니다. did seek 플래그는 false, synchronously notify 플래그는 false로 설정합니다.

    그 밖의 경우,

    animation에 대해 애니메이션 재생 절차를 auto-rewind 플래그를 false로 설정하여 실행합니다.

4.4.16. 애니메이션 역재생

애니메이션 animation에 대해 역재생 절차는 다음과 같습니다:

  1. animation에 연결된 타임라인이 없거나, 연결된 타임라인비활성이면, throw "InvalidStateError" DOMException 예외를 발생시키고 이 단계를 중단합니다.

  2. original pending playback rateanimation대기 중 재생 속도로 설정합니다.

  3. animation대기 중 재생 속도실효 재생 속도의 덧셈 역수(즉, -실효 재생 속도)로 설정합니다.

  4. animation에 대해 애니메이션 재생 절차를 auto-rewind 플래그를 true로 설정하여 실행합니다.

    만약 애니메이션 재생 절차에서 예외가 발생하면, animation대기 중 재생 속도original pending playback rate로 되돌리고, 예외를 전파합니다.

4.4.17. 재생 상태

애니메이션은 아래 재생 상태 중 하나로 설명될 수 있습니다. 각 상태에 대해 비규범적인 설명도 함께 제공합니다:

idle

애니메이션의 현재 시간미해결이고, 애니메이션의 시작 시간미해결이며, 대기 중인 작업이 없습니다. 이 상태에서는 애니메이션이 아무런 효과도 갖지 않습니다.

running

애니메이션은 해결된 현재 시간을 가지며, 각 애니메이션 프레임마다 값이 변경됩니다(단, 재생 속도가 0이 아니고, 타임라인활성이며 단조 증가일 때).

paused

애니메이션이 일시정지되었으며, 현재 시간이 더 이상 변하지 않습니다.

finished

애니메이션이 재생 범위의 자연스러운 경계에 도달했고, 현재 시간이 더 이상 갱신되지 않습니다.

애니메이션 animation재생 상태는 아래 조건들 중 첫 번째에 해당하는 상태입니다:

모두 다음 조건이 참일 때:

idle

다음 중 하나라도 참일 때:

paused

animation현재 시간해결됨이고 다음 중 하나라도 참일 때:

finished

그 밖의 경우,

running

재생 상태 판정에서 paused play statefinished play state보다 우선합니다.

단, 애니메이션이 자연스러운 재생 범위를 벗어난 상태에서 일시정지된 경우 start time을 아래와 같이 설정하면 paused에서 finished로 변환할 수 있습니다(재시작 없이):

animation.effect.updateTiming({ duration: 5000 });
animation.currentTime = 4000;
animation.pause();
animation.ready.then(function() {
  animation.effect.updateTiming({ duration: 3000 });
  alert(animation.playState); // 'paused' 출력
  animation.startTime =
    document.timeline.currentTime - animation.currentTime * animation.playbackRate;
  alert(animation.playState); // 'finished' 출력
});

4.4.18. 애니메이션 이벤트

애니메이션 이벤트에는 이 명세에서 정의된 애니메이션 재생 이벤트와 CSS 트랜지션의 이벤트 [CSS-TRANSITIONS-1], 그리고 CSS 애니메이션의 이벤트 [CSS-ANIMATIONS-1]가 포함됩니다. 추후 명세에서 더 다양한 애니메이션 이벤트가 추가될 수 있습니다.

Document대기 중 애니메이션 이벤트 큐를 유지하며, 애니메이션 이벤트와 해당 이벤트 타겟, 그리고 예정 이벤트 시간을 저장합니다. 예정 이벤트 시간시간 값으로, 시간 원점 기준으로 이벤트가 이상적으로 디스패치되었을 때의 시점을 나타냅니다. 이는 애니메이션 및 이벤트 업데이트 절차에서 큐에 있는 애니메이션 이벤트를 시간 순으로 정렬하는 데 사용됩니다. 이 값은 예를 들어 애니메이션타임라인이 시간 원점과 관계없는 값을 생성하는 경우(예: 스크롤 위치 기반 타임라인)나 타임라인비활성일 때 미해결이 될 수 있습니다.

4.4.18.1. 애니메이션 이벤트 정렬

아래 정의들은 큐에 있는 이벤트를 정렬하는 데 참고용으로 제공됩니다.

애니메이션 시간 값을 타임라인 시간으로 변환은 애니메이션 animation시작 시간 기준 상대 시간 값 time을 타임라인 시간으로 변환하는 절차입니다:

  1. time미해결이면 time을 반환합니다.

  2. time이 무한대이면 미해결 시간 값을 반환합니다.

  3. animation재생 속도가 0이면, 미해결 시간 값을 반환합니다.

  4. animation시작 시간미해결이면 미해결 시간 값을 반환합니다.

  5. 아래 식을 계산한 결과를 반환합니다: time × (1 / playback rate) + start time (playback ratestart time은 각각 재생 속도시작 시간입니다.)

타임라인 시간 값을 원점 기준 시간으로 변환타임라인 timeline과 동일 스케일의 시간 값 time을 원점 기준 시간으로 변환하는 절차입니다:

  1. timeline time애니메이션 시간 값을 타임라인 시간으로 변환한 결과로 설정합니다.

  2. timeline time미해결이면 time을 반환합니다.

  3. animation타임라인과 연결되어 있지 않으면, 미해결 시간 값을 반환합니다.

  4. animation비활성 타임라인에 연결되어 있으면, 미해결 시간 값을 반환합니다.

  5. animation이 연결된 타임라인에 타임라인 시간 값을 원점 기준 시간으로 변환하는 절차가 없다면, 미해결 시간 값을 반환합니다.

  6. 해당 절차로 timeline time을 원점 기준 시간으로 변환한 결과를 반환합니다(animation과 연결된 타임라인에 정의된 절차 사용).

4.4.18.2. 애니메이션 재생 이벤트

애니메이션이 재생될 때, 애니메이션 재생 이벤트를 통해 상태 변화를 보고합니다.

애니메이션 재생 이벤트는 타이밍 모델의 속성입니다. 따라서 애니메이션연관 효과가 없거나 가시적 결과가 없어도 이벤트는 디스패치됩니다.

4.4.18.3. 애니메이션 재생 이벤트 타입
finish

애니메이션이 finished play state에 진입할 때마다 큐에 추가됩니다.

cancel

애니메이션이 다른 상태에서 idle play state로 진입할 때마다 큐에 추가됩니다. 새로 생성된 애니메이션이 처음부터 idle이면 cancel event가 생성되지 않습니다.

remove

애니메이션이 자동으로 제거될 때마다 큐에 추가됩니다. § 5.5 애니메이션 대체 참고.

4.5. 애니메이션 효과

애니메이션 효과는 타이밍 계층에서 항목을 추상적으로 지칭하는 용어입니다.

4.5.1. 애니메이션 효과와 애니메이션 간의 관계

애니메이션연관 효과가 설정되어 있으면, 이는 애니메이션 효과의 한 종류입니다. 연관 효과애니메이션연결됨 상태라고 합니다. 한 시점에 애니메이션 효과는 최대 하나의 애니메이션연결될 수 있습니다.

애니메이션 효과 effect는, 타임라인에 연결됨 timeline 상태일 수 있는데, 이는 effect애니메이션에 연결되어 있고, 그 애니메이션이 timeline에 연결되어 있을 때입니다.

4.5.2. 애니메이션 효과의 종류

이 명세에서는 애니메이션 효과의 한 종류로 키프레임 효과만을 정의합니다. 이후 명세 단계에서는 더 다양한 애니메이션 효과가 정의될 예정입니다.

모든 애니메이션 효과 종류는 다음 절에서 설명하는 여러 공통 속성을 정의합니다.

4.5.3. 활성 구간

애니메이션 효과가 실행되도록 예약된 기간을 활성 구간이라고 합니다. 각 애니메이션 효과는 오직 하나의 활성 구간만을 가집니다.

활성 구간의 하한은 보통 이 애니메이션 효과에 연결된 애니메이션시작 시간과 일치하지만, 애니메이션 효과시작 지연에 의해 이동될 수 있습니다.

구간의 상한은 활성 지속 시간에 의해 결정됩니다.

시작 시간, 시작 지연, 활성 지속 시간의 관계는 아래 그림에서 설명합니다.

활성 구간의 시작점에 대한 start delay의 효과 예시
start delay활성 구간 끝점에 미치는 영향 예시.
(a) 지연이 없는 애니메이션 효과; 시작 시간활성 구간 시작이 일치.
(b) 양수 지연이 있는 경우; 활성 구간 시작이 지연만큼 늦춰짐.
(c) 음수 지연이 있는 경우; 활성 구간 시작이 지연만큼 앞당겨짐.

종료 지연도 지정할 수 있지만, 주로 애니메이션을 순차적으로 실행할 때에만 사용됩니다.

애니메이션 효과활성 구간을 정의하며, 이 구간 내에서 효과가 동작하도록 예약됩니다. 단, fill mode활성 구간 외에도 적용될 수 있습니다.

활성 구간의 하한은 start delay로 정의됩니다.

시작 지연애니메이션 효과가 연결된 애니메이션시작 시간으로부터의 부호 있는 오프셋입니다.

활성 구간의 길이를 활성 지속 시간이라고 하며, 계산 방법은 § 4.8.2 활성 지속 시간 계산에서 정의합니다.

시작 지연과 마찬가지로, 애니메이션 효과종료 지연도 가지며, 이는 주로 다른 애니메이션 효과종료 시간 기준으로 애니메이션을 순차적으로 실행할 때 사용됩니다. 보통 시퀀스 효과와 결합하여 사용할 때 유용하나, SVG의 min 속성을 표현하기 위해서도 포함됩니다([SVG11], 19장).

애니메이션 효과종료 시간max(start delay + 활성 지속 시간 + 종료 지연, 0)의 결과입니다.

4.5.4. 로컬 시간

로컬 시간애니메이션 효과의 특정 시점에서 다음 조건 중 첫 번째로 일치하는 값입니다:

애니메이션 효과애니메이션에 연결되어 있는 경우,

로컬 시간은 해당 애니메이션현재 시간입니다.

그 밖의 경우,

로컬 시간은 미해결입니다.

4.5.5. 애니메이션 효과의 페이즈와 상태

이 섹션은 규범적이지 않습니다

특정 시점에서 애니메이션 효과는 세 가지 페이즈 중 하나일 수 있습니다. 애니메이션 효과로컬 시간미해결이면 아무 페이즈에도 속하지 않습니다.

페이즈별 차이는 아래 그림에서 설명합니다.

애니메이션 효과를 설명하는 다양한 페이즈와 상태 예시
애니메이션 효과를 설명하는 다양한 페이즈와 상태 예시.

페이즈는 다음과 같습니다:

before phase

애니메이션 효과로컬 시간이 효과의 활성 구간종료 시간보다 이전이거나, 음수 시작 지연이 적용된 구간에 해당하는 경우입니다.

active phase

애니메이션 효과로컬 시간이 효과의 활성 구간 내에 있고, 음수 시작 지연이나 음수 종료 지연 구간이 아닌 경우입니다.

after phase

애니메이션 효과로컬 시간이 효과의 활성 구간 또는 종료 시간(음수 종료 지연으로 인해 먼저 올 수도 있음) 이후이지만, 음수 시작 지연 구간에는 해당하지 않는 경우입니다.

이들 페이즈 외에도 애니메이션 효과는 여러 겹치는 상태로도 설명될 수 있습니다. 이 상태들은 오직 하나의 애니메이션 프레임 동안만 정의되며, 주로 모델의 상태적 부분 묘사에 편의를 위해 사용됩니다.

각 상태와 모델 내에서의 용도 요약:

재생 중(in play)

활성 시간이 프레임마다 변하는 애니메이션 효과에 해당합니다.

current

재생 중이거나, 재생 중이 될 수 있는 애니메이션재생 속도에 따라 결정되는 애니메이션 효과에 해당합니다.

효과 중(in effect)

해결된 활성 시간이 있는 애니메이션 효과에 해당합니다. 이는 애니메이션 효과active phase에 있거나, active phase 외에 fill mode(§ 4.6 Fill behavior 참고)에 의해 활성 시간이 해결된 경우입니다. 효과 중 애니메이션 효과만이 타겟에 값을 적용합니다.

각 상태의 규범적 정의는 다음에 이어집니다.

애니메이션 효과 페이즈를 결정하려면 다음 정의가 필요합니다:

애니메이션 방향

효과가 애니메이션에 연결되어 있고, 연결된 애니메이션재생 속도가 0보다 작으면 "backwards"이고, 그 외에는 애니메이션 방향은 "forwards"입니다.

before-active boundary time

max(min(start delay, end time), 0)

active-after boundary time

max(min(start delay + active duration, end time), 0)

애니메이션 효과before phase 상태이며, 해당 효과의 로컬 시간미해결이 아니고, 아래 조건 중 하나라도 만족하면 before phase에 해당합니다:

  1. 로컬 시간before-active boundary time보다 작거나,

  2. 애니메이션 방향이 "backwards"이고 로컬 시간before-active boundary time과 같은 경우.

애니메이션 효과after phase 상태이며, 해당 효과의 로컬 시간미해결이 아니고, 아래 조건 중 하나라도 만족하면 after phase에 해당합니다:

  1. 로컬 시간active-after boundary time보다 크거나,

  2. 애니메이션 방향이 "forwards"이고 로컬 시간active-after boundary time과 같은 경우.

애니메이션 효과active phase 상태이며, 해당 효과의 로컬 시간미해결이 아니고, before phase나 after phase가 아닌 경우입니다.

그리고 위의 어느 페이즈에도 속하지 않는 경우를 편의상 idle phase라고 부르기도 합니다.

애니메이션 효과재생 중(in play) 상태이며, 아래 모든 조건을 만족하면 그렇습니다:

  1. 애니메이션 효과active phase에 있고,

  2. 애니메이션 효과애니메이션에 연결되어 있으며, 연결된 애니메이션이 finished 상태가 아닌 경우.

애니메이션 효과current 상태이며, 아래 조건 중 하나라도 참이면 그렇습니다:

애니메이션 효과는 효과 중(in effect) 상태이며, 활성 시간미해결이 아닐 때입니다(§ 4.8.3.1 활성 시간 계산 참고).

4.5.6. 관련 애니메이션

애니메이션은 연관된 애니메이션 효과 연결 여부를 기준으로 관련 있음으로 정의할 수 있습니다.

애니메이션은 다음 조건을 모두 만족하면 관련 있음(relevant)입니다:

관련 애니메이션(element 또는 pseudo-element target)은, effect targettarget애니메이션 효과를 최소 하나 이상 포함하는 모든 애니메이션의 집합입니다.

서브트리의 관련 애니메이션(element, pseudo-element, document 또는 shadow root target)은, effect targettarget포함 자손(또는 targetdocumentshadow root인 경우 자손)이거나, 해당 자손의 pseudo-element애니메이션 효과를 최소 하나 이상 포함하는 모든 애니메이션의 집합입니다.

4.6. 채움 동작

애니메이션 효과재생 중이 아닐 때의 효과는 해당 채움 모드에 의해 결정됩니다.

가능한 채움 모드는 다음과 같습니다:

이 모드들의 규범적 정의는 § 4.8.3.1 활성 시간 계산에서 활성 시간 계산에 포함되어 있습니다.

작성자들은 채움 모드를 사용하여 효과가 무기한 적용되는 애니메이션을 만드는 것을 지양해야 합니다. 채움 모드는 CSS 애니메이션 animation-fill-mode 속성을 표현하기 위해 도입되었습니다 ([CSS-ANIMATIONS-1]). 하지만 이들은 애니메이션 상태가 무한히 누적되는 상황을 만들 수 있어, § 5.5 애니메이션 대체에서 자동 애니메이션 제거가 필요해집니다. 또한 무기한 채움 애니메이션은 모든 애니메이션이 완료된 후에도 지정된 스타일 변경이 오랫동안 효과를 내지 못하게 할 수 있는데, 이는 CSS 계단식에서 애니메이션 스타일이 우선하기 때문입니다([css-cascade-3]).

가능하면, 작성자는 애니메이션의 최종 상태를 지정된 스타일로 직접 설정하는 것을 선호해야 합니다. 이는 애니메이션이 완료될 때까지 기다렸다가 스타일을 업데이트하는 방식으로 아래와 같이 구현할 수 있습니다:

// 아래 애니메이션이 완료된 후 첫 프레임에서, finished promise의 콜백이 먼저 실행되고 스타일이 업데이트되어 깜빡임이 발생하지 않습니다.
elem.animate({ transform: 'translateY(100px)' }, 200).finished.then(() => {
  elem.style.transform = 'translateY(100px)';
});

또는, 작성자가 애니메이션 시작 시 지정된 스타일을 먼저 설정하고, 원래 값에서 애니메이션하는 방식도 사용할 수 있습니다:

elem.style.transform = 'translateY(100px)';
elem.animate({ transform: 'none', offset: 0 }, 200);

여러 애니메이션을 겹쳐놓은 복잡한 효과에서는, 애니메이션을 취소하기 전에 최종 값을 기록하기 위해 임시로 forwards 채움 모드를 사용할 수 있습니다. 예시:

elem.addEventListener('click', async evt => {
  const animation = elem.animate(
    { transform: `translate(${evt.clientX}px, ${evt.clientY}px)` },
    { duration: 800, fill: 'forwards' }
  );
  await animation.finished;
  // commitStyles는 animation까지의 스타일을 기록하고 elem의 지정 스타일을 갱신합니다.
  animation.commitStyles();
  animation.cancel();
});

4.6.1. 채움 모드

이 섹션은 규범적이지 않습니다

채움 모드의 효과는 다음과 같습니다:

none

애니메이션 효과가 재생 중이 아닐 때 아무 효과도 없습니다.

forwards

애니메이션 효과가 after phase에 있을 때, 마지막으로 재생 중이었던 순간과 동일한 반복 진행도 값을 생성합니다.

그 외의 모든 재생 중이 아닌 시간에는 아무 효과가 없습니다.

backwards

애니메이션 효과가 before phase에 있을 때, 가장 처음 재생 중이었던 순간과 동일한 반복 진행도 값을 생성합니다.

그 외의 모든 재생 중이 아닌 시간에는 아무 효과가 없습니다.

both

애니메이션 효과가 before phase에 있으면 backwards 채움 동작이 적용됩니다.

애니메이션 효과가 after phase에 있으면 forwards 채움 동작이 적용됩니다.

아래에 다양한 채움 모드와 그로 인한 상태 예시가 나와 있습니다.

다양한 채움 모드와 생성되는 상태 예시
다양한 채움 모드와 생성된 상태 예시.
(a) 채움 모드 "none". 애니메이션 효과는 활성 phase 외에는 아무 효과도 없습니다.
(b) 채움 모드 "forwards". 활성 phase가 끝난 후에도 반복 진행도 값이 채움 값으로 유지됩니다.
(c) 채움 모드 "backwards". 활성 phase 시작 전까지 채움 값이 적용됩니다.
(d) 채움 모드 "both". 활성 phase 전후 모두 채움 값이 적용됩니다.

참고: 채움 모드를 설정해도 활성 구간의 끝점이나 phase 경계에는 영향이 없습니다. 그러나 채움 모드는 타이밍 모델의 여러 속성에 영향을 주는데, 활성 시간은 애니메이션 효과가 active phase 내에 있거나 채움이 적용될 때만 정의됩니다(미해결이 아님).

4.7. 반복

4.7.1. 반복 구간

애니메이션 효과가 정해진 횟수 또는 무한히 반복되도록 지정할 수 있습니다. 이 반복은 활성 구간 내에서 발생합니다. 한 번 반복이 실행되는 시간 범위를 반복 구간이라고 합니다.

활성 구간과 달리, 애니메이션 효과는 여러 반복 구간을 가질 수 있지만, 일반적으로 현재 반복에 해당하는 구간만 사용됩니다.

한 번 반복되는 길이를 반복 지속 시간이라고 하며, 애니메이션 효과의 초기 반복 지속 시간은 0입니다.

이 섹션은 규범적이지 않습니다

반복 지속 시간활성 지속 시간을 비교하면 다음과 같습니다:

반복 지속 시간

애니메이션 효과의 한 번 반복이 완료되는 데 걸리는 시간.

활성 지속 시간

전체 애니메이션 효과가 완료되는 데 걸리는 시간(반복 포함). 이 값은 반복 지속 시간보다 길거나 짧을 수 있습니다.

반복 지속 시간활성 지속 시간의 관계는 아래 그림에서 설명합니다.

반복 지속 시간과 활성 시간의 비교
반복 지속 시간활성 지속 시간의 비교. 반복 횟수가 2.5인 애니메이션 효과 예시. 마지막 반복의 반복 지속 시간은 변하지 않고, 단지 활성 지속 시간에 의해 잘립니다.

4.7.2. 반복 제어

애니메이션 효과가 반복되는 횟수를 반복 횟수라고 합니다. 반복 횟수는 0 이상의 실수입니다. 반복 횟수는 양의 무한대가 될 수 있으며, 이는 애니메이션 효과가 무한히 반복됨을 의미합니다.

반복 횟수 외에도, 애니메이션 효과반복 시작 속성을 가지며, 이는 애니메이션 효과가 반복 시리즈 중 어느 위치에서 시작할지 지정합니다. 반복 시작은 0 이상의 유한 실수입니다.

이 파라미터들의 동작은 § 4.8 핵심 애니메이션 효과 계산에서 정의됩니다.

이 섹션은 규범적이지 않습니다

반복 횟수반복 시작 파라미터의 효과는 아래 그림에서 설명합니다.

반복 횟수와 반복 시작 파라미터의 효과
반복 횟수반복 시작 파라미터의 효과.
첫 번째 예에서는 반복 횟수가 2.5로, 세 번째 반복이 반복 구간의 중간에서 잘립니다.
두 번째 예시는 반복 시작이 0.5인 경우로, 애니메이션 효과가 첫 번째 반복의 중간에서 시작하게 됩니다.

반복 횟수 파라미터와 달리, 반복 시작 파라미터는 활성 지속 시간의 길이에 영향을 주지 않습니다.

반복 시작이 1 이상인 값은, iteration composite operationaccumulate로 설정된 애니메이션 효과와 조합할 때만 일반적으로 유용합니다.

4.7.3. 반복 시간 공간

이 섹션은 규범적이지 않습니다

Web Animations에서는 모든 시간이 어떤 기준점에 상대적입니다. 이러한 기준점의 차이로 서로 다른 시간 공간이 생깁니다.

이는 컴퓨터 그래픽에서 사용하는 좌표 공간과 비교할 수 있습니다. 시간 공간의 0초는 좌표 공간의 원점에 해당합니다.

반복되는 애니메이션은 애니메이션이 반복될 때마다 새로운 시간 공간, 즉 반복 시간 공간을 형성한다고 설명할 수 있습니다.

반복 시간 공간은 애니메이션 효과의 현재 반복이 시작되는 시점을 0초로 하는 시간 공간입니다.

Web Animations 모델 내에서는 활성 시간도 사용하는데, 이는 활성 구간의 시작점에 상대적인 시간입니다. 이 시간 공간은 모델 내부에서만 사용되며, 프로그래밍 인터페이스나 마크업에서는 노출되지 않습니다.

이러한 시간 공간들은 아래 그림에서 설명합니다.

로컬 시간, 활성 시간, 반복 시간의 비교
반복 지속 시간 1초, 반복 횟수 2.5인 애니메이션의 로컬 시간, 활성 시간, 반복 시간 비교.

참고: 시간 공간 자체에는 경계가 없지만, Web Animations에서는 활성 시간반복 진행도를 다이어그램처럼 특정 범위로 제한(clamp)합니다. 예를 들어, 활성 시간 공간에서 -1초도 유효한 시간이지만, § 4.8.3.1 활성 시간 계산 절차에서는 음수 값이 반환되지 않습니다.

이들 시간 공간 외에도 문서 시간 공간이라고 부르는 것이 있는데, 이는 기본 문서 타임라인시간 값이 속한 Document현재 글로벌 객체의 시간 공간을 의미합니다.

4.7.4. 구간 타이밍

이 섹션은 규범적이지 않습니다

애니메이션 효과가 반복될 때 반복 경계에서의 동작을 정의해야 합니다. 이를 포함한 모든 구간 타이밍에 대해 Web Animations는 endpoint-exclusive 모델을 사용합니다. 즉, 구간의 시작 시간은 포함되지만, 끝 시간은 포함되지 않습니다. 구간 표기법으로는 [begin, end)입니다. 이 모델은 구간이 반복·순차적으로 실행될 때 구간 간의 겹침이 없도록 합리적 동작을 제공합니다.

아래 예시에서 반복 효과의 경우, 로컬 시간 1초에 반복 시간은 0입니다. 순차 애니메이션의 경우, 타임라인 시간 1초에는 애니메이션 B의 연관 효과재생 중이 되며, 겹침이 없습니다.

구간의 끝점 배타 타이밍 예시
끝점 배타 타이밍 예시. 반복 및 순차 애니메이션 효과 모두 구간 경계에서 겹침이 없습니다.

이 동작의 예외는 채움을 수행할 때, 채움이 구간 끝점에서 시작된다면 그 끝점이 사용된다는 점입니다. 이 동작은 § 4.8.3.3 간단 반복 진행도 계산의 알고리듬에서 유도되며, 아래 그림에서 설명합니다.

반복과 채움이 반복 시간에 미치는 영향
반복이 한 번 끝나면 반복 진행도는 0이지만, 두 번 반복 후(그 이후에도) 반복 진행도는 채움 동작에 따라 1이 됩니다.

4.8. 핵심 애니메이션 효과 계산

4.8.1. 개요

이 섹션은 규범적이지 않습니다

Web Animations 타이밍 모델의 핵심은 로컬 시간 값을 받아 반복 진행도로 변환하는 과정입니다.

이 과정의 첫 단계는 활성 구간의 경계를 계산하는데, 이는 활성 지속 시간에 의해 결정됩니다.

이 과정은 아래 그림에서 설명합니다.

활성 지속 시간 계산 예시
활성 지속 시간 계산은 반복 지속 시간반복 횟수를 곱해서 결정됩니다.

활성 지속 시간 계산 과정은 § 4.8.2 활성 지속 시간 계산에 규범적으로 정의되어 있습니다.

활성 지속 시간이 결정되면, 애니메이션 효과로컬 시간변환 진행도(반복 진행도)로 변환하는 과정은 아래 그림에서 설명합니다.

타이밍 모델 계산 개요
타이밍 모델 계산 개요.
(1) 로컬 시간은 연결된 애니메이션에서 결정됨.
(2) 로컬 시간활성 시간으로 변환되며, 시작 지연을 반영함.
(3) 활성 시간반복 지속 시간으로 나누고 반복 시작 속성도 반영하여 전체 진행도를 산출.
(4) 전체 진행도는 반복 내 오프셋인 간단 반복 진행도로 변환됨.
(5) 간단 반복 진행도방향 진행도로 변환되며, 재생 방향도 반영함.
(6) 마지막으로 타이밍 함수가 방향 진행도에 적용되어 변환 진행도가 산출됨.

첫 단계인 로컬 시간 계산은 § 4.5.4 로컬 시간에서 설명합니다. 다이어그램의 2~4단계는 다음 절에 설명되어 있습니다. 5, 6단계는 § 4.9.1 방향 진행도 계산§ 4.10.1 변환 진행도 계산에 설명되어 있습니다.

4.8.2. 활성 지속 시간 계산

활성 지속 시간은 아래와 같이 계산됩니다:

활성 지속 시간 = 반복 지속 시간 × 반복 횟수

반복 지속 시간 또는 반복 횟수가 0이면 활성 지속 시간도 0입니다.

이 명확화는 IEEE 754-2008에 따라 무한대 × 0의 결과가 정의되지 않기 때문에 필요합니다.

4.8.3. 로컬 시간 변환

4.8.3.1. 활성 시간 계산

활성 시간로컬 시간시작 지연에 기반합니다. 하지만, 활성 시간은 애니메이션 효과가 실제로 출력을 생성해야 할 때만 정의되며, 아래와 같이 채움 모드와 페이즈에 따라 달라집니다,

애니메이션 효과가 before phase에 있을 때,

결과는 아래에서 첫 번째로 일치하는 조건에 따라 결정됩니다,

채움 모드backwards 또는 both일 때,

아래 식의 결과를 반환합니다: max(로컬 시간 - 시작 지연, 0).

그 밖의 경우,

미해결 시간 값을 반환합니다.

애니메이션 효과가 active phase에 있을 때,

아래 식의 결과를 반환합니다: 로컬 시간 - 시작 지연.

애니메이션 효과가 after phase에 있을 때,

결과는 아래에서 첫 번째로 일치하는 조건에 따라 결정됩니다,

채움 모드forwards 또는 both일 때,

아래 식의 결과를 반환합니다: max(min(로컬 시간 - 시작 지연, 활성 지속 시간), 0).

그 밖의 경우,

미해결 시간 값을 반환합니다.

그 밖의 경우(로컬 시간미해결일 때),

미해결 시간 값을 반환합니다.

4.8.3.2. 전체 진행도 계산

전체 진행도는 지금까지 완료된 반복 횟수(부분 반복 포함)를 나타내며, 아래와 같이 정의됩니다:

  1. 활성 시간미해결이면 미해결을 반환합니다.

  2. 아래에서 첫 번째로 일치하는 조건에 따라 overall progress의 초기값을 계산합니다:

    반복 지속 시간이 0인 경우,

    애니메이션 효과가 before phase에 있으면 overall progress는 0, 그 외에는 반복 횟수와 같습니다.

    그 밖의 경우,

    overall progress는 아래 계산 결과로 합니다: 활성 시간 / 반복 지속 시간.

  3. overall progress + 반복 시작 결과를 반환합니다.

4.8.3.3. 간단 반복 진행도 계산

간단 반복 진행도는 현재 반복 내의 진행도를 나타내는 분수 값으로, 재생 방향이나 타이밍 함수 등 시간 변형을 무시하고 아래와 같이 계산합니다:

  1. 전체 진행도미해결이면 미해결을 반환합니다.

  2. 전체 진행도가 무한대면 simple iteration progress반복 시작 % 1.0이고, 그 외에는 simple iteration progress전체 진행도 % 1.0입니다.

  3. 아래 모든 조건이 참이면,

    simple iteration progress를 1.0으로 합니다.

    위 단계는 애니메이션의 활성 구간이 반복 끝점에 정확히 맞춰 끝나면, 다음 반복의 시작점이 아니라 마지막 반복의 끝점에서 채움이 유지되는 동작을 구현합니다.

    마지막 조건은 반복 횟수가 처음부터 0이어서 반복이 전혀 실행되지 않은 경우에는 적용되지 않게 합니다.

  4. simple iteration progress를 반환합니다.

4.8.4. 현재 반복 계산

현재 반복은 아래의 단계로 계산할 수 있습니다:

  1. 활성 시간미해결이면 미해결을 반환합니다.

  2. 애니메이션 효과가 after phase에 있고 반복 횟수가 무한대라면, 무한대를 반환합니다.

  3. 간단 반복 진행도가 1.0이면, floor(전체 진행도) - 1를 반환합니다.

  4. 그 밖의 경우, floor(전체 진행도)를 반환합니다.

4.9. 방향 제어

애니메이션 효과는 반복의 방향을 제어할 수도 있습니다. 이를 위해 애니메이션 효과재생 방향 파라미터를 가지며, 아래 값 중 하나를 가집니다:

이 값들의 의미는 아래 방향 진행도 계산에 포함되어 있습니다.

이 섹션은 규범적이지 않습니다

이 값들의 비규범적 정의는 다음과 같습니다:

normal

모든 반복은 지정된 대로 재생됩니다.

reverse

모든 반복은 지정과 반대 방향으로 재생됩니다.

alternate

짝수 반복은 지정된 방향대로, 홀수 반복은 반대 방향으로 재생됩니다.

alternate-reverse

짝수 반복은 반대 방향으로, 홀수 반복은 지정된 대로 재생됩니다.

4.9.1. 방향 진행도 계산

방향 진행도간단 반복 진행도에서 아래 단계로 계산합니다:

  1. 간단 반복 진행도미해결이면 미해결을 반환합니다.

  2. 아래에서 첫 번째로 일치하는 조건에 따라 current direction을 결정합니다:

    재생 방향normal인 경우,

    current direction을 forwards로 설정합니다.

    재생 방향reverse인 경우,

    current direction을 reverse로 설정합니다.

    그 밖의 경우,
    1. d현재 반복으로 설정합니다.

    2. 재생 방향alternate-reverse라면 d를 1만큼 증가시킵니다.

    3. d % 2 == 0이면 current direction을 forwards로, 아니면 reverse로 설정합니다. d가 무한대라면 current direction을 forwards로 설정합니다.

  3. current direction이 forwards이면 간단 반복 진행도를 반환합니다.

    그 밖의 경우, 1.0 - 간단 반복 진행도를 반환합니다.

4.10. 시간 변환

애니메이션 효과의 진행 속도를 제어하는 것이 바람직한 경우가 많습니다. 예를 들어, 애니메이션의 속도를 부드럽게(이징) 조절하면 모멘텀을 느끼게 하거나 보다 자연스러운 효과를 줄 수 있습니다. CSS 이징 함수 모듈 [CSS-EASING-1]에서는 이를 위한 타이밍 함수를 정의합니다.

애니메이션 효과는 하나의 타이밍 함수를 가집니다. 기본 타이밍 함수선형 타이밍 함수입니다.

4.10.1. 변환 진행도 계산

변환 진행도방향 진행도에서 다음 단계로 계산합니다:

  1. 방향 진행도미해결이면, 미해결을 반환합니다.

  2. before flag의 값을 아래와 같이 계산합니다:

    1. § 4.9.1 방향 진행도 계산에서 정의된 절차로 current direction을 결정합니다.

    2. current directionforwards이면, going forwards를 true로, 아니면 false로 설정합니다.

    3. 애니메이션 효과가 before phase에 있고 going forwards가 true이면, 또는 애니메이션 효과가 after phase에 있고 going forwards가 false이면, before flag를 설정합니다.

  3. 애니메이션 효과타이밍 함수를, 방향 진행도input progress value로, before flagbefore flag로 넘겨 계산한 결과를 반환합니다.

4.11. 반복 진행도

반복 진행도애니메이션 효과변환 진행도입니다.

5. 애니메이션 모델

이 섹션은 규범적이지 않습니다

일부 애니메이션 효과에 대해, Web Animations 애니메이션 모델타이밍 모델이 산출한 반복 진행도현재 반복 값을 받아 이에 상응하는 출력을 계산합니다.

이러한 애니메이션 효과 각각의 출력은 효과 스택에서 다른 효과의 출력과 합쳐진 다음, 대상 속성에 적용됩니다(§ 5.4 효과 결합 참고).

5.1. 소개

애니메이션 효과는 타이밍 출력 변화에 따라 영향을 받는 0개 이상의 속성을 가집니다. 이 속성들을 효과의 대상 속성이라고 합니다.

반복 진행도, 현재 반복, 기저 값이 주어지면, 애니메이션 효과는 각 애니메이션 가능한 대상 속성에 대해 해당 속성에 맞는 애니메이션 타입의 절차를 적용해 효과 값을 산출합니다.

5.2. 속성 애니메이션

별도 명시가 없는 한, 모든 CSS 속성은 애니메이션 가능입니다. 속성 값이 어떻게 결합되는지는 각 속성 정의 표의 애니메이션 타입 행에 정의되어 있습니다:

애니메이션 불가
해당 속성은 애니메이션 불가입니다. 애니메이션 키프레임에 명시되어도 처리되지 않으며, 트랜지션에도 영향을 받지 않습니다.

참고: 일부 속성은 애니메이션 처리 시 과도한 복잡성이 생기므로 애니메이션에서 제외됩니다. 예를 들어, 애니메이션 파라미터를 정의하는 속성은 애니메이션 불가인데, 이들을 애니메이션하면 복잡한 재귀 동작이 나타날 수 있습니다.

참고: 애니메이션 효과애니메이션 불가 속성만 대상으로 할 경우에도, 이벤트 발생, 애니메이션현재 finished promise의 이행 지연 등 통상적인 애니메이션 효과의 동작은 그대로 나타납니다.

이산(discrete)
해당 속성 값은 의미 있게 결합될 수 없으므로, 가산 불가능보간Va에서 Vb로 50%(p=0.5)에서 전환됩니다. 즉,
V result = V start p < 0.5일 때 V end p ≥ 0.5일 때
계산값 기준(by computed value)
계산값의 개별 컴포넌트를 (보간, 덧셈, 누적 등) 해당 값 타입에 맞는 절차로 결합합니다 (CSS Values 4 § 3 값 결합: 보간, 덧셈, 누적 참고). 컴포넌트 수나 타입이 맞지 않거나, 어떤 컴포넌트 값이 이산(discrete) 애니메이션이고 두 값이 다르다면, 속성 값은 이산(discrete)으로 결합됩니다.
반복 가능한 리스트(repeatable list)
계산값 기준과 동일하지만, 두 리스트의 아이템 수가 다르면 먼저 최소공배수 길이까지 반복합니다. 각 아이템은 계산값 기준으로 결합합니다. 결합 불가한 쌍이나 어떤 컴포넌트 값이 이산(discrete) 애니메이션이면, 속성 값은 이산(discrete)으로 결합합니다.

참고: 반복 가능한 리스트 개념은, 리스트가 특정 길이까지 개념적으로 반복될 때(background-originbackground-image 리스트 길이에 맞게 반복됨) 또는 무한 반복될 때, 어떤 값 사이든 부드럽게 전환되고, 계산값이 결과를 올바르게 표현하며(상속도 가능), 리스트가 올바른 길이로 처리될 수 있도록 합니다.

(See prose)
일부 속성은 위의 경우에 해당하지 않는 특정 보간 동작을 가지며, 이 경우 해당 속성에 대해 애니메이션 동작이 별도로 명시됩니다.

아직 애니메이션 타입 행이 속성 정의에 포함되지 않은 속성의 애니메이션 타입부록 A: 기존 속성의 애니메이션 타입에서 정의됩니다.

5.2.1. 사용자 정의 속성

사용자 정의 속성registerProperty() 메서드를 통해 현재 글로벌 오브젝트에 등록된 경우, 해당 애니메이션 타입계산값 기준이며, 속성의 문법 정의에 사용된 타입에서 유도됩니다. 속성의 지정 문법에 해당하는 계산값 타입이 없거나 (예: 문법이 범용 문법 정의일 때) 혹은 사용자 정의 속성이 등록되지 않은 경우에는, 애니메이션 타입이산(discrete)입니다.

5.3. 키프레임 효과

키프레임 효과애니메이션 효과의 한 종류로, 타이밍 모델의 출력을 이용해 요소 또는 의사 요소(예: ::before::after [select])의 CSS 속성을 갱신합니다. 이를 효과 타겟이라고 합니다.

효과 타겟Element 타입의 타겟 요소와, 의사 요소 선택자인 타겟 의사 선택자로 구성됩니다. 효과 타겟Element이면, 타겟 요소는 해당 요소이고, 타겟 의사 선택자null입니다. 효과 타겟의사 요소이면, 타겟 요소는 그 기원 요소이고, 타겟 의사 선택자는 해당 의사 요소를 지정하는 선택자입니다.

이 방법으로 지정된 모든 효과 타겟(예: ::part() 의사 요소나 미지원 의사 요소 등)이 반드시 계산된 속성 값을 갖는 것은 아닙니다.

5.3.1. 키프레임

키프레임 효과효과 값은, 분수 오프셋에 위치한 여러 속성 값 사이를 보간(interpolate)하여 계산됩니다. 오프셋별로 인덱싱된 각 속성 값 집합을 키프레임이라고 합니다.

키프레임 오프셋은 [0, 1] 범위의 값 또는 특별한 값 null입니다. 키프레임 목록은 키프레임 효과에 대해 오프셋 기준 느슨한 정렬이어야 하며, 이는 목록의 각 키프레임이 null이 아닌 키프레임 오프셋을 갖는 경우, 해당 오프셋 값이 목록에서 바로 이전의 null이 아닌 키프레임키프레임 오프셋 이상이어야 한다는 뜻입니다.

키프레임이 겹치거나 값이 미지원일 때의 동작은 § 5.3.4 키프레임 효과의 효과 값에서 정의됩니다.

각 키프레임에는 타이밍 함수가 연결되어 있으며, 해당 함수는 지정된 키프레임과 다음 키프레임 사이 구간에 적용됩니다. 목록의 마지막 키프레임에 지정된 타이밍 함수는 적용되지 않습니다.

키프레임에는 키프레임별 합성 연산(composite operation)이 있을 수 있으며, 지정된 경우 해당 키프레임의 모든 값에 적용됩니다. 가능한 연산과 의미는 § 5.4.4 효과 합성에서 전체 키프레임 효과에 지정된 합성 연산과 동일합니다. 키프레임별 합성 연산이 지정되지 않은 키프레임의 값에는 해당 키프레임 효과 전체에 대해 지정된 합성 연산이 사용됩니다.

5.3.2. 속성 값 계산

속성 값 계산 알고리즘은, 속성 property, 값 value, Element element가 주어졌을 때, property의 정의표에서 "Computed Value" 행을 따라 value를 resolve하고, 계산값 컨텍스트로 element의 계산값을 사용한 후, 그 결과를 반환합니다.

참고: 계산값은 해당 알고리즘에 의해 element에서 변경되지 않습니다.

이 알고리즘은, 키프레임에 지정된 속성 값이 순서 종속성을 만들 수 있음을 의미합니다. 속성 값 계산 시, value가 의존하는 값의 계산값먼저 계산되어야 합니다.

var animation = elem.animate([{ fontSize: '10px', width: '10em' },
                              { fontSize: '20px', width: '20em' }], 1000);
animation.currentTime = 500;
console.log(getComputedStyle(elem).fontSize); // 15px이어야 함
console.log(getComputedStyle(elem).width); // 225px이어야 함

이 예시에서 10em속성 값을 계산하려면, font-size계산값타겟 요소에서 알아야 하며, 이는 다시 효과 값으로 결정되고, font-size의 속성 값을 계산해야 합니다. 따라서 속성 값 계산에는 순서 제약이 따릅니다.

5.3.3. 계산된 키프레임 계산

키프레임 효과효과 값을 계산하기 전에, 그 키프레임의 속성 값을 계산하고, null 키프레임 오프셋에 사용할 오프셋도 계산합니다. 이 값들의 결과가 계산된 키프레임입니다.

null이 아닌 값을 포함한 키프레임 집합의 키프레임 오프셋을 계산한 결과를 계산된 키프레임 오프셋이라고 합니다.

계산된 키프레임 오프셋을 산출하기 위해, 키프레임 시퀀스 keyframes에 대해 키프레임 오프셋 누락 계산 절차를 정의하며, 다음 단계로 진행합니다:

  1. keyframes의 각 키프레임에 대해, 키프레임계산된 키프레임 오프셋을 해당 키프레임 오프셋 값으로 설정합니다.

  2. keyframes키프레임이 2개 이상 있고, 첫 번째 키프레임계산된 키프레임 오프셋이 null이면, 첫 번째 계산된 키프레임 오프셋을 0으로 설정합니다.

  3. 마지막 키프레임계산된 키프레임 오프셋이 null이면, 해당 계산된 키프레임 오프셋을 1로 설정합니다.

  4. 아래 조건을 모두 만족하는 키프레임 A, B 쌍에 대하여:

    AB 사이에 있는 각 키프레임계산된 키프레임 오프셋은 아래와 같이 계산합니다:

    1. offsetk계산된 키프레임 오프셋으로 합니다.

    2. nA, B 포함해 사이에 있는 키프레임 수에서 1을 뺀 값으로 합니다.

    3. indexAB 사이 키프레임 중에서, A 바로 다음 키프레임이 1인 위치로 합니다.

    4. keyframe계산된 키프레임 오프셋offsetA + (offsetBoffsetA) × index / n으로 설정합니다.

계산된 키프레임은 다음 절차로 산출합니다. 이 절차는 반드시 계산된 속성 값을 산출할 수 있는 키프레임 효과에 대해 수행합니다.

  1. computed keyframes를 빈 키프레임 리스트로 초기화합니다.

  2. 해당 키프레임 효과에 지정된 키프레임 리스트의 각 keyframe에 대해, 아래 단계를 수행합니다:

    1. 새 빈 키프레임 computed keyframecomputed keyframes에 추가합니다.

    2. keyframe에 지정된 각 속성에 대해:

      예를 들어, keyframeborder-width에 "12pt" 값을 지정하면, 사용자 에이전트는 각 longhand 속성에 대해 "16px"로 속성 값 계산을 할 수 있습니다: border-bottom-width, border-left-width, border-right-width, border-top-width 등. 결과적으로 computed keyframe에는 border-width 속성 값은 없고, 각 longhand 속성에 "16px" 값이 포함됩니다.

      축약 속성 확장이나 논리 속성의 물리 속성 대체 과정에서 충돌이 발생하면, 아래 규칙을 순서대로 적용해 해결합니다:

      1. longhand 속성이 shorthand 속성보다 우선합니다(예: border-top-colorborder-top보다 우선).

      2. longhand 구성 요소가 더 적은 shorthand 속성이 더 많은 shorthand 구성 요소를 포함한 속성보다 우선합니다(예: border-topborder-color보다 우선).

      3. 물리 속성이 논리 속성보다 우선합니다.

      4. 동일한 longhand 구성 수를 가지는 shorthand 속성의 경우, 각 속성의 IDL 이름(CSS property to IDL attribute 알고리즘 [CSSOM] 참고)이 유니코드 코드포인트 오름차순 정렬에서 더 앞서는 속성이 뒤에 오는 속성보다 우선합니다.

  3. 키프레임 오프셋 누락 계산 절차를 computed keyframes에 적용합니다.

  4. computed keyframes를 반환합니다.

5.3.4. 키프레임 효과의 효과 값

키프레임 효과가 참조하는 단일 속성의 효과 값은 그 대상 속성 중 하나로, 주어진 iteration progress, current iteration, underlying value에 대해 아래와 같이 계산됩니다.

  1. iteration progress미해결이면 이 절차를 중단합니다.

  2. target property를 효과 값을 계산할 longhand 속성으로 설정합니다.

  3. target property애니메이션 타입애니메이션 불가이면 효과를 적용할 수 없으므로 이 절차를 중단합니다.

  4. 키프레임 효과효과 타겟이 없거나, 효과 타겟에서 계산된 속성 값을 산출할 수 없으면 이 절차를 중단합니다.

  5. 합성 중립값을, add 합성 연산으로 기저 값과 결합할 때 기저 값이 그대로 나오게 하는 값으로 정의합니다.

  6. property-specific keyframes를 이 키프레임 효과계산된 키프레임 집합으로 설정합니다.

  7. property-specific keyframes에서 target property 값이 없는 키프레임을 모두 제거합니다.

  8. property-specific keyframes가 비어 있으면 underlying value를 반환합니다.

  9. 만약 property-specific keyframes 내에 계산된 키프레임 오프셋이 0인 키프레임이 없다면, 키프레임을 새로 만들어, 계산된 키프레임 오프셋을 0으로, 속성 값을 합성 중립값으로, 합성 연산add로 지정하여 property-specific keyframes 맨 앞에 추가합니다.

  10. 마찬가지로, property-specific keyframes 내에 계산된 키프레임 오프셋이 1인 키프레임이 없다면, 키프레임을 새로 만들어, 계산된 키프레임 오프셋을 1로, 속성 값을 합성 중립값으로, 합성 연산add로 지정하여 property-specific keyframes 맨 끝에 추가합니다.

  11. interval endpoints를 빈 키프레임 시퀀스로 초기화합니다.

  12. interval endpoints를 아래 첫 번째로 일치하는 조건에 따라 채웁니다:

    iteration progress < 0이고, property-specific keyframes계산된 키프레임 오프셋이 0인 키프레임이 두 개 이상 있을 때,

    property-specific keyframes의 첫 번째 키프레임interval endpoints에 추가합니다.

    iteration progress ≥ 1이고, property-specific keyframes계산된 키프레임 오프셋이 1인 키프레임이 두 개 이상 있을 때,

    property-specific keyframes의 마지막 키프레임interval endpoints에 추가합니다.

    그 밖의 경우,
    1. property-specific keyframes에서 계산된 키프레임 오프셋iteration progress 이하이고 1 미만인 마지막 키프레임interval endpoints에 추가합니다. 없으면(예: iteration progress가 음수인 경우) 키프레임계산된 키프레임 오프셋이 0인 마지막 키프레임을 추가합니다.

    2. 이전 단계에서 추가한 키프레임 바로 다음 키프레임interval endpoints에 추가합니다.

  13. interval endpoints의 각 keyframe에 대해:

    1. keyframe합성 연산replace가 아니거나, keyframe합성 연산이 없고 이 키프레임 효과합성 연산replace가 아니면, 아래 단계를 수행합니다:

      1. composite operation to usekeyframe합성 연산으로, 없으면 이 키프레임 효과의 합성 연산으로 설정합니다.

      2. value to combinekeyframe에 지정된 target property의 속성 값으로 설정합니다.

      3. target property의 속성 값을 keyframe에서, underlying value(Va)와 value to combine(Vb)를 composite operation to use에 맞는 애니메이션 타입의 절차로 결합한 결과로 대체합니다.

  14. interval endpoints에 키프레임이 하나만 있으면, 그 키프레임의 target property 속성 값을 반환합니다.

  15. start offsetinterval endpoints의 첫 번째 키프레임의 계산된 키프레임 오프셋으로 설정합니다.

  16. end offsetinterval endpoints의 마지막 키프레임의 계산된 키프레임 오프셋으로 설정합니다.

  17. interval distance(iteration progress - start offset) / (end offset - start offset)로 계산합니다.

  18. transformed distanceinterval endpoints의 첫 번째 키프레임에 연결된 타이밍 함수interval distance를 입력값으로 넘겨 계산한 결과로 설정합니다.

  19. interval endpoints의 두 키프레임에 지정된 target property 값을 애니메이션 타입보간(interpolation) 절차에 따라, 첫 번째 값을 Vstart, 두 번째 값을 Vend로 사용하고, transformed distance를 보간 파라미터 p로 사용해서 결과를 반환합니다.

이 절차는 효과에 지정된 키프레임 목록에 대해 아래와 같은 조건을 가정합니다:

모델 사용자(예: 선언적 마크업 또는 프로그래밍 인터페이스)가 이 조건을 충족시켜야 합니다.

예를 들어, 본 명세에서 정의된 프로그래밍 인터페이스에선, 이 조건은 계산된 키프레임을 산출하는 절차에서 충족되어, 본 절차의 입력이 됩니다.

참고: 이 절차는 키프레임이 겹치는(overlap) 경우도 허용합니다. 겹치는 오프셋에서 출력 값은 해당 오프셋에 마지막으로 정의된 키프레임 값으로 점프합니다. 0 또는 1에서 겹치는 키프레임의 경우, iteration progress 값이 0 미만 또는 1 이상일 때 출력 값은 키프레임 목록의 첫 번째 또는 마지막 값이 됩니다.

계산된 키프레임은 "live" 상태임에 유의하세요: 사용자 에이전트는 효과 값을 계산할 때마다 새롭게 계산되는 것처럼 동작해야 합니다.

예를 들어 font-size 속성에 대해 10px에서 20px로 트랜지션 중일 때, 키프레임1em 값이 지정되면, 키프레임 계산 과정에서 계산값font-size의 트랜지션으로 생성된 [10px, 20px] 범위 내에서 resolve됩니다.

일부 타이밍 함수가 있을 때, 애니메이션 효과에 전달되는 입력 iteration progress는 [0, 1] 범위로 제한되지 않습니다. 현재는 키프레임 오프셋은 반드시 [0, 1] 범위로 제한되어 있으며, 그 범위 밖의 iteration progress 값에 대해서는 속성 값이 단순히 외삽(extrapolate)됩니다.

이 제한을 제거하는 방안도 고려 중인데, 범위 밖의 iteration progress에서 속성 값이 비선형적으로 변하는 경우가 실무적으로 존재하기 때문입니다. 예를 들어, 애니메이션이 초록에서 노랑으로 보간하지만 오버슈트 타이밍 함수 덕분에 잠시 노랑을 넘어 빨간색으로 이동한 뒤 다시 노랑으로 복귀하는 경우가 있습니다.

이 효과는 키프레임과 타이밍 함수를 조정해 만들 수도 있지만, 이 방식은 모델의 타이밍과 애니메이션 효과 분리를 깨뜨리는 것으로 보입니다.

이 효과를 어떻게 구현할지는 아직 불명확하지만, 키프레임 오프셋을 [0, 1] 밖으로 허용하면 0과 1에서 키프레임을 합성하는 기존 동작과 일관성이 깨질 수 있습니다.

2013 도쿄 F2F 4절(Keyframe offsets outside [0, 1]) 회의록 참고.

<https://github.com/w3c/csswg-drafts/issues/2081>

5.4. 효과 결합

이 섹션은 규범적이지 않습니다

키프레임 효과효과 값을 계산한 뒤, 해당 값들은 애니메이션 효과대상 속성에 적용됩니다.

여러 효과 중 키프레임 효과가 동일 속성을 타겟팅할 수 있으므로, 여러 키프레임 효과의 결과를 결합해야 할 필요가 있습니다. 이 과정을 합성(compositing)이라고 하며, 각 속성별로 효과 스택을 구축해 진행합니다(효과 중 애니메이션 효과 기준).

여러 키프레임 효과의 결과를 합성한 뒤, 그 합성 결과는 해당 대상 속성에 지정된 다른 값들과 결합됩니다.

아래 그림은 전체 구조를 설명합니다:

효과 값이 대상 속성에 적용되는 전체 흐름
효과 값대상 속성에 적용되는 전체 구조.
동일 속성을 타겟팅하는 키프레임 효과의 결과는 효과 스택을 사용해 합성됩니다.
이 합성 결과는 적절한 위치에서 CSS 계단식에 삽입되어 적용됩니다.

이 과정의 첫 단계(동일 속성에 대해 효과 값을 결합하는 과정)에서는, 여러 키프레임 효과를 어떻게 결합할지(how), 그리고 적용 순서(order, 즉 상대 합성 순서(composite order))를 정해야 합니다.

효과 값을 결합하는 방식(how)은 각 키프레임 효과합성 연산에 의해 결정됩니다.

효과 값의 상대 합성 순서는, 각 애니메이션된 속성별로 구축되는 효과 스택에 의해 결정됩니다.

5.4.1. 애니메이션 클래스

이 명세는, 본 모델 위에 마크업이나 프로그래밍 인터페이스를 정의하는 다른 명세에서 사용할 수 있도록 공통 애니메이션 모델을 제공합니다. 특정 마크업/프로그래밍 인터페이스가 생성한 애니메이션은 그 애니메이션 클래스를 정의합니다.

후속 명세에서는 서로 다른 애니메이션 클래스 간 또는 클래스 내부에서 합성 순서에 대한 특수 동작을 정의할 수 있습니다.

이 섹션은 규범적이지 않습니다

예를 들어, 클래스가 "CSS animation"인 애니메이션은 "CSS transition" 클래스보다 높은 합성 순서, 기타 클래스 없는 애니메이션보다 낮은 합성 순서를 갖도록 정의됩니다.

"CSS animation" 객체 집합 내에서는, animation-name 속성 등 여러 요소에 따라 특수 합성 순서가 정의됩니다.

5.4.2. 효과 스택

효과 스택은, 하나 이상의 키프레임 효과가 타겟팅하는 각 속성마다 연결됩니다. 효과 스택키프레임 효과들 간의 상대 합성 순서를 결정합니다.

효과 스택 내 두 키프레임 효과 A, B의 상대 합성 순서는 아래 속성 비교로 결정됩니다:

  1. 애니메이션 효과의 연결된 애니메이션을, 해당 애니메이션 효과연결애니메이션으로 합니다.

  2. AB를 아래 조건을 순서대로 적용해 비교해 결정합니다:

    1. A, B연결된 애니메이션클래스가 다르면, 각 클래스에 정의된 inter-class 합성 순서로 결정합니다.

    2. 아직 비교가 끝나지 않았으면, 두 A, B의 공통 클래스에 정의된 class-specific 합성 순서로 비교합니다.

    3. 아직도 결정이 안 되면, 전역 애니메이션 리스트에서 A, B연결된 애니메이션 위치로 비교합니다.

애니메이션 효과가 먼저 정렬되면 더 낮은 합성 순서를 갖습니다.

5.4.3. 효과 스택 결과 계산

효과 스택의 최종 값을 계산하려면, 스택에 포함된 각 키프레임 효과효과 값을 합성 순서대로 결합합니다.

효과 스택 평가 과정의 각 단계는 입력값으로 기저 값을 받습니다.

스택의 각 키프레임 효과에 대해, 해당 키프레임 효과의 적절한 효과 값기저 값과 결합하여 새 값을 생성합니다. 이렇게 생성된 값은 다음 키프레임 효과와 결합할 때의 새로운 기저 값이 됩니다.

스택의 최종 효과 스택 값은 합성 값이라 하며, 스택에서 마지막(합성 순서가 가장 높은) 키프레임 효과효과 값과 해당 시점의 기저 값을 결합한 결과입니다.

5.4.4. 효과 합성

효과 값기저 값과 결합할 때 사용하는 구체적인 연산은 키프레임 효과합성 연산(composite operation)에 따라 결정됩니다.

이 명세에서는 아래 세 가지 합성 연산을 정의합니다:

replace

효과 값기저 값을 합성한 결과는 단순히 효과 값입니다.

add

효과 값덧셈(addition) 연산으로 기저 값에 더합니다. 애니메이션 타입에 따라 덧셈 연산이 교환법칙이 성립하지 않는 경우, 피연산자 순서는 기저 값 + 효과 값입니다.

accumulate

효과 값누적(accumulation) 연산으로 기저 값에 누적합니다. 애니메이션 타입에 따라 누적 연산이 교환법칙이 성립하지 않는 경우, 피연산자 순서는 기저 값 다음에 효과 값입니다.

5.4.5. 합성 결과 적용

합성 값대상 속성에 적용하려면, 지정값을 CSS 계단식에 추가하면 됩니다.

지정값이 CSS 계단식의 어느 단계에 추가되는지는, 효과 스택 내에서 가장 높은 합성 순서를 갖는 효과가 연결된 클래스에 따라 결정됩니다. 기본적으로 지정값은 CSS 계단식의 "Animation declarations" 단계에 추가됩니다([css-cascade-3]).

이 섹션은 규범적이지 않습니다

예를 들어, 가장 높은 합성 순서의 효과가 "CSS transition" 클래스 애니메이션에 연결된 경우, 합성 값은 "Transition declarations" 단계에 추가됩니다.

CSS 대상 속성에 계산된 합성 값은 아래 절차로 적용됩니다.

  1. 해당 속성에 대해 애니메이션이 없을 때 계산값을 구해, 그 값을 base value로 설정합니다.

  2. 해당 속성의 효과 스택을 구축합니다(§ 5.4.2 효과 스택 참고).

  3. base value를 초기 기저 값으로 하여, 효과 스택합성 값을 계산합니다(§ 5.4.3 효과 스택 결과 계산 참고).

  4. 효과 스택의 맨 위에 있는 효과가 연결된 애니메이션클래스에 정의된 단계에, 합성 값을 CSS 계단식에 삽입합니다.

5.5. 애니메이션 대체

이 섹션은 규범적이지 않습니다

이 명세에서 정의된 프로그래밍 인터페이스를 사용하면, 요소의 애니메이션 스타일에 기여하는 새 애니메이션을 무한 반복적으로 트리거할 수 있습니다.

예를 들어, 아래 코드를 보세요:

elem.addEventListener('mousemove', evt => {
  circle.animate(
    { transform: `translate(${evt.clientX}px, ${evt.clientY}px)` },
    { duration: 500, fill: 'forwards' }
  );
});

이 코드는 마우스가 움직일 때마다 새로운 forwards-fill 애니메이션을 생성하며, 빠르게 수백, 수천 개의 forwards-fill 애니메이션이 쌓입니다.

만약 사용자 에이전트가 모든 이런 애니메이션을 유지해야 한다면, 애니메이션 리스트가 끝없이 커져 결국 메모리 누수가 발생할 수 있습니다.

이 섹션에서는 오버라이드된 애니메이션이 명시적으로 보존되지 않는 한 자동으로 제거되는 메커니즘을 정의합니다.

5.5.1. 대체 상태

애니메이션은 아래 값 중 하나를 가질 수 있는 대체 상태(replace state)를 유지합니다:

애니메이션대체 상태의 초기 값은 active입니다.

replace stateremoved애니메이션애니메이션 효과는 그 대상 속성효과 스택에 포함되지 않습니다.

5.5.2. 대체된 애니메이션 제거

애니메이션은 아래 모든 조건을 만족하면 대체 가능(replaceable)입니다:

Document doc에 대해 대체된 애니메이션 제거를 요청받으면, 아래 조건을 모두 만족하는 각 애니메이션 animation에 대해 다음을 수행합니다:

다음 단계를 수행합니다:

  1. animationreplace stateremoved로 설정합니다.

  2. Create an AnimationPlaybackEvent, removeEvent.

  3. removeEventtype 속성을 remove로 설정합니다.

  4. removeEventcurrentTime 속성을 animation현재 시간으로 설정합니다.

  5. removeEventtimelineTime 속성을 animation이 연결된 타임라인 현재 시간으로 설정합니다.

  6. animationdocument for timing이 있으면, removeEvent를 그 document for timing대기 중 애니메이션 이벤트 큐에, 타겟 animation과 함께 추가합니다. 예정 이벤트 시간타임라인 시간을 원점 기준 시간으로 변환 절차를 animation이 연결된 타임라인 현재 시간에 적용한 결과로 사용합니다.

    그 밖의 경우, 태스크(queue a task)디스패치(dispatch)하는데, removeEventanimation에 디스패치합니다. 이 태스크의 소스는 DOM 조작 태스크 소스입니다.

5.6. 애니메이션의 부수 효과

최소 하나의 애니메이션 효과에 의해 타겟팅되고, current 또는 효과 중인 모든 속성에 대해, 그리고 그 효과가 애니메이션에 연결되어 있고, 해당 애니메이션의 replace stateremoved아닌 경우, 사용자 에이전트는 will-change 속성이 effect target에 해당 속성을 포함하는 것처럼 동작해야 합니다.

이 섹션은 규범적이지 않습니다

위 요구사항의 결과로, 예를 들어 애니메이션이 요소의 transform 속성을 타겟팅하면, 스태킹 컨텍스트effect target에 대해 생성됩니다. 단, 애니메이션before phase 또는 active phase에 있거나, "forwards" 혹은 "both" fill mode이고 after phase에 있는 경우에만 해당합니다.

6. 프로그래밍 인터페이스

이 섹션은 규범적이지 않습니다

위에서 설명한 추상 모델 외에도, Web Animations는 모델에 대한 프로그래밍 인터페이스도 정의합니다. 이 인터페이스는 선언적 방식으로 생성된 애니메이션을 검사 및 확장하거나, 절차적 접근이 더 적합한 경우 직접 애니메이션을 생성하는 데 사용할 수 있습니다.

6.1. 프로그래밍 인터페이스의 시간 값

시간 값은 프로그래밍 인터페이스에서 double 타입으로 표현됩니다. 미해결 시간 값은 null로 표현됩니다.

6.2. AnimationTimeline 인터페이스

타임라인은 Web Animations API에서 AnimationTimeline 인터페이스로 표현됩니다.

[Exposed=Window]
interface AnimationTimeline {
    readonly attribute double? currentTime;
};
currentTime, 타입 double, 읽기 전용, nullable

이 타임라인의 현재 시간을 반환합니다. 타임라인이 비활성이면 null을 반환합니다.

6.3. DocumentTimeline 인터페이스

문서 타임라인기본 문서 타임라인은 Web Animations API에서 DocumentTimeline 인터페이스로 표현됩니다.

dictionary DocumentTimelineOptions {
  DOMHighResTimeStamp originTime = 0;
};

[Exposed=Window]
interface DocumentTimeline : AnimationTimeline {
  constructor(optional DocumentTimelineOptions options = {});
};
originTime, 타입 DOMHighResTimeStamp, 기본값 0

타임라인의 origin time을 밀리초 단위 실수로 지정하며, 시간 원점 기준 상대값입니다.

DocumentTimeline (options)

DocumentTimeline를 생성합니다. 타임라인이 연결되는 DocumentDocument연결Window현재 글로벌 오브젝트가 됩니다.

options

새로 생성된 타임라인의 설정 파라미터. 이 명세에서는 originTime만 정의하지만, 다른 명세에서 더 많은 파라미터를 확장할 수 있습니다.

6.4. Animation 인터페이스

애니메이션은 Web Animations API에서 Animation 인터페이스로 표현됩니다.

[Exposed=Window]
interface Animation : EventTarget {
    constructor(optional AnimationEffect? effect = null,
                optional AnimationTimeline? timeline);
             attribute DOMString                id;
             attribute AnimationEffect?         effect;
             attribute AnimationTimeline?       timeline;
             attribute double?                  startTime;
             attribute double?                  currentTime;
             attribute double                   playbackRate;
    readonly attribute AnimationPlayState       playState;
    readonly attribute AnimationReplaceState    replaceState;
    readonly attribute boolean                  pending;
    readonly attribute Promise<Animation>       ready;
    readonly attribute Promise<Animation>       finished;
             attribute EventHandler             onfinish;
             attribute EventHandler             oncancel;
             attribute EventHandler             onremove;
    undefined cancel();
    undefined finish();
    undefined play();
    undefined pause();
    undefined updatePlaybackRate(double playbackRate);
    undefined reverse();
    undefined persist();
    [CEReactions]
    undefined commitStyles();
};
Animation (effect, timeline)

아래 절차에 따라 새로운 Animation 객체를 생성합니다.

  1. animation을 새로운 Animation 객체로 생성합니다.

  2. animation에 대해 timelinenew timeline으로 넘기거나, timeline 인자가 없으면 기본 문서 타임라인Document연결Window현재 글로벌 오브젝트로 넘겨 애니메이션의 타임라인 설정 절차를 실행합니다.

  3. animation에 대해 sourcenew effect로 넘겨 애니메이션의 연관 효과 설정 절차를 실행합니다.

effect

null이 아니면, 새로 생성된 애니메이션에 할당할 연관 효과를 지정합니다.

timeline

존재하면, 새로 생성된 애니메이션과 연결할 타임라인을 지정합니다. 없으면, 기본 문서 타임라인Document연결Window현재 글로벌 오브젝트로 사용됩니다.

id, 타입 DOMString

애니메이션을 식별하는 문자열입니다.

effect, 타입 AnimationEffect, nullable

이 애니메이션의 연관 효과입니다. 해당 속성을 설정하면 연관 효과가 애니메이션의 연관 효과 설정 절차에 따라 갱신됩니다.

timeline, 타입 AnimationTimeline, nullable

이 애니메이션에 연결된 타임라인입니다. 해당 속성을 설정하면 애니메이션의 타임라인이 애니메이션 타임라인 설정 절차에 따라 갱신됩니다.

startTime, 타입 double, nullable

이 애니메이션의 시작 시간을 반환합니다. 해당 속성을 설정하면 새로운 값으로 시작 시간이 시작 시간 설정 절차에 따라 갱신됩니다.

currentTime, 타입 double, nullable

이 애니메이션의 현재 시간입니다. 해당 속성을 설정하면 새로운 값으로 애니메이션 현재 시간 설정 절차를 수행합니다.

playbackRate, 타입 double

이 애니메이션의 재생 속도입니다. 해당 속성을 설정하면 새로운 값으로 재생 속도 설정 절차를 수행합니다.

이 속성을 설정하면 재생 속도가 동기적으로 갱신되며, 별도의 프로세스나 스레드에서 실행 중인 애니메이션과 재생 상태를 동기화하지 않습니다. 결과적으로, 비행 중인(실행 중인) 애니메이션의 playbackRate를 설정하면 애니메이션이 점프할 수 있습니다.

비행 중인 애니메이션의 재생 속도를 부드럽게 갱신하려면, 비동기 updatePlaybackRate() 메서드를 사용하세요.

playState, 타입 AnimationPlayState, 읽기 전용

이 애니메이션의 재생 상태입니다.

replaceState, 타입 AnimationReplaceState, 읽기 전용

이 애니메이션의 대체 상태입니다.

pending, 타입 boolean, 읽기 전용

이 애니메이션에 대기 중 재생 태스크대기 중 일시정지 태스크가 있으면 true를 반환합니다.

ready, 타입 Promise<Animation>, 읽기 전용

이 객체의 현재 ready promise를 반환합니다.

finished, 타입 Promise<Animation>, 읽기 전용

이 객체의 현재 finished promise를 반환합니다.

onfinish, 타입 EventHandler

finish 이벤트의 이벤트 핸들러입니다.

oncancel, 타입 EventHandler

cancel 이벤트의 이벤트 핸들러입니다.

onremove, 타입 EventHandler

remove 이벤트의 이벤트 핸들러입니다.

void cancel()

이 애니메이션으로 인한 모든 효과를 모두 제거하고 재생을 중단합니다. 이 객체에 대해 애니메이션 취소 절차를 실행합니다.

void finish()

현재 방향에서 애니메이션을 연관 효과 끝까지 진행합니다. 이 객체에 대해 애니메이션 완료 절차를 실행합니다.

DOMException of type InvalidStateError

이 애니메이션의 재생 속도가 0이거나, 재생 속도가 0 초과이고 연관 효과 끝이 무한대인 경우 발생합니다.

void play()

애니메이션 재생 또는 다시 재생을 시작합니다. play an animation 절차를 auto-rewind 플래그에 true를 넘겨 실행합니다.

void pause()

이 애니메이션의 재생을 일시정지합니다. 이 객체에 대해 애니메이션 일시정지 절차를 실행합니다.

void updatePlaybackRate(playbackRate)

이 애니메이션의 재생 속도를 비동기적으로 갱신합니다. 재생 속도 원활 갱신 절차를 실행하며, playbackRatenew playback rate로 넘깁니다.

playbackRate

갱신할 재생 속도를 지정하는 유한 실수입니다.

void reverse()

이 애니메이션의 재생 속도를 반전시키고 애니메이션 반전 절차로 재생합니다. play()와 마찬가지로, 이 메서드는 애니메이션을 일시정지 해제하며, 이미 역방향으로 완료된 애니메이션은 연관 효과의 시작으로 이동합니다.

void persist()

이 애니메이션의 대체 상태persisted로 설정합니다.

void commitStyles()

이 애니메이션의 애니메이션 효과가 생성한 효과 값을 해당 효과 타겟의 인라인 스타일에 계산된 스타일 커밋 절차로 기록합니다.

이 인터페이스의 대부분 다른 메서드와 달리, 이 메서드는 스타일 변경 이벤트(§ 6.13 모델 생명력 참고)를 트리거합니다.

계산된 스타일 커밋 절차에는 효과 값도 포함되므로, 애니메이션이 removed 상태여도 이 메서드는 애니메이션의 효과를 유지하는 데 유용합니다(§ 5.5.2 대체된 애니메이션 제거 참고). 단, 실제 애니메이션을 유지하지 않아도 됩니다.

커밋되는 값은 계산된 값이며, 애니메이션 효과가 메서드 호출 시점에 생성한 값입니다. 계산값이므로, CSS 변수 변화나 em 단위의 font-size 변화 등 컨텍스트 변화에 따라는 실시간으로 반영되지 않습니다.

채움 애니메이션의 결과를 완전히 유지하려면(§ 5.5 애니메이션 대체 참고), persist() 메서드를 사용할 수 있습니다. 단, 이렇게 하면 애니메이션이 계속 리소스를 소비합니다.

계산된 스타일 커밋애니메이션 animation에 대해 수행하려면:

  1. targets집합으로, 애니메이션 효과animation과 연결된 모든 효과 타겟을 포함합니다.

  2. target에 대해:

    1. targetstyle 속성을 가질 수 있는 요소가 아니면([CSS-STYLE-ATTR], 예를 들어 pseudo-element나 style 속성이 정의되지 않은 문서 포맷의 요소 등) throw "NoModificationAllowedError" DOMException 하고, 절차를 중단합니다.

    2. 대기 중인 스타일 변경 적용 후, target렌더링 중이 아니면 throw "InvalidStateError" DOMException 하고, 절차를 중단합니다.

      렌더링 중의 정의는 display: contents와 관련해 논의 중입니다. 본 절차에서는, display: contents 상태이고 레이아웃 박스를 가질 수 있는 요소(즉, connected이고 display: none 서브트리에 포함되지 않은 경우) 렌더링 중으로 간주합니다.

    3. inline styletargetCSS 선언 블록에서 가져옵니다. targetstyle 속성가지고 있지 않으면, inline style을 새로운 빈 CSS 선언 블록으로 하고, owner nodetarget으로 설정합니다.

    4. targeted properties를, target에 대해 애니메이션 효과animation과 연결되어 있고 해당 효과 타겟target인 경우에, 물리적 longhand 대상 속성의 집합으로 설정합니다.

    5. targeted propertiesproperty에 대해:

      1. partialEffectStacktarget효과 스택의 복사본으로 설정합니다.

      2. animation대체 상태removed이면, animation과 연결되고 target을 효과 타겟으로 가지며 property를 대상 속성으로 포함하는 모든 애니메이션 효과partialEffectStack에 추가합니다.

      3. partialEffectStack에서 animation보다 합성 순서가 더 높은 애니메이션에 연결된 애니메이션 효과를 모두 제거합니다.

      4. effect valuepropertytarget의 계산된 스타일을 이용해 partialEffectStack의 결과로 계산합니다(§ 5.4.3 효과 스택 결과 계산 참고).

      5. CSS 선언 설정으로 inline stylepropertyeffect value를 기록합니다.

    6. inline style의 style 속성 갱신을 수행합니다.

6.4.1. AnimationPlayState 열거형

enum AnimationPlayState { "idle", "running", "paused", "finished" };
idle

idle play state에 해당합니다.

running

running play state에 해당합니다.

paused

paused play state에 해당합니다.

finished

finished play state에 해당합니다.

6.4.2. AnimationReplaceState 열거형

enum AnimationReplaceState { "active", "removed", "persisted" };
active

active replace state에 해당합니다.

removed

removed replace state에 해당합니다.

persisted

persisted replace state에 해당합니다.

6.5. AnimationEffect 인터페이스

애니메이션 효과는 Web Animations API에서 추상 AnimationEffect 인터페이스로 표현됩니다.

[Exposed=Window]
interface AnimationEffect {
    EffectTiming         getTiming();
    ComputedEffectTiming getComputedTiming();
    undefined            updateTiming(optional OptionalEffectTiming timing = {});
};
향후에는 any onupdate (double? progress, double currentIteration, Animatable? target, any underlyingValue)를 노출하여 애니메이션 효과를 타이밍 모델과 분리해 동작할 수 있도록 할 수도 있습니다.
getTiming()

애니메이션 효과의 지정된 타이밍 속성들을 반환합니다.

반환되는 EffectTiming 객체의 멤버와 타이밍 모델의 속성 간의 대응 관계는 EffectTiming 인터페이스를 참조하세요.

getComputedTiming()

애니메이션 효과의 계산된 타이밍 속성들을 반환합니다.

getTiming()getComputedTiming()이 반환하는 객체의 일부 속성은 동일하지만, 다음과 같이 값이 다를 수 있습니다:

참고: 향후에는 다른 타이밍 멤버도 auto와 유사한 값을 확장할 수 있습니다. 타이밍 계산 시, 허용값의 범위나 타입이 변경될 수 있으므로 getComputedTiming()을 사용하는 것이 호환성에 유리합니다.

반환값 차이 외에도, getTiming()과 비교했을 때, getComputedTiming()ComputedEffectTiming 딕셔너리에서 정의한 추가 타이밍 정보를 반환합니다.

updateTiming(timing)

애니메이션 효과의 지정된 타이밍 속성을 갱신합니다. 애니메이션 효과의 타이밍 속성 갱신 절차를 실행하며, timing 파라미터를 input으로 넘깁니다.

optional OptionalEffectTiming timing

갱신할 타이밍 속성입니다. timing에 없는 멤버에 해당하는 타이밍 속성은 수정되지 않습니다.

remove() 메서드는 효과를 부모 그룹이나 애니메이션에서 제거하는 데 사용할 수 있습니다. 1단계에서 남겨두고 애니메이션에서 효과를 제거하는 것으로만 정의할까요? [Issue #2082]

6.5.1. EffectTimingOptionalEffectTiming 딕셔너리

EffectTiming 딕셔너리는 AnimationEffect의 타이밍 속성을 나타냅니다.

OptionalEffectTiming 딕셔너리는 EffectTiming 딕셔너리의 변형으로, 일부 멤버가 존재하지 않아도 됩니다. 이는 updateTiming() 메서드에서 타이밍 속성의 델타 업데이트를 수행할 때 사용됩니다. AnimationEffect 인터페이스의 애니메이션 효과의 타이밍 속성에 적용됩니다.

dictionary EffectTiming {
    double                             delay = 0;
    double                             endDelay = 0;
    FillMode                           fill = "auto";
    double                             iterationStart = 0.0;
    unrestricted double                iterations = 1.0;
    (unrestricted double or DOMString) duration = "auto";
    PlaybackDirection                  direction = "normal";
    DOMString                          easing = "linear";
};

dictionary OptionalEffectTiming {
    double                             delay;
    double                             endDelay;
    FillMode                           fill;
    double                             iterationStart;
    unrestricted double                iterations;
    (unrestricted double or DOMString) duration;
    PlaybackDirection                  direction;
    DOMString                          easing;
};
delay, 타입 double, 기본값 0

시작 지연으로, 연결된 애니메이션시작 시간부터 활성 구간 시작까지의 밀리초 단위 시간입니다.

endDelay, 타입 double, 기본값 0

끝 지연으로, 애니메이션 효과활성 구간 종료부터 종료 시간까지의 밀리초 단위 시간입니다.

fill, 타입 FillMode, 기본값 "auto"

채움 모드로, 애니메이션 효과활성 구간 외부에서 어떻게 동작할지 정의합니다.

타이밍 계산 시, 특수 문자열 값 auto는 타이밍 모델에서 인식하는 채움 모드 중 하나로 확장됩니다:

애니메이션 효과키프레임 효과인 경우,

none채움 모드로 사용합니다.

그 밖의 경우,

both채움 모드로 사용합니다.

§ 4.6 채움 동작에서 설명한 것처럼, 무기한 채움 애니메이션 사용은 지양해야 합니다.
iterationStart, 타입 double, 기본값 0.0

애니메이션 효과반복 시작 속성으로, 0 이상의 유한 실수이며 애니메이션 효과가 시작되는 반복 인덱스 및 그 반복 내 진행도를 의미합니다.

예를 들어, 값이 0.5이면 애니메이션 효과가 첫 반복의 중간에서 시작됨을, 1.2이면 두 번째 반복의 20% 지점에서 시작됨을 의미합니다.

iterations 값은 iterationStart더해진다고 볼 수 있습니다. 예를 들어, iterationStart가 "0.5"이고 iterations가 "2"이면 반복은 두 번이지만, 시작과 끝이 반복 구간의 중간에서 이루어집니다.

iterationStart 값이 1 이상이면, iteration composite operationaccumulate일 때나, 현재 반복 인덱스가 의미 있을 때 유용합니다.

iterations, 타입 unrestricted double, 기본값 1.0

애니메이션 효과반복 횟수 속성으로, 0 이상의 실수(양의 무한대 포함)이며 애니메이션 효과를 반복할 횟수입니다.

+Infinity로 지정하면 효과가 무한 반복됩니다(단, 효과의 duration이 0이면 즉시 종료됨).

duration, 타입 (unrestricted double or DOMString), 기본값 "auto"

반복 지속 시간으로, 0 이상의 실수(양의 무한대 포함)이며 애니메이션 효과의 한 번 반복에 소요되는 시간입니다.

이 명세 레벨에서는 문자열 값 auto를 타이밍 모델 계산 및 duration 멤버 반환값에서 0으로 처리합니다. 단, 작성자가 auto를 지정하면 duration 멤버를 getTiming()에서 반환할 때 auto를 반환해야 합니다.

향후 명세 레벨에서는 그룹 효과 등에서 auto 값이 자식 효과의 duration을 포함하도록 확장될 수 있습니다.

direction, 타입 PlaybackDirection, 기본값 "normal"

애니메이션 효과재생 방향으로, 반복마다 재생이 정방향/역방향/교대로 실행될지 결정합니다.

easing, 타입 DOMString, 기본값 "linear"

타이밍 함수로, 시간 값을 스케일링하여 이징 효과를 생성합니다.

문자열의 문법은 <easing-function> 프로덕션에 정의되어 있습니다([CSS-EASING-1]).

6.5.2. FillMode 열거형

enum FillMode { "none", "forwards", "backwards", "both", "auto" };
none

채움 없음.

forwards

forwards 채움.

backwards

backwards 채움.

both

backwards 및 forwards 모두 채움.

auto

채움 없음. 이후 명세 레벨에서는 다른 종류의 애니메이션 효과에 대해 다른 동작을 할 수 있습니다.

6.5.3. PlaybackDirection 열거형

enum PlaybackDirection { "normal", "reverse", "alternate", "alternate-reverse" };
normal

모든 반복이 지정된 대로 재생됩니다.

reverse

모든 반복이 지정된 순서의 반대 방향으로 재생됩니다.

alternate

짝수 반복은 지정된 대로, 홀수 반복은 반대 방향으로 재생됩니다.

alternate-reverse

짝수 반복은 반대 방향으로, 홀수 반복은 지정된 대로 재생됩니다.

6.5.4. AnimationEffect의 타이밍 업데이트

애니메이션 효과의 타이밍 속성 업데이트effect에 대해, EffectTiming 또는 OptionalEffectTiming 객체 input을 사용해 다음 절차를 수행합니다:

  1. inputiterationStart 멤버가 존재하고 0 미만이면, TypeError를 발생시키고 절차를 중단합니다.

    참고: TypeError를 사용하는 이유는 RangeError가 아닌 WebIDL의 [EnforceRange] 어노테이션의 동작을 반영하기 위함이며, 향후 부동소수점 값에도 적용될 수 있습니다.

  2. inputiterations 멤버가 존재하며, 0 미만이거나 NaN이면 TypeError를 발생시키고 절차를 중단합니다.

  3. inputduration 멤버가 존재하며, 0 미만이거나 NaN이면 TypeError를 발생시키고 절차를 중단합니다.

  4. inputeasing 멤버가 존재하지만 <easing-function> 프로덕션으로 파싱할 수 없으면, TypeError를 발생시키고 절차를 중단합니다.

  5. input에서 존재하는 각 멤버를 아래와 같이 effect의 해당 타이밍 속성에 할당합니다:

6.5.5. ComputedEffectTiming 딕셔너리

타이밍 모델에서 계산된 타이밍 속성은 ComputedEffectTiming 딕셔너리 객체로 노출됩니다.

dictionary ComputedEffectTiming : EffectTiming {
    unrestricted double  endTime;
    unrestricted double  activeDuration;
    double?              localTime;
    double?              progress;
    unrestricted double? currentIteration;
};
endTime, 타입 unrestricted double

애니메이션 효과종료 시간(end time)은 0 로컬 시간(local time)(즉, 해당 애니메이션애니메이션과 연관되어 있다면 시작 시간(start time) 이후)부터 밀리초 단위로 표현됩니다. 이는 애니메이션 효과의 활성 구간(active interval) 마지막과 종료 지연(end delay)을 더한 값에 해당합니다.

activeDuration, 타입 unrestricted double

애니메이션 효과활성 지속 시간입니다.

localTime, 타입 double, nullable

애니메이션 효과로컬 시간입니다.

애니메이션 효과애니메이션과 연관되어 있지 않으면 null이 됩니다.

progress, 타입 double, nullable

애니메이션 효과의 현재 반복 진행도(iteration progress)입니다.

currentIteration, 타입 unrestricted double, nullable

첫 번째 반복은 0부터 시작하는 현재 반복(current iteration) 인덱스입니다.

대부분의 경우 이 값은 양의 정수입니다. 하지만, 0 지속시간 애니메이션이 무한 반복될 경우 값은 양의 Infinity가 됩니다.

미해결(unresolved) 시간과 마찬가지로, 현재 반복(current iteration)이 미해결 상태라면 null 값으로 표현됩니다.

6.6. KeyframeEffect 인터페이스

키프레임 효과KeyframeEffect 인터페이스로 표현됩니다.

[Exposed=Window]
interface KeyframeEffect : AnimationEffect {
    constructor(Element? target,
                object? keyframes,
                optional (unrestricted double or KeyframeEffectOptions) options = {});
    constructor(KeyframeEffect source);
    attribute Element?           target;
    attribute CSSOMString?       pseudoElement;
    attribute CompositeOperation composite;
    sequence<object> getKeyframes();
    undefined        setKeyframes(object? keyframes);
};
KeyframeEffect (target, keyframes, options)

아래 절차에 따라 새로운 KeyframeEffect 객체를 생성합니다:

  1. 새로운 KeyframeEffect 객체 effect를 생성합니다.

  2. effect타겟 요소target으로 설정합니다.

  3. 타겟 의사 선택자를 아래 조건 중 처음 일치하는 결과로 설정합니다.

    만약 optionsKeyframeEffectOptions 객체이고 pseudoElement 속성을 가진 경우,

    타겟 의사 선택자pseudoElement 속성 값으로 설정합니다.

    이 속성을 설정할 때, 인터페이스의 pseudoElement setter에 정의된 예외 처리가 적용됩니다. 만약 setter에서 예외를 발생시켜야 한다면, 이 절차도 동일한 예외를 발생시키고 이후 모든 단계를 중단해야 합니다.

    그 밖의 경우,

    타겟 의사 선택자null로 설정합니다.

  4. timing input을 아래 조건 중 처음 일치하는 결과로 설정합니다.

    만약 optionsKeyframeEffectOptions 객체인 경우,

    timing inputoptions로 설정합니다.

    그 밖의 경우(optionsdouble인 경우),

    timing input을 모든 멤버가 기본값이고 duration 값만 options으로 설정된 새로운 EffectTiming 객체로 설정합니다.

  5. effect에 대해 timing input을 사용하여 애니메이션 효과의 타이밍 속성 업데이트 절차를 호출합니다.

    만약 해당 절차에서 예외가 발생하면, 예외를 전파하고 이 절차를 중단합니다.

  6. 만약 optionsKeyframeEffectOptions 객체라면, effectcomposite 속성을 options의 해당 값으로 할당합니다.

    이 속성을 할당할 때, KeyframeEffect 인터페이스의 setter에 정의된 예외 처리가 적용됩니다. 만약 setter가 options의 값에 대해 예외를 발생시켜야 한다면, 동일한 예외를 발생시키고 절차를 중단해야 합니다.

  7. 키프레임 집합을 setKeyframes() 절차를 keyframes 인자로 호출하여 초기화합니다.

Element? target

타겟 요소. 특정 요소를 타겟하지 않는 애니메이션에서는 null일 수 있습니다.

object? keyframes

사용할 키프레임 집합. 이 인자의 형식과 처리 방법은 § 6.6.3 키프레임 인자 처리에서 정의됩니다.

optional KeyframeEffectOptions options

효과의 반복 지속 시간을 지정하는 숫자 또는 효과의 타이밍 및 동작을 지정하는 속성 집합입니다.

이 생성자의 사용 예시는 § 6.6.1 새로운 KeyframeEffect 객체 생성에서 확인할 수 있습니다.

KeyframeEffect (source)

아래 절차에 따라 KeyframeEffect 객체를 새로 생성하며, source 와 동일한 속성을 갖습니다:

  1. KeyframeEffect 객체 effect를 생성합니다.

  2. effect의 다음 속성을 source의 해당 값으로 설정합니다:

    참고: KeyframeEffect(target, keyframes, options) 생성자와 달리, source에 지정된 타이밍 속성은 유효하다고 간주할 수 있으므로 예외를 다시 발생시킬 필요가 없습니다.

KeyframeEffect source

키프레임 효과를 정의할 속성을 복사할 키프레임 효과.

target, 타입 Element, nullable

이 객체가 애니메이션하는 타겟 요소입니다 (만약 효과 타겟Element인 경우 또는 의사 요소라면 기원 요소). 오디오 API 등 특정 요소가 없는 애니메이션에서는 null일 수 있습니다.

pseudoElement, 타입 CSSOMString, nullable

타겟 의사 선택자. 효과 타겟이 없거나 효과 타겟이 요소(즉, 의사 요소가 아닌 경우)라면 null입니다. 효과 타겟이 의사 요소라면, 해당 의사 요소 선택자(예: ::before)를 지정합니다.

설정 시, 애니메이션 효과타겟 의사 선택자를 제공된 값으로 설정하며, 다음 예외를 적용합니다:

  • 값이 null이 아니고 <pseudo-element-selector>로서 올바르지 않으면, 사용자 에이전트는 DOMException (에러 이름 SyntaxError) 을 발생시키고 애니메이션 효과타겟 의사 선택자는 변경하지 않습니다.

    참고, 이 컨텍스트에서 invalid는 invalid selector 정의를 따릅니다. 즉, 문법적으로 잘못된 의사 요소와 사용자 에이전트가 지원하지 않는 의사 요소 모두 invalid로 간주됩니다.

  • 레거시 Selectors Level 2 단일 콜론 선택자(':before', ':after', ':first-letter', ':first-line')가 지정된 경우, 타겟 의사 선택자는 동등한 2콜론 선택자(e.g. '::before')로 설정해야 합니다.

composite, 타입 CompositeOperation

키프레임 효과효과 스택과 합성하는 데 사용하는 합성 연산입니다. CompositeOperation 열거형 값 중 하나로 지정합니다.

설정 시, 제공된 값으로 이 애니메이션 효과합성 연산 속성을 설정합니다.

sequence<object> getKeyframes()

이 효과를 구성하는 키프레임들과 각 키프레임의 계산된 키프레임 오프셋을 반환합니다.

이 섹션은 규범적이지 않습니다

이 메서드의 결과는 아래 형식의 객체 시퀀스입니다:

dictionary ComputedKeyframe {
    // ... property-value pairs ...
    // i.e. DOMString propertyName
    double?                  offset = null;
    double                   computedOffset;
    DOMString                easing = "linear";
    CompositeOperationOrAuto composite = "auto";
};

각 멤버의 의미와 값은 아래와 같습니다:

offset

키프레임 오프셋 값으로, 0.0~1.0 사이의 숫자 또는 null입니다.

해당 키프레임이 인접 키프레임 간 자동 간격 지정일 경우 null이 됩니다.

computedOffset

키프레임계산된 키프레임 오프셋으로, 키프레임 오프셋 누락 계산 절차에서 산출됩니다.

offset과 달리 computedOffset은 절대 null이 아닙니다.

easing

이 키프레임부터 다음 키프레임까지 시간 진행을 변환하는 데 사용하는 타이밍 함수입니다.

composite

이 키프레임의 값과 기저 값을 결합하는 데 사용하는 키프레임별 합성 연산입니다.

만약 키프레임 효과합성 연산을 사용하는 경우, 이 멤버는 auto입니다.

키프레임은 현재 WebIDL로 완전히 표현할 수 없는 부분적으로 열린 딕셔너리 타입이므로, 이 메서드 결과 준비 절차는 아래와 같이 서술됩니다:

  1. result를 빈 객체 시퀀스로 초기화합니다.

  2. keyframes를 아래 중 하나로 설정합니다:

    1. 키프레임 효과CSSAnimation과 연결되어 있고, 키프레임setKeyframes() 성공 호출로 대체되지 않은 경우; 해당 키프레임 효과계산된 키프레임.

    2. 그 외에는, 이 키프레임 효과키프레임에 대해 키프레임 오프셋 누락 계산 절차를 적용한 결과.

    참고: CSS 애니메이션의 경우, 모든 CSS 지정 키프레임이 딕셔너리로 표현될 수는 없으므로 계산된 키프레임을 반환합니다.

  3. keyframe에 대해 다음 단계를 수행합니다:

    1. 아래 정의에 따라 딕셔너리 객체 output keyframe을 초기화합니다:

      dictionary BaseComputedKeyframe {
           double?                  offset = null;
           double                   computedOffset;
           DOMString                easing = "linear";
           CompositeOperationOrAuto composite = "auto";
      };
      
    2. output keyframeoffset, computedOffset, easing, composite 멤버를 각각 키프레임 오프셋, 계산된 키프레임 오프셋, 키프레임별 타이밍 함수, 키프레임별 합성 연산 값으로 설정합니다.

    3. keyframe의 각 애니메이션 속성-값 쌍 declaration에 대해:

      1. property namedeclaration의 속성명에 애니메이션 속성명 → IDL 속성명 알고리즘을 적용한 결과로 합니다.

      2. IDL valuedeclarationCSS 값 직렬화 알고리즘에 넘겨서 직렬화한 결과로 합니다.

      3. valueDOMString → ECMAScript String 변환IDL value를 넘긴 결과로 합니다.

      4. output keyframeproperty name 이름으로 value를 [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true, [[Value]]: value 설정하여 [[DefineOwnProperty]] 내부 메서드를 Boolean flag false와 함께 호출합니다.

    4. output keyframeresult에 추가합니다.

  4. result를 반환합니다.

void setKeyframes(object? keyframes)

이 효과를 구성하는 키프레임 집합을 대체합니다.

object? keyframes

키프레임 시퀀스. 형식과 처리 방법은 § 6.6.3 키프레임 인자 처리에서 정의됩니다.

이 효과의 키프레임 집합은 키프레임 인자 처리 절차를 수행한 결과로 대체됩니다. 만약 해당 절차에서 예외가 발생하면, 이 효과의 키프레임은 변경되지 않습니다.

6.6.1. KeyframeEffect 객체 생성하기

이 섹션은 규범적이지 않습니다

KeyframeEffect 생성자는 새로운 KeyframeEffect 객체를 만드는 여러 방식을 제공합니다.

가장 단순하게, KeyframeEffect 객체로 elem의 "left" 속성을 3초 동안 100px로 변경하려면 다음과 같이 작성할 수 있습니다:

var effect = new KeyframeEffect(elem, { left: '100px' }, 3000);

두 번째 파라미터(키프레임 목록)는 여러 속성을 지정할 수 있습니다. (§ 6.6.3 키프레임 인자 처리 참고)

// 여러 속성을 한 번에 지정
var effectA = new KeyframeEffect(elem, { left: '100px', top: '300px' }, 3000);

// 여러 키프레임 지정
var effectB = new KeyframeEffect(elem, [ { left: '100px' }, { left: '300px' } ], 3000);

세 번째 파라미터(애니메이션 타이밍)는 위처럼 밀리초 단위의 반복 지속 시간 숫자일 수도 있고, 시작 지연 등 추가 타이밍 속성을 지정하려면 다음처럼 EffectTiming 객체를 사용할 수도 있습니다:

var effect =
  new KeyframeEffect(elem, { left: '100px' }, { duration: 3000, delay: 2000 });

duration을 지정하지 않으면 0이 사용됩니다. 보간 없이 속성만 설정하는 애니메이션도 아래처럼 만들 수 있습니다:

var effect =
  new KeyframeEffect(elem, { visibility: 'hidden' }, { fill: 'forwards' });

§ 4.6 채움 동작에서 설명한 것처럼, 이런 식의 무한 채움 애니메이션 사용은 권장하지 않습니다.

KeyframeEffect 객체를 생성했다면, Animation 에 추가한 뒤 재생할 수 있습니다. 간단한 효과에는 Element.animate 단축 메서드가 더 편리합니다. 이 메서드는 위 과정을 자동으로 수행합니다. 예를 들면,

elem.animate({ left: '100px' }, 3000);

6.6.2. 속성 이름과 IDL 이름

애니메이션 속성명 → IDL 속성명 알고리즘은 property에 대해 아래와 같습니다:

  1. property<custom-property-name> 프로덕션을 따를 경우, property를 반환합니다.

  2. property가 CSS float 속성인 경우, "cssFloat" 문자열을 반환합니다.

  3. property가 CSS offset 속성인 경우, "cssOffset" 문자열을 반환합니다.

  4. 그 밖의 경우, CSS 속성 → IDL 속성 알고리즘([CSSOM])을 property에 적용한 결과를 반환합니다.

IDL 속성명 → 애니메이션 속성명 알고리즘은 attribute에 대해 아래와 같습니다:

  1. attribute<custom-property-name> 프로덕션을 따를 경우, attribute를 반환합니다.

  2. attribute가 "cssFloat" 문자열이면, CSS float 속성을 나타내는 애니메이션 속성을 반환합니다.

  3. attribute가 "cssOffset" 문자열이면, CSS offset 속성을 나타내는 애니메이션 속성을 반환합니다.

  4. 그 밖의 경우, IDL 속성 → CSS 속성 알고리즘([CSSOM])을 attribute에 적용한 결과를 반환합니다.

6.6.3. keyframes 인자 처리

이 섹션은 규범적이지 않습니다

아래 메서드는 모두 키프레임 집합을 인자로 받습니다:

이 인자는 아래 두 가지 형식 중 하나로 지정할 수 있습니다:

// 아래 두 표현식은 동일 결과를 만듭니다:
elem.animate([ { color: 'blue' },
               { color: 'green' },
               { color: 'red' },
               { color: 'yellow' } ], 2000);
elem.animate({ color: [ 'blue', 'green', 'red', 'yellow' ] }, 2000);

// 여러 속성 애니메이션의 경우 아래 두 표현도 동등합니다:
elem.animate([ { color: 'blue', left: '0px' },
               { color: 'green', left: '-20px' },
               { color: 'red', left: '100px' },
               { color: 'yellow', left: '50px'} ], 2000);
elem.animate({ color: [ 'blue', 'green', 'red', 'yellow' ],
               left: [ '0px', '-20px', '100px', '50px' ] }, 2000);

// 참고로 아래 세 표현식도 모두 동일합니다:
elem.animate([ { color: 'red' } ], 1000);
elem.animate({ color: [ 'red' ] }, 1000);
elem.animate({ color: 'red' }, 1000);

첫 번째 형식(배열형)은 각 키프레임이 애니메이션 속성당 최대 하나의 값을 지정하는 키프레임 배열입니다. 두 번째 형식(객체형)은 각 애니메이션 속성이 단일 값 또는 값 배열을 지정하는 객체입니다.

첫 번째 배열형이 표준 형식이며, getKeyframes() 메서드가 반환하는 형식입니다.

키프레임 오프셋도 아래와 같이 두 형식 중 하나로 지정할 수 있습니다:

// 오프셋 없는 키프레임은 자동으로 오프셋이 할당됨
// 첫 키프레임은 0, 중간은 0.65, 마지막은 1로 계산됨.
elem.animate([ { color: 'blue' },
               { color: 'green', offset: 0.5 },
               { color: 'red' },
               { color: 'yellow', offset: 0.8 },
               { color: 'pink' } ], 2000);

// 아래도 동일한 결과. 마지막 값은 명시할 필요 없이 자동으로 'null'로 처리됨.
elem.animate({ color: [ 'blue', 'green', 'red', 'yellow', 'pink' ],
               offset: [ null, 0.5, null, 0.8 ] }, 2000);

마찬가지로 타이밍 함수키프레임별 합성 연산도 두 형식 중 하나로 지정할 수 있습니다. 배열형은 각 키프레임마다 다른 값을 지정할 수 있고, 객체형은 값 리스트가 반복되어 모든 키프레임에 값이 할당될 때까지 이어집니다.

// 타이밍 함수는 _키프레임 사이_에 적용되므로 마지막 키프레임에 지정해도 무시됨.
elem.animate([ { color: 'blue', easing: 'ease-in' },
               { color: 'green', easing: 'ease-out' },
               { color: 'yellow' } ], 2000);

// 아래도 동일 결과.
elem.animate({ color: [ 'blue', 'green', 'yellow' ],
               easing: [ 'ease-in', 'ease-out' ] }, 2000);

// 반복 동작 덕분에 모든 키프레임에 동일 값 할당도 간단:
elem.animate({ color: [ 'blue', 'green', 'yellow' ],
               easing: 'ease-in-out' }, 2000);

두 형식 모두의 easing 속성은 키프레임별 타이밍 함수를 설정한다는 점에 유의하세요. 이는 KeyframeEffectOptions 오브젝트(또는 KeyframeAnimationOptions 오브젝트, animate() 메서드 사용시 Animatable 믹스인 인터페이스에서)로 지정하는 전체 타이밍 함수와는 별개의 것입니다. 반복 지속 시간에 적용되는 함수와는 다릅니다.

아래 예시에서 두 문장은 서로 다른 결과를 산출합니다.

// 이 경우, 'ease-in-out'이 각 color 값 사이에 적용됨.
elem.animate({ color: [ 'blue', 'green', 'yellow' ],
               easing: 'ease-in-out' }, 2000);

// 반면, 이 경우는 'ease-in-out'이 애니메이션 전체(즉 'blue'~'yellow')에 적용됨.
elem.animate({ color: [ 'blue', 'green', 'yellow' ] },
             { duration: 2000, easing: 'ease-in-out' });

keyframes 인자의 타입은 부분적으로 열린 딕셔너리 타입에 의존하므로 WebIDL로 표현할 수 없습니다.

개념적으로, 이 인자의 타입은 아래 WebIDL 유사 정의와 동일합니다:

dictionary Keyframe {
    // ... property-value pairs ...
    // i.e. DOMString propertyName
    double?                   offset = null;
    DOMString                 easing = "linear";
    CompositeOperationOrAuto  composite = "auto";
};

dictionary PropertyIndexedKeyframes {
    // ... property-value and property-valuelist pairs ...
    // i.e. (DOMString or sequence&lt;DOMString&gt;) propertyName
    (double? or sequence<double?>)                         offset = [];
    (DOMString or sequence<DOMString>)                     easing = [];
    (CompositeOperationOrAuto or sequence<CompositeOperationOrAuto>) composite = [];
};

typedef (sequence<Keyframe> or PropertyIndexedKeyframes) KeyframeArgument;

각 인자의 의미와 허용 값은 다음과 같습니다:

offset

키프레임 오프셋 값으로, 키프레임의 0.0~1.0 사이 숫자 또는 null입니다.

null 값은 키프레임이 인접 키프레임 사이에 자동 간격으로 배치됨을 의미합니다.

오프셋이 [0.0, 1.0] 범위 밖이면 TypeError가 발생합니다.

오프셋을 지정한 키프레임은 오프셋이 증가하는 순서로 제공해야 합니다. 인접하고 동일한 오프셋은 허용됩니다.

easing

타이밍 함수로, 해당 키프레임에서 다음 키프레임까지 시간 진행 변환에 사용됩니다.

문자열 파싱 구문 및 오류 처리는 easing attribute, EffectTiming 인터페이스와 동일합니다.

composite

키프레임별 합성 연산으로, 해당 키프레임 값과 기저 값을 결합합니다.

auto인 경우, 키프레임 효과에 지정된 합성 연산을 사용합니다.

이 타입은 WebIDL로 표현할 수 없으므로 처리 절차는 다음 서술로 정의됩니다.

keyframes 인자를 받는 각 메서드는 입력값에 대해 키프레임 인자 처리 절차를 실행하고, 그 결과를 저장합니다.

우선 두 가지 보조 정의를 제시합니다.

명령 완료 레코드 확인result가 ECMAScript 연산 호출의 완료 레코드일 때, 다음 단계와 같습니다:

  1. result갑작스런 완료라면, result의 [[value]] 필드의 예외를 throw하고 절차를 중단합니다.

    [[type]]이 break, continue, return일 때 어떻게 해야 할까요? 해당 경우가 있을까요?

  2. result를 그 [[value]] 필드 값으로 대체합니다.

키프레임 유사 객체 처리 절차는 두 인자를 받습니다:

그리고 아래 절차를 사용하여 false일 때는 속성명을 DOMString 값으로, true일 때는 속성명을 DOMString 값 시퀀스로 매핑하는 맵을 반환합니다:

  1. ECMAScript 값을 딕셔너리 타입으로 변환 절차를 keyframe input에 대해 실행합니다. allow lists 값에 따라 딕셔너리 타입은 아래와 같습니다:

    만약 allow lists가 true라면,

    딕셔너리 타입은 아래와 같습니다:

    dictionary BasePropertyIndexedKeyframe {
        (double? or sequence<double?>)                         offset = [];
        (DOMString or sequence<DOMString>)                     easing = [];
        (CompositeOperationOrAuto or sequence<CompositeOperationOrAuto>) composite = [];
    };
    
    그 밖의 경우,

    아래 딕셔너리 타입 사용:

    dictionary BaseKeyframe {
        double?                  offset = null;
        DOMString                easing = "linear";
        CompositeOperationOrAuto composite = "auto";
    };
    

    이 절차 결과를 keyframe output으로 저장합니다.

  2. 아래와 같이 animatable properties 리스트를 만듭니다:

    1. animatable properties를 구현체에서 애니메이션 가능한 속성(애니메이션 가능한 longhand 하위 속성이 있는 shorthand 포함) 이름 리스트로 만듭니다.

    2. 각 속성명을 애니메이션 속성명 → IDL 속성명 알고리즘으로 변환합니다.

  3. input propertiesEnumerableOwnNames 연산에 keyframe input을 넘겨 얻습니다.

  4. animation properties 리스트는 input propertiesanimatable properties 모두에 포함된 속성, 또는 input properties에 포함되어 있고 <custom-property-name> 프로덕션을 만족하는 속성으로 구성합니다.

  5. animation properties를 각 속성명의 Unicode 코드포인트 오름차순으로 정렬합니다.

  6. property name에 대해,

    1. raw value[[Get]] 내부 메서드에 keyframe inputproperty name을 넘겨 얻습니다.

    2. raw value에 대해 완료 레코드 확인을 수행합니다.

    3. raw value를 DOMString 또는 DOMString 시퀀스 property values로 변환합니다:

      만약 allow lists가 true라면,

      property valuesECMAScript 값 → IDL 값 변환 절차로 (DOMString or sequence<DOMString>) 타입으로 변환합니다.

      단일 DOMString이면, 그 값만 포함하는 DOMString 시퀀스로 대체합니다.

      그 밖의 경우,

      raw valueECMAScript 값 → DOMString 변환 절차로 변환합니다.

    4. normalized property nameIDL 속성명 → 애니메이션 속성명 알고리즘을 property name에 적용한 결과로 합니다.

    5. keyframe outputnormalized property name 이름으로 property values를 속성값으로 추가합니다.

  7. keyframe output을 반환합니다.

키프레임 인자 처리 절차는 nullable ECMAScript 객체 object를 받아 아래 절차로 키프레임 시퀀스를 반환합니다:

  1. object가 null이면 빈 키프레임 시퀀스를 반환합니다.

  2. processed keyframes를 빈 키프레임 시퀀스로 초기화합니다.

  3. methodGetMethod(object, @@iterator) 결과로 설정합니다.

  4. method에 대해 완료 레코드 확인을 수행합니다.

  5. 아래 조건 중 처음 일치하는 것에 대해 단계 수행:

    methodundefined가 아니라면,
    1. iterGetIterator(object, method)로 설정합니다.

    2. iter에 대해 완료 레코드 확인을 수행합니다.

    3. 반복:

      1. nextIteratorStep(iter)로 설정합니다.

      2. next에 대해 완료 레코드 확인을 수행합니다.

      3. next가 false이면 반복 종료.

      4. nextItemIteratorValue(next)로 설정합니다.

      5. nextItem에 대해 완료 레코드 확인을 수행합니다.

      6. Type(nextItem) 값이 Undefined, Null, Object가 아니면 TypeError를 throw하고 단계 중단.

      7. processed keyframes키프레임 유사 객체 처리 절차(nextItem, allow lists=false) 결과를 추가합니다.

    그 밖의 경우,
    1. property-indexed keyframe키프레임 유사 객체 처리 절차(object, allow lists=true) 결과로 설정합니다.

    2. property-indexed keyframe의 각 멤버 m에 대해:

      1. property namem의 키로 합니다.

      2. property name이 "composite", "easing", "offset" 중 하나면 이 루프의 남은 단계 건너뛰고 다음 멤버로 계속.

      3. property valuesm의 값으로 합니다.

      4. property keyframes를 빈 키프레임 시퀀스로 초기화합니다.

      5. property values의 값 v에 대해:

        1. null 키프레임 오프셋을 가진 새 키프레임 k 생성.

        2. kproperty namev 속성-값 쌍 추가.

        3. property keyframesk 추가.

      6. 키프레임 오프셋 누락 계산 절차를 property keyframes에 적용.

      7. property keyframes키프레임processed keyframes에 추가.

    3. processed keyframes를 각 키프레임계산된 키프레임 오프셋 오름차순으로 정렬합니다.

    4. 인접 키프레임계산된 키프레임 오프셋이 같으면 병합.

    5. offsetsproperty-indexed keyframe의 "offset" 멤버 타입에 따라 할당:

      sequence<double?>,

      "offset"의 값을 그대로 사용.

      double?,

      길이 1의 시퀀스에 "offset" 값을 단일 아이템으로, 즉 « offset ».

    6. offsets의 각 값을 processed keyframes에서 해당 위치 키프레임 오프셋에 할당.

    7. easingsproperty-indexed keyframe의 "easing" 멤버 타입에 따라 할당:

      sequence<DOMString>,

      "easing" 값을 그대로 사용.

      DOMString,

      길이 1의 시퀀스에 "easing" 값을 단일 아이템으로, 즉 « "easing" ».

    8. easings이 빈 시퀀스면 « "linear" »를 단일 값으로 함.

    9. easingsprocessed keyframes보다 아이템 수가 적으면, 앞에서부터 반복해 processed keyframes 길이만큼 채움.

      예: processed keyframes가 5이고 easings가 « "ease-in", "ease-out" »이면, « "ease-in", "ease-out", "ease-in", "ease-out", "ease-in" »로 반복됨.
    10. easingsprocessed keyframes보다 길면 남는 아이템을 unused easings로 저장.

    11. easings의 각 값을 processed keyframes의 해당 위치 키프레임의 "easing" 속성에 할당.

    12. property-indexed keyframe의 "composite" 멤버가 빈 시퀀스가 아니라면:

      1. composite modes를 "composite" 멤버의 타입에 따라 CompositeOperationOrAuto 시퀀스로 할당. 단일 값이면 길이 1 시퀀스로.

      2. composite modesprocessed keyframes보다 짧으면 반복해 채움.

      3. auto가 아닌 각 값을 processed keyframes의 해당 위치 키프레임의 키프레임별 합성 연산에 할당.

  6. processed keyframes오프셋 기준 느슨한 정렬이 아니면, TypeError를 throw하고 중단.

  7. 만약 processed keyframes 내에 키프레임키프레임 오프셋이 null이 아니고 0 미만이나 1 초과이면 TypeError를 throw하고 중단.

  8. frame에 대해:

    1. 각 속성-값 쌍을 해당 속성의 문법으로 파싱. 값이 문법에 맞지 않으면 버림. 오류 진단 지원시 사용자 에이전트는 경고를 제공해야 함.

    2. frame타이밍 함수를 "easing" 속성을 easing 문법으로 파싱한 결과로 설정. 파싱 실패시 TypeError throw 및 중단.

      참고: 위 두 단계 모두 CSS 파서를 사용하므로 CSS 주석/이스케이프는 허용되지만 성공 시 값에 남지 않습니다.

      참고: "easing" 속성 파싱 실패 시, TypeErrorobject의 모든 속성 읽기 이후에 throw되어야 하며, 나중에 부분적으로 열린 딕셔너리가 WebIDL에서 지원될 때와 동작이 달라지지 않도록 해야 합니다.

  9. unused easings의 각 값도 easing 문법으로 파싱. 실패시 TypeError throw 및 중단.

    이 단계는 아래 모든 경우에 일관적으로 TypeError를 throw하기 위해 필요합니다:

    elem.animate({ easing: 'invalid' });
    elem.animate({ easing: ['invalid'] });
    elem.animate([{ easing: 'invalid' }]);
    

6.6.4. KeyframeEffectOptions 딕셔너리

추가적인 파라미터는 KeyframeEffect(target, keyframes, options) 생성자에 KeyframeEffectOptions 객체를 제공하여 전달할 수 있습니다.

dictionary KeyframeEffectOptions : EffectTiming {
    CompositeOperation composite = "replace";
    CSSOMString?       pseudoElement = null;
};
composite, 타입 CompositeOperation, 기본값 "replace"

이 애니메이션을 효과 스택과 합성할 때 사용하는 합성 연산으로, CompositeOperation 열거형 값 중 하나로 지정합니다. auto 키프레임별 합성 연산을 지정한 모든 키프레임에 적용됩니다.

pseudoElement, 타입 CSSOMString, nullable, 기본값 null

타겟 요소에 대해 효과 타겟을 지정할 때 사용하는 의사 요소 선택자(유효하거나 null이어야 함)입니다.

6.7. CompositeOperationCompositeOperationOrAuto 열거형

키프레임 효과의 합성 동작에 사용할 수 있는 값은 CompositeOperation 열거형으로 표현됩니다.

enum CompositeOperation { "replace", "add", "accumulate" };
replace

replace 합성 연산 값에 해당하며, 애니메이션 효과가 합성 대상 기저 값을 덮어씁니다.

add

add 합성 연산 값에 해당하며, 애니메이션 효과가 합성 대상 기저 값더해집니다.

accumulate

accumulate 합성 연산 값에 해당하며, 애니메이션 효과가 합성 대상 기저 값누적됩니다.

키프레임의 합성 동작에 사용할 수 있는 값은 CompositeOperation 열거형의 값과 추가적으로 auto 값을 포함합니다.

enum CompositeOperationOrAuto { "replace", "add", "accumulate", "auto" };
auto

연결된 키프레임 효과합성 연산을 사용함을 나타냅니다.

6.8. Animatable 인터페이스 믹스인

KeyframeEffect 객체의 타겟이 될 수 있는 객체는 Animatable 인터페이스 믹스인을 구현합니다.

interface mixin Animatable {
    Animation           animate(object? keyframes,
                                optional (unrestricted double or KeyframeAnimationOptions) options = {});
    sequence<Animation> getAnimations(optional GetAnimationsOptions options = {});
};

dictionary KeyframeAnimationOptions : KeyframeEffectOptions {
    DOMString id = "";
    AnimationTimeline? timeline;
};

dictionary GetAnimationsOptions {
    boolean subtree = false;
};
Animation animate(keyframes, options)

아래 순서로 동작합니다:

  1. target을 이 메서드를 호출한 객체로 설정합니다.

  2. target관련 Realm에서 KeyframeEffect 객체 effect를 생성합니다. KeyframeEffect(target, keyframes, options) 생성자와 동일 절차를 사용하며, target, keyframes, options 인자를 전달합니다.

    이 절차에서 예외가 발생하면 예외를 전파하고 중단합니다.

  3. optionsKeyframeAnimationOptions 객체이면, timelineoptionstimeline 멤버 값으로, 없으면 이 메서드를 호출한 요소의 기본 문서 타임라인으로 설정합니다.

  4. target관련 Realm에서 Animation 객체 animation을 생성합니다. Animation() 생성자와 동일 절차를 사용하며, effecttimeline을 인자로 넘깁니다.

  5. optionsKeyframeAnimationOptions 객체이면, optionsid 값을 animationid 속성에 할당합니다.

  6. animation에 대해 애니메이션 재생 절차를 auto-rewind 플래그 true로 실행합니다.

  7. animation을 반환합니다.

이 섹션은 규범적이지 않습니다

아래 코드 예시는:

var animation = elem.animate({ opacity: 0 }, 2000);

다음과 거의 동일합니다:

var effect = new KeyframeEffect(elem, { opacity: 0 }, 2000);
var animation = new Animation(effect, elem.ownerDocument.timeline);
animation.play();
keyframes

사용할 키프레임 집합. 이 값은 KeyframeEffect(target, keyframes, options) 생성자의 keyframes 파라미터로 전달되며, 해당 생성자의 정의와 동일하게 해석됩니다.

options

생성된 KeyframeEffectAnimation 의 타이밍 및 애니메이션 옵션입니다.

sequence<Animation> getAnimations(options)

이 객체에 대해 관련 애니메이션 집합을 반환하거나, options 파라미터에서 subtree 값이 true일 경우, 이 객체에 대해 서브트리 관련 애니메이션 집합을 반환합니다.

반환된 리스트는 애니메이션의 합성 순서에 따라 정렬되며, § 5.4.2 효과 스택을 참고하세요.

이 메서드를 호출하면 스타일 변경 이벤트타겟 요소에 발생합니다. 따라서 반환된 리스트는 애니메이션 관련 스타일 속성 등 아직 처리되지 않은 대기 중 스타일 변경 적용 이후 상태를 반영합니다.

options

getAnimations() 로 반환되는 애니메이션 집합을 제어하는 파라미터입니다.

id, 타입 DOMString, 기본값 ""

생성된 Animationid 속성에 할당할 문자열입니다.

timeline, 타입 AnimationTimeline, nullable

존재할 경우, 새로 생성된 애니메이션에 연결할 타임라인을 지정합니다.

subtree, 타입 boolean, 기본값 false

true일 경우, 이 객체에 대해 애니메이션애니메이션 효과와 연결되어 있고, 타겟 요소가 이 객체의 자식인 경우 결과에 포함됩니다.

6.9. Document 인터페이스 확장

아래 확장들은 Document 인터페이스([DOM] 정의)에 적용됩니다.

partial interface Document {
    readonly attribute DocumentTimeline timeline;
};
timeline, 타입 DocumentTimeline, 읽기 전용

DocumentTimeline 객체로, 기본 문서 타임라인을 나타냅니다.

6.10. DocumentOrShadowRoot 인터페이스 믹스인 확장

아래 확장들은 DocumentOrShadowRoot 인터페이스 믹스인([DOM] 정의)에 적용됩니다.

partial interface mixin DocumentOrShadowRoot {
    sequence<Animation> getAnimations();
};
sequence<Animation> getAnimations()

이 메서드를 호출한 document 또는 shadow root서브트리 관련 애니메이션 집합을 반환합니다.

반환 리스트는 애니메이션의 합성 순서에 따라 정렬되며, § 5.4.2 효과 스택을 참고하세요.

이 메서드 호출은 document의 스타일 변경 이벤트를 트리거합니다. 따라서 반환 리스트는 아직 처리되지 않은 애니메이션 관련 스타일 속성 변경 등 대기 중 변경 적용 이후 상태를 반영합니다.

6.11. Element 인터페이스 확장

DOM 요소는 애니메이션의 타겟이 될 수 있으므로, Element 인터페이스([DOM])는 아래와 같이 확장됩니다:

Element includes Animatable;

이 확장으로 아래와 같이 사용할 수 있습니다.

elem.animate({ color: 'red' }, 2000);

6.12. AnimationPlaybackEvent 인터페이스

애니메이션 재생 이벤트AnimationPlaybackEvent 인터페이스로 표현됩니다.

[Exposed=Window]
interface AnimationPlaybackEvent : Event {
    constructor(DOMString type, optional AnimationPlaybackEventInit eventInitDict = {});
    readonly attribute double? currentTime;
    readonly attribute double? timelineTime;
};
dictionary AnimationPlaybackEventInit : EventInit {
    double? currentTime = null;
    double? timelineTime = null;
};
AnimationPlaybackEvent(type, eventInitDict)

이벤트 생성 절차([DOM])를 따라 새로운 AnimationPlaybackEvent 객체를 만듭니다.

currentTime, 타입 double, 읽기 전용, nullable

이벤트가 큐에 들어간 시점의 애니메이션 현재 시간 값입니다. 이벤트가 생성될 때 애니메이션idle 상태였다면 null입니다.

timelineTime, 타입 double, 읽기 전용, nullable

이벤트가 큐에 들어간 시점에 이벤트를 생성한 애니메이션이 연결된 타임라인시간 값입니다. 이벤트가 큐에 들어갈 때 애니메이션active하지 않은 타임라인과 연결되어 있었다면 null입니다.

currentTime, 타입 double, nullable, 기본값 null

currentTime 속성 설명 참고.

timelineTime, 타입 double, nullable, 기본값 null

timelineTime 속성 설명 참고.

6.13. 모델 생동성

모델의 어떤 부분이든 변경이 이루어지면 전체 타이밍 모델이 갱신되고 모든 종속된 스타일도 함께 갱신됩니다.

별도의 언급이 없는 한, 이 명세의 프로그래밍 인터페이스 섹션에서 정의된 인터페이스의 메서드 또는 생성자를 호출하거나, 멤버를 조회/설정해도 스타일 변경 이벤트(style change event)가 발생하지 않습니다.

참고: 이 명세를 확장하는 다른 명세들은 스타일 변경 이벤트가 트리거되는 상황을 추가하여 해당 이벤트에 대한 요구사항을 세분화할 것으로 예상됩니다. 예를 들어, 이 명세의 인터페이스가 CSS 마크업으로 정의된 애니메이션을 표현하는 경우, 많은 메서드들이 지정된 스타일의 변화를 반영하기 위해 스타일 변경 이벤트를 트리거해야 합니다.

이 섹션은 규범적이지 않습니다

위 요구사항과 명세의 다른 규범 요구사항에 기반하여 다음 불변식이 관찰될 수 있습니다:

Web Animations 모델에 대한 변경은 즉시 반영된다

예를 들어, KeyframeEffectAnimation 과 연관되어 있고, 프로그래밍 인터페이스를 통해 탐색(seek)될 경우(§ 4.4.4 애니메이션의 현재 시간 설정 참고), 애니메이션의 startTime을 조회하면 모델의 갱신된 상태가 즉시 반영됩니다.

// 초기에는 animation.effect.getComputedTiming().localTime 값이 3000
animation.currentTime += 2000;
alert(animation.effect.getComputedTiming().localTime); // "5000" 표시
애니메이션에 의해 영향을 받는 속성의 계산 스타일을 조회하면 애니메이션의 최신 상태가 반영된다

예를 들어, 어떤 요소에 새 Animation 을 적용한 직후에 사용 스타일을 조회하면, 새 애니메이션의 결과가 반환값에 반영됩니다.

// opacity를 즉시 0으로 설정
elem.animate({ opacity: 0 }, { fill: 'forwards' });
alert(window.getComputedStyle(elem).opacity); // "0" 표시
동일 태스크 내에서 이루어진 변경은 전체 변경 집합이 한 번에 렌더링되도록 동기화된다

모델 변경이 즉시 반영되는 것과 ECMAScript의 run-to-completion 의미론이 결합되어, 예를 들어 지정된 스타일 변화만 렌더링되고 애니메이션은 적용되지 않는 상황이 발생하지 않아야 합니다.

// Element.animate를 지원하지 않는 브라우저 대비 fallback 포함 페이드 효과
elem.style.opacity = '0';
elem.animate([ { opacity: 1 }, { opacity: 0 } ], 500);

참고: 위 예시에서 사용자 에이전트가 위 변화가 전혀 적용되지 않은 프레임을 렌더링할 수 있습니다. 예를 들어 렌더링이 별도 프로세스에서 동작하고, 위 태스크 완료 직후 렌더링이 예약되었으나 변화가 해당 프로세스로 전달되기 전에 렌더링이 이루어지는 경우가 있을 수 있습니다.

currentTime 속성으로 반환된 값은 태스크 내에서는 변하지 않는다

타임라인애니메이션 갱신 및 이벤트 전송 절차가 실행될 때마다 현재 시간을 갱신해야 하므로, 같은 스크립트 블록 내에서 currentTime을 두 번 조회해도 아래 예시처럼 값은 같습니다.

var a = document.timeline.currentTime;
// ... 많은 코드 ...
var b = document.timeline.currentTime;
alert(b - a); // "0" 표시
requestAnimationFrame 콜백에 전달된 시간은 document.timeline.currentTime과 같다

HTML의 이벤트 루프 처리 모델에서 애니메이션 갱신 및 이벤트 전송 절차가 애니메이션 프레임 콜백 실행 전에 수행된다고 정의되어 있고, 해당 콜백에 전달되는 시간(now)은 두 절차 모두에 동일하게 전달되므로, 기본 문서 타임라인현재 시간requestAnimationFrame에 전달된 시간과 일치해야 합니다.

window.requestAnimationFrame(function(now) {
  // "0" 표시
  alert(now - document.timeline.currentTime);
});
이 프로그래밍 인터페이스의 메서드를 호출해도 일반적으로 트랜지션이 트리거되지 않는다

다음 예시를 참고하세요:

// 트랜지션 시작점 설정
div.style.opacity = '1';
getComputedStyle(div).opacity;

// 트랜지션 종료점 설정
div.style.transition = 'opacity 1s';
div.style.opacity = '0';

// 애니메이션 실행
div.animate({ opacity: [0.5, 1] }, 500);

// 트랜지션 종료 대기 -- 아래는 절대 호출되지 않음!
div.addEventListener('transitionend', () => {
  console.log('transitionend');
});

이 경우 animate() 를 호출해도 스타일 변경 이벤트가 트리거되지 않습니다. 결과적으로 대기 중인 스타일 변경은 새 애니메이션으로 인한 스타일 변경과 동시에 처리됩니다. 애니메이션 스타일이 변경 전 스타일변경 후 스타일을 덮어쓰기 때문에, 트랜지션이 생성되지 않고, transitionend 이벤트 핸들러도 절대 호출되지 않습니다.

7. 미디어 프래그먼트와의 통합

Media Fragments 명세 [MEDIA-FRAGS] 는 미디어 리소스의 시간 범위를 지정하는 방법을 정의합니다. 미디어 프래그먼트의 적용은 지정된 리소스의 MIME 타입에 따라 달라집니다. SVG MIME 타입 [SVG11]의 경우, 시간 관련 파라미터의 적용은 Animation Elements 명세에서 정의됩니다.

참고: 미디어 프래그먼트는 리소스의 MIME 타입을 기준으로 동작하도록 정의되어 있습니다. 이로 인해 Web Animations 콘텐츠가 사용되는 모든 상황에서 시간 지정이 지원되지 않을 수도 있습니다.

8. 페이지 표시와의 상호작용

HTML은 사용자 에이전트가 사용자 에이전트 정의 상태세션 히스토리 엔트리와 함께 저장하도록 허용하여, 사용자가 페이지 간 이동할 때 페이지의 이전 상태(예: 스크롤 위치 [HTML])를 복구할 수 있도록 합니다.

문서가 언로드/이동될 때 미디어 요소를 일시정지/재개하는 사용자 에이전트라면, Web Animations 콘텐츠가 포함된 문서에도 일관된 처리를 적용하는 것이 권장됩니다. 이 동작이 제공되는 경우, 벽시계 시간(wallclock time)을 추적하는 타임라인시간 값을 조정하는 방식으로 구현해야 합니다.

이 방식이 시간 값navigationStart 기준이고 requestAnimationFramedocument.timeline.currentTime과 동일한 시간을 사용하는 것과 충돌하지 않는가? [Issue #2083]

9. 구현 요구사항

9.1. 시간 값의 정밀도

시간 값의 내부 표현은 구현에 따라 다르지만, 사용자 에이전트가 입력된 시간 값을 마이크로초 단위로 표현할 수 있도록 하는 것이 권장됩니다. 이렇게 하면 시간 값이(통상적으로 밀리초 단위) 0.001일 때 0.0과 구분할 수 있습니다.

9.2. 적합성 기준

이 명세는 애니메이션을 위한 추상 모델을 정의하며, 스크립팅을 지원하지 않는 사용자 에이전트의 경우 테스트 가능한 표면이 없으므로 적합성 기준이 없습니다.

스크립팅을 지원하지 않는 사용자 에이전트라 하더라도, 이 명세를 바탕으로 정의된 추가 기술을 구현할 수 있으며, 이 경우 이 명세에서 제공하는 정의가 해당 추가 기술의 적합성 기준의 일부가 됩니다.

적합한 스크립트 기반 Web Animations 사용자 에이전트§ 6 프로그래밍 인터페이스에서 정의된 API를 구현하는 사용자 에이전트를 의미합니다.

10. 감사의 글

이 명세에 기여해주신 Steve Block, Michael Giuffrida, Ryan Seys, 그리고 Eric Willigers께 감사드립니다.

또한 부드러운 타이밍 함수 제안에 대한 수식 도움을 준 Michiel "Pomax" Kamermans에게도 감사드립니다. 이 기능은 이후 명세로 연기되었습니다.

방송 애니메이션 제작 과정과 기법을 편집자에게 소개해주신 Southern Star Animation의 친절과 인내에 깊은 감사를 드립니다.

11. 최종 공개 이후 변경사항

2022년 9월 8일 Working Draft 이후 다음과 같은 변경이 이루어졌습니다:

변경 로그에서 더 자세한 변경 내역을 볼 수 있습니다.

부록 A: 기존 속성의 애니메이션 타입

일반적으로 속성의 애니메이션 타입은 정의와 함께 제공됩니다. 하지만 오래되었거나 매우 성숙한 명세에서 정의된 일부 속성에는 애니메이션 타입 정보가 포함되어 있지 않을 수 있습니다. 이러한 모든 속성은 아래 예외를 제외하고 애니메이션 타입계산값 기준으로 간주됩니다.

font-weight의 애니메이션

font-weight 속성 값은 level 4 이전에는 다음과 같이 결합됩니다:

참고: 이 정의는 [CSS-FONTS-4]에서 폐지되었으며, 여기서는 font-weight 값이 100의 배수일 필요가 없습니다. 이 경우 font-weight애니메이션 타입은 단순히 계산값 기준이 됩니다.

visibility의 애니메이션

visibility 속성의 경우, visible이산적 단계로 보간됩니다. 여기서 p 값이 0~1 사이면 visible에 맵핑되며, 그 외 값은 더 가까운 끝점에 맵핑됩니다; 두 값 모두 visible이 아니면 이산 애니메이션이 사용됩니다.

box-shadowtext-shadow의 애니메이션

box-shadow 또는 text-shadow 속성의 애니메이션은 결합 그림자 리스트 절차에 따릅니다:

리스트의 각 그림자(none은 길이 0 리스트로 간주)는 계산값 기준 동작처럼 컴포넌트별로 보간됩니다. 하지만 두 입력 그림자 모두 inset이거나 모두 inset이 아니면, 보간된 그림자도 입력 그림자와 같은 속성을 가져야 합니다. 입력 그림자 쌍 중 하나가 inset이고 다른 하나가 inset이 아니면, 전체 그림자 리스트는 이산 애니메이션을 사용합니다. 그림자 리스트의 길이가 다르면, 짧은 리스트는 끝에 transparent 색상, 모든 길이 0, 그리고 inset 속성이 긴 리스트와 맞는 그림자로 패딩됩니다.

그림자 리스트 VaVb덧셈리스트 연결로 정의되며, VresultVa 확장Vb를 연결한 값과 같습니다.

누적그림자 리스트에 대해 위 보간 규칙을 따르며, 각 컴포넌트별로 타입에 따라 덧셈을 수행하거나, inset 값이 다르면 이산 애니메이션으로 처리합니다.

적합성

문서 규약

적합성 요구사항은 설명적 주장과 RFC 2119 용어의 조합으로 표현됩니다. “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, “OPTIONAL” 등의 주요 단어는 이 문서의 규범적 부분에서 RFC 2119에 따라 해석되어야 합니다. 다만, 가독성을 위해 이 명세에서는 대문자로 표기하지 않습니다.

이 명세의 모든 텍스트는 명시적으로 비규범적임을 표시한 섹션, 예시, 노트를 제외하고 규범적입니다. [RFC2119]

이 명세의 예시는 “예를 들어(for example)”로 시작하거나, class="example"로 규범적 텍스트와 구분되어 아래와 같이 제시됩니다:

이것은 참고용 예시의 예입니다.

정보 제공용 노트는 “참고(Note)”로 시작하며 class="note"로 규범적 텍스트와 구분되어 아래와 같이 표시됩니다:

참고, 이것은 정보 제공용 노트입니다.

Advisement(권고)는 특별한 주의를 환기하도록 스타일링된 규범적 섹션으로, <strong class="advisement">으로 구분되어 아래와 같이 표시됩니다: UA는 반드시 접근 가능한 대체 수단을 제공해야 합니다.

적합성 클래스

이 명세에 대한 적합성은 세 가지 적합성 클래스로 정의됩니다:

스타일 시트
CSS 스타일 시트.
렌더러
스타일 시트의 의미를 해석하고 이를 사용하는 문서를 렌더링하는 UA.
저작 도구
스타일 시트를 작성하는 UA.

스타일 시트가 이 명세에 적합하려면, 이 모듈에서 정의한 문법을 사용하는 모든 구문이 일반 CSS 문법과 각 기능별 개별 문법에 따라 유효해야 합니다.

렌더러가 이 명세에 적합하려면, 스타일 시트를 적절한 명세에 따라 해석하는 것 외에도, 이 명세에서 정의한 모든 기능을 올바르게 파싱하고 문서를 이에 따라 렌더링해야 합니다. 단, UA가 디바이스의 한계로 인해 문서를 올바르게 렌더링하지 못해도 UA는 비적합으로 간주되지 않습니다. (예: UA가 모노크롬 모니터에서 색을 렌더링할 필요는 없음)

저작 도구가 이 명세에 적합하려면, 일반 CSS 문법과 이 모듈의 각 기능별 개별 문법에 따라 문법적으로 올바른 스타일 시트를 작성하고, 이 모듈에서 설명한 스타일 시트의 모든 기타 적합성 요구사항을 충족해야 합니다.

부분 구현

작성자가 호환성 있는 파싱 규칙을 통해 폴백 값을 지정할 수 있도록, CSS 렌더러는 지원하지 않는 모든 at-rule, 속성, 속성 값, 키워드 및 기타 구문 구조를 반드시 무효(적절히 무시)로 처리해야 합니다. 특히, 사용자 에이전트는 지원하지 않는 구성 요소 값만 선택적으로 무시하고, 단일 다중 값 속성 선언에서 지원되는 값만 적용해서는 안 됩니다: 어떤 값이라도 무효(지원하지 않는 값은 반드시 무효임)로 간주되면, CSS는 전체 선언을 무시하도록 요구합니다.

불안정 및 독점 기능 구현

향후 안정적인 CSS 기능과 충돌을 방지하기 위해, CSSWG는 최선의 구현 방법을 따를 것을 권장합니다. 불안정한 기능과 독점 확장 CSS 기능 구현 시 참고하세요.

비실험적 구현

명세가 후보 권고(Candidate Recommendation) 단계에 도달하면, 비실험적 구현이 가능해지고, 구현자는 스펙에 따라 올바르게 구현되었음을 입증할 수 있는 모든 CR 수준 기능에 대해 접두사가 없는 구현을 배포해야 합니다.

CSS 구현 간 호환성(interoperability)을 확립하고 유지하기 위해, CSS 작업 그룹은 비실험적 CSS 렌더러가 W3C에 구현 보고서(필요시 구현 보고서에 사용된 테스트 케이스도 포함)를 제출한 후에만 CSS 기능의 접두사 없는 구현을 배포할 것을 요청합니다. W3C에 제출된 테스트 케이스는 CSS 작업 그룹이 검토 및 수정할 수 있습니다.

테스트 케이스 및 구현 보고서 제출에 대한 자세한 정보는 CSS 작업 그룹 웹사이트 https://www.w3.org/Style/CSS/Test/에서 확인할 수 있습니다. 문의는 public-css-testsuite@w3.org 메일링 리스트로 보내세요.

색인

이 명세에서 정의한 용어

참조로 정의된 용어

참고 문헌

규범적 참고 문헌

[CSS-ANIMATIONS-1]
David Baron; 외. CSS Animations Level 1. 2023년 3월 2일. WD. URL: https://www.w3.org/TR/css-animations-1/
[CSS-ANIMATIONS-2]
David Baron; Brian Birtles. CSS Animations Level 2. 2023년 3월 2일. WD. URL: https://www.w3.org/TR/css-animations-2/
[CSS-BACKGROUNDS-3]
Bert Bos; Elika Etemad; Brad Kemper. CSS Backgrounds and Borders Module Level 3. 2023년 2월 14일. CR. URL: https://www.w3.org/TR/css-backgrounds-3/
[CSS-CASCADE-3]
Elika Etemad; Tab Atkins Jr.. CSS Cascading and Inheritance Level 3. 2021년 2월 11일. REC. URL: https://www.w3.org/TR/css-cascade-3/
[CSS-CASCADE-5]
Elika Etemad; Miriam Suzanne; Tab Atkins Jr.. CSS Cascading and Inheritance Level 5. 2022년 1월 13일. CR. URL: https://www.w3.org/TR/css-cascade-5/
[CSS-COLOR-4]
Tab Atkins Jr.; Chris Lilley; Lea Verou. CSS Color Module Level 4. 2022년 11월 1일. CR. URL: https://www.w3.org/TR/css-color-4/
[CSS-DISPLAY-3]
Elika Etemad; Tab Atkins Jr.. CSS Display Module Level 3. 2023년 3월 30일. CR. URL: https://www.w3.org/TR/css-display-3/
[CSS-EASING-1]
Brian Birtles; Dean Jackson; Matt Rakow. CSS Easing Functions Level 1. 2023년 2월 13일. CR. URL: https://www.w3.org/TR/css-easing-1/
[CSS-FONTS-4]
John Daggett; Myles Maxfield; Chris Lilley. CSS Fonts Module Level 4. 2021년 12월 21일. WD. URL: https://www.w3.org/TR/css-fonts-4/
[CSS-LOGICAL-1]
Rossen Atanassov; Elika Etemad. CSS Logical Properties and Values Level 1. 2018년 8월 27일. WD. URL: https://www.w3.org/TR/css-logical-1/
[CSS-PROPERTIES-VALUES-API-1]
Tab Atkins Jr.; 외. CSS Properties and Values API Level 1. 2020년 10월 13일. WD. URL: https://www.w3.org/TR/css-properties-values-api-1/
[CSS-SHADOW-PARTS-1]
Tab Atkins Jr.; Fergal Daly. CSS Shadow Parts. 2018년 11월 15일. WD. URL: https://www.w3.org/TR/css-shadow-parts-1/
[CSS-STYLE-ATTR]
Tantek Çelik; Elika Etemad. CSS Style Attributes. 2013년 11월 7일. REC. URL: https://www.w3.org/TR/css-style-attr/
[CSS-TEXT-DECOR-4]
Elika Etemad; Koji Ishii. CSS Text Decoration Module Level 4. 2022년 5월 4일. WD. URL: https://www.w3.org/TR/css-text-decor-4/
[CSS-TRANSFORMS-1]
Simon Fraser; 외. CSS Transforms Module Level 1. 2019년 2월 14일. CR. URL: https://www.w3.org/TR/css-transforms-1/
[CSS-TRANSITIONS-1]
David Baron; 외. CSS Transitions. 2018년 10월 11일. WD. URL: https://www.w3.org/TR/css-transitions-1/
[CSS-TRANSITIONS-2]
CSS Transitions Level 2 URL: https://drafts.csswg.org/css-transitions-2/
[CSS-VALUES-4]
Tab Atkins Jr.; Elika Etemad. CSS Values and Units Module Level 4. 2023년 4월 6일. WD. URL: https://www.w3.org/TR/css-values-4/
[CSS-VARIABLES-1]
Tab Atkins Jr.. CSS Custom Properties for Cascading Variables Module Level 1. 2022년 6월 16일. CR. URL: https://www.w3.org/TR/css-variables-1/
[CSS-WILL-CHANGE-1]
Tab Atkins Jr.. CSS Will Change Module Level 1. 2022년 5월 5일. CR. URL: https://www.w3.org/TR/css-will-change-1/
[CSS-WRITING-MODES-3]
Elika Etemad; Koji Ishii. CSS Writing Modes Level 3. 2019년 12월 10일. REC. URL: https://www.w3.org/TR/css-writing-modes-3/
[CSS-WRITING-MODES-4]
Elika Etemad; Koji Ishii. CSS Writing Modes Level 4. 2019년 7월 30일. CR. URL: https://www.w3.org/TR/css-writing-modes-4/
[CSS21]
Bert Bos; 외. Cascading Style Sheets Level 2 Revision 1 (CSS 2.1) 명세. 2011년 6월 7일. REC. URL: https://www.w3.org/TR/CSS21/
[CSS22]
Bert Bos. Cascading Style Sheets Level 2 Revision 2 (CSS 2.2) 명세. 2016년 4월 12일. WD. URL: https://www.w3.org/TR/CSS22/
[CSSOM]
Daniel Glazman; Emilio Cobos Álvarez. CSS 오브젝트 모델 (CSSOM). 2021년 8월 26일. WD. URL: https://www.w3.org/TR/cssom-1/
[DOM]
Anne van Kesteren. DOM 표준. 현행 표준. URL: https://dom.spec.whatwg.org/
[ECMASCRIPT]
ECMAScript 언어 명세. URL: https://tc39.es/ecma262/multipage/
[HR-TIME]
Yoav Weiss. 고해상도 시간(High Resolution Time). 2023년 4월 25일. WD. URL: https://www.w3.org/TR/hr-time-3/
[HTML]
Anne van Kesteren; 외. HTML 표준. 현행 표준. URL: https://html.spec.whatwg.org/multipage/
[INFRA]
Anne van Kesteren; Domenic Denicola. Infra 표준. 현행 표준. URL: https://infra.spec.whatwg.org/
[MEDIA-FRAGS]
Raphaël Troncy; 외. Media Fragments URI 1.0 (기본). 2012년 9월 25일. REC. URL: https://www.w3.org/TR/media-frags/
[MOTION-1]
Dirk Schulze; 외. Motion Path Module Level 1. 2018년 12월 18일. WD. URL: https://www.w3.org/TR/motion-1/
[RFC2119]
S. Bradner. 요구사항 수준을 나타내기 위한 RFC에서 사용하는 주요 단어(Key words for use in RFCs to Indicate Requirement Levels). 1997년 3월. Best Current Practice. URL: https://datatracker.ietf.org/doc/html/rfc2119
[SELECT]
Tantek Çelik; 외. Selectors Level 3. 2018년 11월 6일. REC. URL: https://www.w3.org/TR/selectors-3/
[SELECTORS-4]
Elika Etemad; Tab Atkins Jr.. Selectors Level 4. 2022년 11월 11일. WD. URL: https://www.w3.org/TR/selectors-4/
[SVG11]
Erik Dahlström; 외. Scalable Vector Graphics (SVG) 1.1 (Second Edition). 2011년 8월 16일. REC. URL: https://www.w3.org/TR/SVG11/
[SVG2]
Amelia Bellamy-Royds; 외. Scalable Vector Graphics (SVG) 2. 2018년 10월 4일. CR. URL: https://www.w3.org/TR/SVG2/
[WEB-ANIMATIONS-2]
Brian Birtles; Robert Flack. Web Animations Level 2. 2023년 2월 21일. WD. URL: https://www.w3.org/TR/web-animations-2/
[WEBIDL]
Edgar Chen、Timothy Gu。 Web IDL現行標準。現行標準。URL: https://webidl.spec.whatwg.org/

참고 문헌

[SMIL-ANIMATION]
Patrick Schmitz; Aaron Cohen. SMIL Animation. 2001년 9월 4일. REC. URL: https://www.w3.org/TR/smil-animation/

IDL 색인

[Exposed=Window]
interface AnimationTimeline {
    readonly attribute double? currentTime;
};

dictionary DocumentTimelineOptions {
  DOMHighResTimeStamp originTime = 0;
};

[Exposed=Window]
interface DocumentTimeline : AnimationTimeline {
  constructor(optional DocumentTimelineOptions options = {});
};

[Exposed=Window]
interface Animation : EventTarget {
    constructor(optional AnimationEffect? effect = null,
                optional AnimationTimeline? timeline);
             attribute DOMString                id;
             attribute AnimationEffect?         effect;
             attribute AnimationTimeline?       timeline;
             attribute double?                  startTime;
             attribute double?                  currentTime;
             attribute double                   playbackRate;
    readonly attribute AnimationPlayState       playState;
    readonly attribute AnimationReplaceState    replaceState;
    readonly attribute boolean                  pending;
    readonly attribute Promise<Animation>       ready;
    readonly attribute Promise<Animation>       finished;
             attribute EventHandler             onfinish;
             attribute EventHandler             oncancel;
             attribute EventHandler             onremove;
    undefined cancel();
    undefined finish();
    undefined play();
    undefined pause();
    undefined updatePlaybackRate(double playbackRate);
    undefined reverse();
    undefined persist();
    [CEReactions]
    undefined commitStyles();
};

enum AnimationPlayState { "idle", "running", "paused", "finished" };

enum AnimationReplaceState { "active", "removed", "persisted" };

[Exposed=Window]
interface AnimationEffect {
    EffectTiming         getTiming();
    ComputedEffectTiming getComputedTiming();
    undefined            updateTiming(optional OptionalEffectTiming timing = {});
};

dictionary EffectTiming {
    double                             delay = 0;
    double                             endDelay = 0;
    FillMode                           fill = "auto";
    double                             iterationStart = 0.0;
    unrestricted double                iterations = 1.0;
    (unrestricted double or DOMString) duration = "auto";
    PlaybackDirection                  direction = "normal";
    DOMString                          easing = "linear";
};

dictionary OptionalEffectTiming {
    double                             delay;
    double                             endDelay;
    FillMode                           fill;
    double                             iterationStart;
    unrestricted double                iterations;
    (unrestricted double or DOMString) duration;
    PlaybackDirection                  direction;
    DOMString                          easing;
};

enum FillMode { "none", "forwards", "backwards", "both", "auto" };

enum PlaybackDirection { "normal", "reverse", "alternate", "alternate-reverse" };

dictionary ComputedEffectTiming : EffectTiming {
    unrestricted double  endTime;
    unrestricted double  activeDuration;
    double?              localTime;
    double?              progress;
    unrestricted double? currentIteration;
};

[Exposed=Window]
interface KeyframeEffect : AnimationEffect {
    constructor(Element? target,
                object? keyframes,
                optional (unrestricted double or KeyframeEffectOptions) options = {});
    constructor(KeyframeEffect source);
    attribute Element?           target;
    attribute CSSOMString?       pseudoElement;
    attribute CompositeOperation composite;
    sequence<object> getKeyframes();
    undefined        setKeyframes(object? keyframes);
};

dictionary BaseComputedKeyframe {
     double?                  offset = null;
     double                   computedOffset;
     DOMString                easing = "linear";
     CompositeOperationOrAuto composite = "auto";
};

dictionary BasePropertyIndexedKeyframe {
    (double? or sequence<double?>)                         offset = [];
    (DOMString or sequence<DOMString>)                     easing = [];
    (CompositeOperationOrAuto or sequence<CompositeOperationOrAuto>) composite = [];
};

dictionary BaseKeyframe {
    double?                  offset = null;
    DOMString                easing = "linear";
    CompositeOperationOrAuto composite = "auto";
};

dictionary KeyframeEffectOptions : EffectTiming {
    CompositeOperation composite = "replace";
    CSSOMString?       pseudoElement = null;
};

enum CompositeOperation { "replace", "add", "accumulate" };

enum CompositeOperationOrAuto { "replace", "add", "accumulate", "auto" };

interface mixin Animatable {
    Animation           animate(object? keyframes,
                                optional (unrestricted double or KeyframeAnimationOptions) options = {});
    sequence<Animation> getAnimations(optional GetAnimationsOptions options = {});
};

dictionary KeyframeAnimationOptions : KeyframeEffectOptions {
    DOMString id = "";
    AnimationTimeline? timeline;
};

dictionary GetAnimationsOptions {
    boolean subtree = false;
};

partial interface Document {
    readonly attribute DocumentTimeline timeline;
};

partial interface mixin DocumentOrShadowRoot {
    sequence<Animation> getAnimations();
};

Element includes Animatable;

[Exposed=Window]
interface AnimationPlaybackEvent : Event {
    constructor(DOMString type, optional AnimationPlaybackEventInit eventInitDict = {});
    readonly attribute double? currentTime;
    readonly attribute double? timelineTime;
};
dictionary AnimationPlaybackEventInit : EventInit {
    double? currentTime = null;
    double? timelineTime = null;
};

이슈 색인

"origin time"보다 더 나은 용어가 있어야 합니다— "time origin"과 너무 유사합니다. [이슈 #2079]
특정 타이밍 함수가 있을 때 애니메이션 효과에 대한 입력 반복(progress)는 [0, 1] 범위로 제한되지 않습니다. 하지만 현재는 키프레임 offset이 반드시 [0, 1] 범위로 제한되고, 속성 값은 입력 반복(progress)이 이 범위를 벗어나면 단순히 외삽(extrapolate)됩니다.

일부 경우에는 [0, 1] 범위 밖에서 속성 값이 비선형적으로 변하도록 지정할 수 있으면 유용하기 때문에 이 제한을 해제하는 방안을 고려한 적이 있습니다. 예를 들어 녹색에서 노란색으로 보간하지만, 오버슈트 타이밍 함수로 인해 일시적으로 노란색을 넘어 빨간색까지 갔다가 다시 노란색으로 돌아오는 애니메이션이 있습니다.

이 효과는 키프레임과 타이밍 함수를 조정해서 구현할 수도 있지만, 이 방식은 모델의 타이밍과 애니메이션 효과의 분리 원칙을 깨뜨린다고 생각됩니다.

이 효과를 어떻게 구현해야 하는지 명확하지 않지만, [0, 1] 범위를 벗어난 키프레임 offset을 허용하면 현재 명세된 offset 0과 1의 키프레임을 필요에 따라 합성(synthesize)하는 동작이 일관성을 잃을 수 있습니다.

자세한 내용은 2013년 도쿄 F2F 회의록 4번(키프레임 offset이 [0, 1]을 벗어날 때) 섹션을 참고하세요.

<https://github.com/w3c/csswg-drafts/issues/2081>

being rendered [HTML]의 정의에서 display: contents에 관한 부분은 아직 논의 중입니다. 이 절차에서는 display: contents이면서 레이아웃 박스를 가질 수 있는 요소(즉, connected이고 display: none 서브트리에 속하지 않는 경우)는 렌더링되고 있다고 간주합니다.

remove() 메서드는 효과를 부모 그룹이나 애니메이션에서 제거할 때 사용할 수 있습니다. 레벨 1에서 이 메서드를 유지할지, 효과를 애니메이션에서 단순히 제거하는 것으로 정의할지 결정해야 합니다. [이슈 #2082]
[[type]]이 break, continue, return일 때 어떻게 해야 할까요? 이런 경우가 실제로 존재할 수 있을까요?
시간 값navigationStart 기준이고 requestAnimationFramedocument.timeline.currentTime과 동일한 시간을 사용하는 것과 충돌하지 않는가? [이슈 #2083]