웹 애니메이션

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을 통해 텍스트 수정
Animation at Work Slack의 "waapi" 채널에 참여
IRC: W3C의 IRC에 있는 #webanimations

초록

이 명세는 웹 페이지 표현의 변경 사항에 대한 동기화 및 타이밍 모델을 정의한다. 또한 이 명세는 이 모델과 상호 작용하기 위한 애플리케이션 프로그래밍 인터페이스를 정의하며, 향후 명세에서 이러한 기능을 노출하기 위한 선언적 수단을 정의할 것으로 예상된다.

CSS는 구조화된 문서(예: HTML 및 XML)의 렌더링을 설명하기 위한 언어로, 화면, 종이 등에 사용된다.

이 문서의 상태

이 절에서는 이 문서가 게시된 시점의 상태를 설명한다. 현재 W3C 출판물 목록과 이 기술 보고서의 최신 개정판은 https://www.w3.org/TR/의 W3C 기술 보고서 색인에서 확인할 수 있다.

이 문서는 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의 모든 불투명도 애니메이션의 id를 출력한다
for (const animation of elem.getAnimations()) {
  if (
    animation.effect instanceof KeyframeEffect &&
    animation.effect
      .getKeyframes()
      .some(frame => frame.hasOwnProperty('opacity'))
  ) {
    console.log(animation.id);
  }
}

마찬가지로 애니메이션을 미세 조정하려면 재생 속도를 낮추고 다시 재생해야 하는 경우가 많다.

// 모든 변환 애니메이션의 속도를 낮추고 다시 재생한다
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);
}
애니메이션 테스트

애니메이션을 사용하는 애플리케이션을 테스트할 때는 이러한 애니메이션이 끝까지 실행되기를 기다리는 것이 비현실적인 경우가 많다. 대신 애니메이션을 특정 시간으로 탐색할 수 있는 것이 바람직하다.

// 애니메이션의 중간 지점으로 탐색하고 불투명도가 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 Animation [SMIL-ANIMATION]을 기준으로 정의되어 있다. SVG의 애니메이션 기능을 웹 애니메이션 모델을 기준으로 정의함으로써 SVG와 SMIL Animation 간의 의존성을 제거하는 것이 의도되어 있다.

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

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

이 명세의 프로그래밍 인터페이스 구성 요소는 HTML [HTML]에 정의된 인터페이스에 몇 가지 사항을 추가한다.

1.3. 이 명세의 개요

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

2. 명세 규칙

이 명세는 먼저 애니메이션애니메이션 효과와 같은 추상 개념과, 이들에 속하는 재생 속도 또는 반복 지속 시간과 같은 속성을 설명한다. 이러한 속성 외에도 이러한 속성을 업데이트하는 특정 절차가 종종 존재하며, 예를 들어 재생 속도를 설정하는 절차나 애니메이션의 시작 시간을 설정하는 절차가 있다.

이 명세가 특정 절차에 명시적으로 링크하지 않는 경우, "animation시작 시간미해결 상태로 만든다"와 같이 사용자 에이전트가 속성을 업데이트하도록 요구하는 텍스트는 관련 절차를 호출하지 않고 속성을 직접 업데이트하는 것을 의미하는 것으로 이해해야 한다.

이 명세에 특화되지 않은 추가 문서 작성 규칙은 문서 규칙에 설명되어 있다.

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

이 절은 비규범적이다

개략적으로 웹 애니메이션 모델은 크게 독립적인 두 부분, 즉 타이밍 모델애니메이션 모델로 구성된다. 이들 부분의 역할은 다음과 같다:

타이밍 모델

한 시점을 받아 애니메이션의 단일 반복 내에서 반복 진행률이라고 하는 비례적 거리로 변환한다. 일부 애니메이션은 반복할 때마다 달라지므로 반복 인덱스도 기록된다.

애니메이션 모델

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

그래픽으로 이 흐름은 다음과 같이 나타낼 수 있다:

웹 애니메이션 모델의 동작 개요.
웹 애니메이션 모델의 동작 개요.
현재 시간이 타이밍 모델에 입력되면 반복 진행률 값과 반복 인덱스가 생성된다.
이 매개변수는 애니메이션 모델의 입력으로 사용되며 적용할 값을 생성한다.

예를 들어 다음과 같은 애니메이션을 생각해 보자:

처음 세 항목은 타이밍 모델에 적용된다. 6초 시점에는 애니메이션이 두 번째 반복의 절반까지 진행되어야 한다고 계산하고 결과 0.5를 생성한다. 그런 다음 애니메이션 모델은 이 정보를 사용하여 너비를 계산한다.

이 명세는 타이밍 모델부터 시작한 다음 애니메이션 모델로 진행한다.

4. 타이밍 모델

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

4.1. 타이밍 모델 개요

이 절은 비규범적이다

웹 애니메이션 타이밍 모델은 두 가지 특성을 가진다. 무상태이며 계층적이다.

4.1.1. 무상태

웹 애니메이션 타이밍 모델은 입력 시간을 받아 출력 반복 진행률을 생성하는 방식으로 동작한다. 출력은 오직 입력 시간에만 기반하며 이전 입력과 독립적이므로, 이 모델은 무상태라고 설명할 수 있다. 이에 따라 모델은 다음 특성을 갖는다:

프레임 속도와 무관함

출력이 이전 입력과 독립적이므로 모델이 업데이트되는 속도는 진행에 영향을 주지 않는다. 입력 시간이 현실 세계 시간의 진행에 비례하는 한, 애니메이션은 이를 실행하는 장치의 성능과 관계없이 동일한 속도로 진행된다.

방향과 무관함

입력 순서는 중요하지 않으므로 모델에는 방향이 없다. 즉, 특별한 처리를 요구하지 않고 임의의 시점으로 모델을 업데이트할 수 있다.

상수 시간 탐색

각 입력은 이전 입력과 독립적이므로, 먼 미래로의 탐색 연산에서도 필요한 처리는 적어도 잠재적으로 상수 시간일 수 있다.

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

첫째, 모델의 프로그래밍 인터페이스에 정의된 여러 메서드는 애니메이션 일시 중지와 같은 재생 제어를 제공한다. 이러한 메서드는 호출된 시간을 기준으로 정의되므로 상태를 가진다. 이러한 메서드는 주로 편의를 위해 제공되며 핵심 타이밍 모델의 일부가 아니라 그 위에 계층으로 추가된다.

마찬가지로 애니메이션의 완료 동작은 애니메이션의 미디어(연관 효과) 종료 시간을 동적으로 변경할 때 변경이 발생한 시점에 따라 다른 결과가 발생할 수 있음을 의미한다. 이 동작은 다소 바람직하지 않지만 직관적이며 HTML과 일관성이 있다고 판단되었다. 따라서 이 모델은 실제로는 타이밍 속성에 동적 변경이 없는 경우에만 무상태라고 설명할 수 있다.

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

4.1.2. 계층적

타이밍 모델의 또 다른 특징은 시간이 상속된다는 것이다. 시간은 타임라인에서 시작하여 여러 단계를 거쳐 각 애니메이션 효과로 전달된다. 각 단계에서 시간은 앞뒤로 이동하거나, 배율이 적용되거나, 역전되거나, 일시 중지되거나, 반복될 수 있다.

타이밍 노드의 계층 구조
타이밍 노드의 계층 구조. 트리의 각 노드는 부모 노드에서 시간을 파생한다.

이 명세의 이 레벨에서는 계층 구조가 얕다. 이 명세의 후속 레벨에서는 더 깊은 타이밍 계층 구조를 허용하는 그룹 효과 개념을 도입할 것이다.

4.2. 시간 값

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

시간 값은 명목상 특정 시점으로부터의 밀리초 수를 나타내는 실수이다. 시간 값과 벽시계 밀리초 사이의 관계는 값이 시간 계층 구조를 통과하는 동안 적용되는 여러 변환으로 인해 불분명해질 수 있다.

향후 스크롤 위치 또는 UI 제스처를 기반으로 하는 타임라인이 생길 수 있으며, 이 경우 시간 값과 밀리초 간의 관계는 더욱 약해질 수 있다.

예를 들어 타이밍 노드가 시간 값을 생성할 수 있는 상태가 아닌 경우, 시간 값미해결일 수도 있다.

4.3. 타임라인

타임라인은 동기화를 목적으로 시간 값의 소스를 제공한다.

주어진 어느 시점에서든 타임라인에는 단순히 타임라인의 현재 시간이라고 하는 하나의 현재 시간 값이 있다.

타임라인은 항상 의미 있는 시간 값을 반환할 수 있는 것은 아니며, 미해결 시간 값만 반환할 수도 있다. 예를 들어 문서의 load 이벤트 발생처럼 아직 일어나지 않은 시점을 기준으로 정의될 수 있다. 타임라인시간 값미해결인 경우 해당 타임라인은 비활성 상태로 간주된다.

타임라인은 보고된 현재 시간이 이전에 보고된 현재 시간보다 항상 크거나 같은 경우 단조 증가한다.

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

타임라인문서와 연결될 수 있다.

Document doc에 대해 타임스탬프 now에서 애니메이션을 업데이트하고 이벤트를 전송하도록 요청되면 다음 단계를 실행한다:

  1. now를 타임스탬프로 전달하여 doc연결된 모든 타임라인의 현재 시간을 업데이트한다.

    타이밍 모델의 계층적 특성으로 인해 타임라인현재 시간을 업데이트하는 것은 다음도 포함한다:

  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 타임스탬프로부터의 고정 오프셋으로 계산된다. 이 고정 오프셋을 문서 타임라인의 원점 시간이라고 한다.

"원점 시간"보다 더 나은 용어가 있어야 한다— "시간 원점"과 너무 유사하다. [이슈 #2079]

연결된 문서에 대해 시간 원점이 설정되기 전에는 문서 타임라인비활성이다.

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

Document와 연결된 문서 타임라인은 해당 Document가 활성 문서가 아닌 경우에도 비활성으로 간주된다.

문서 타임라인 timeline에 대해 timeline time이라는 타임라인 시간을 원점 기준 시간으로 변환하려면, timeline timetimeline원점 시간의 합을 반환한다. timeline이 비활성인 경우 미해결 시간 값을 반환한다.

4.3.2. 기본 문서 타임라인

Document에는 기본 문서 타임라인이라고 하는 문서 타임라인이 있다. 기본 문서 타임라인은 각 문서마다 고유하며, document.open() [HTML] 호출을 포함하여 문서의 전체 수명 동안 유지된다.

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

이 절은 비규범적이다

문서 타임라인에 제공되는 now 타임스탬프 값에는 배율이 적용되지 않으므로, 문서 타임라인이 생성하는 시간 값은 벽시계 밀리초에 비례한다.

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

4.4. 애니메이션

이 절은 비규범적이다

타임라인의 자식을 애니메이션이라고 한다. 애니메이션은 일부 시간 기반 동작의 정적 설명인 애니메이션 효과를 받아 이를 타임라인에 바인딩하여 실행되도록 한다. 또한 애니메이션은 일시 중지, 탐색 및 속도 제어를 제공함으로써 애니메이션 효과와 그 타임라인 사이의 연결을 런타임에 제어할 수 있게 한다. 애니메이션과 애니메이션 효과의 관계는 DVD 플레이어와 DVD의 관계와 유사하다.

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

애니메이션타이밍용 문서는 해당 애니메이션의 타임라인연결되어 있는 Document이다. 애니메이션이 타임라인과 연결되어 있지 않거나 해당 타임라인이 문서와 연결되어 있지 않으면 타이밍용 문서가 없다.

애니메이션시작 시간은 해당 애니메이션의 연관 효과가 재생을 시작하도록 예정된 시점의 타임라인 시간 값이다. 애니메이션의 시작 시간은 처음에는 미해결이다.

애니메이션은 일시 중지와 같은 상황에서 애니메이션의 출력 시간 값, 즉 현재 시간을 고정하는 데 사용되는 보류 시간 시간 값도 유지한다. 보류 시간은 처음에는 미해결이다.

충돌하는 애니메이션의 상대적 순서를 설정하기 위해, 애니메이션은 생성되는 순서대로 전역 애니메이션 목록에 추가된다. 그러나 특정 애니메이션 클래스는 애니메이션 순서를 정하는 대체 방법을 제공할 수 있다 (§ 5.4.1 애니메이션 클래스 참조).

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

애니메이션 animation의 타임라인을 null일 수 있는 new timeline으로 설정하는 절차는 다음과 같다:

  1. 존재하는 경우 animation의 현재 타임라인old timeline으로 둔다.

  2. new timelineold timeline과 동일한 객체이면 이 절차를 중단한다.

  3. animation타임라인new timeline으로 둔다.

  4. animation시작 시간해결됨이면, animation보류 시간미해결로 만든다.

    참고: 이 단계는 animation완료 재생 상태가 "고정"되지 않고 업데이트된 현재 시간을 기준으로 다시 평가되도록 보장한다.

  5. animation에 대해 did seek 플래그를 false로 설정하고 synchronously notify 플래그를 false로 설정하여 애니메이션의 완료 상태 업데이트 절차를 실행한다.

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

애니메이션 animation의 연관 효과를 null일 수 있는 new effect설정하는 절차는 다음과 같다:

  1. 존재하는 경우 animation의 현재 연관 효과old effect로 둔다.

  2. new effectold effect와 동일한 객체이면 이 절차를 중단한다.

  3. animation대기 중인 일시 중지 태스크가 있으면, animation준비됨 상태가 되는 즉시 해당 태스크가 실행되도록 다시 예약한다.

  4. animation대기 중인 재생 태스크가 있으면, animationnew effect를 재생할 준비됨 상태가 되는 즉시 해당 태스크가 실행되도록 다시 예약한다.

  5. new effectnull이 아니고, new effect가 다른 애니메이션 previous animation연관 효과인 경우, previous animation에 대해 new effect로 null을 전달하여 애니메이션의 연관 효과 설정 절차(이 절차)를 실행한다.

  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. 애니메이션의 현재 시간 설정

애니메이션을 탐색하기 위해 애니메이션의 현재 시간을 새 값으로 설정할 수 있다. 현재 시간을 설정하는 절차는 두 부분으로 정의된다.

애니메이션 animation의 현재 시간을 seek time으로 조용히 설정하는 절차는 다음과 같다:

  1. seek time미해결 시간 값이면 다음 단계를 수행한다.

    1. 현재 시간해결됨이면 TypeError던진다.

    2. 이 단계를 중단한다.

  2. animation보류 시간 또는 시작 시간 중 하나를 다음과 같이 업데이트한다:

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

    animation보류 시간seek time으로 설정한다.

    그렇지 않으면,

    animation시작 시간timeline time - (seek time / 재생 속도)를 평가한 결과로 설정한다. 여기서 timeline timeanimation과 연결된 타임라인의 현재 시간 값이다.

  3. animation에 연결된 타임라인이 없거나 연결된 타임라인비활성이면, animation시작 시간미해결로 만든다.

    이는 활성 타임라인이 없을 때 시작 시간 또는 애니메이션의 현재 시간하나만 설정할 수 있다는 불변 조건을 유지한다.

  4. animation이전 현재 시간미해결로 만든다.

애니메이션 animation현재 시간을 설정하여 seek time으로 만드는 절차는 다음과 같다:

  1. animation현재 시간을 조용히 설정하여 seek time으로 만드는 단계를 실행한다.

  2. animation대기 중인 일시 중지 태스크가 있으면 다음 단계를 수행하여 일시 중지 연산을 동기적으로 완료한다:

    1. animation보류 시간seek time으로 설정한다.

    2. animation대기 중인 재생 속도를 적용한다.

    3. animation시작 시간미해결로 만든다.

    4. 대기 중인 일시 중지 태스크를 취소한다.

    5. animation현재 준비 Promiseanimation으로 이행한다.

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

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

애니메이션 animation시작 시간을 설정하여 new 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미해결이면),

    previous current time미해결인 경우에도 animation보류 시간previous current time으로 설정한다.

  7. animation대기 중인 재생 태스크 또는 대기 중인 일시 중지 태스크가 있으면 해당 태스크를 취소하고, animation현재 준비 프로미스animation으로 이행한다.

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

4.4.6. 연관 효과 기다리기

이 절은 비규범적이다

애니메이션이 수행하는 일부 연산은 즉시 발생하지 않을 수 있다. 예를 들어 일부 사용자 에이전트는 애니메이션 재생을 별도의 프로세스나 특수 그래픽 하드웨어에 위임할 수 있으며, 각각 어느 정도의 설정 오버헤드가 발생할 수 있다.

이러한 애니메이션의 타이밍이 애니메이션이 트리거된 순간부터 시작된다면, 관련된 설정 시간에 해당하여 애니메이션의 첫 번째 프레임과 두 번째 프레임 사이에 상당한 점프가 발생할 수 있다.

이 문제를 피하기 위해 웹 애니메이션은 일반적으로 애니메이션의 첫 번째 프레임이 완료되는 순간부터 애니메이션 타이밍을 시작한다. 이는 애니메이션미해결 시작 시간으로 표현되며, 애니메이션이 준비됨 상태가 되면 해결된다. 콘텐츠는 시작 시간해결됨 시간 값으로 설정하여 이 동작을 사용하지 않도록 할 수 있다.

다음 두 조건이 모두 참이 되는 최초의 순간에 애니메이션은 준비됨 상태이다:

4.4.7. 현재 준비 프로미스

애니메이션에는 현재 준비 프로미스가 있다. 현재 준비 프로미스는 처음에는 애니메이션 자체를 값으로 하여 새 이행된 Promise를 생성하는 절차를 사용해 생성되고, 애니메이션의 관련 Realm에서 생성된 이행된 Promise이다.

애니메이션에 이전에 대기 중인 태스크가 없던 상태에서 대기 중인 재생 태스크 또는 대기 중인 일시 중지 태스크를 큐에 넣을 때마다, 또는 애니메이션이 취소될 때마다(참조: § 4.4.14 애니메이션 취소), 이 객체는 새로운 Promise 객체로 대체된다.

대기 중인 재생 요청과 대기 중인 일시 중지 요청 모두에 동일한 객체가 사용되므로, 작성자는 Promise 객체가 이행될 때 애니메이션의 상태를 확인하는 것이 권장된다.

예를 들어 다음 코드 조각에서는 현재 준비 프로미스가 이행될 때 애니메이션의 상태가 실행 중이 된다. 이는 대기 중인 재생 태스크가 아직 큐에 있는 동안 play 연산이 발생하기 때문에 현재 준비 프로미스가 재사용되기 때문이다.

animation.pause();
animation.ready.then(function() {
  // 'running'을 표시한다
  alert(animation.playState);
});
animation.play();

4.4.8. 애니메이션 재생

플래그 auto-rewind가 주어진 경우, animation이라는 애니메이션을 재생하는 절차는 다음과 같다:

  1. aborted pauseanimation대기 중인 일시 중지 태스크가 있으면 true이고, 그렇지 않으면 false인 불리언 플래그로 둔다.

  2. has pending ready promise를 처음에는 false인 불리언 플래그로 둔다.

  3. seek time을 처음에는 미해결시간 값으로 둔다.

  4. auto-rewind 플래그가 true이면, 해당하는 것이 있는 경우 다음 조건 중 처음으로 일치하는 조건에 대응하는 단계를 수행한다:

    animation유효 재생 속도가 ≥ 0이고, animation현재 시간이 다음 중 하나이면:

    seek time을 0으로 설정한다.

    animation유효 재생 속도가 < 0이고, animation현재 시간이 다음 중 하나이면:

    연관 효과 종료가 양의 무한대이면,

    "InvalidStateError" DOMException던지고 이 단계를 중단한다.

    그렇지 않으면,

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

  5. 다음 세 조건이 모두 충족되면:

    seek time을 0으로 설정한다.

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

  6. animation단조 증가하지 않는 연결된 타임라인이 있으면 has finite timeline을 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현재 준비 프로미스animation관련 Realm에 있는 새 프로미스로 둔다.

  12. animation준비됨 상태가 되는 즉시 실행할 태스크를 예약한다. 태스크는 다음 단계를 수행해야 한다:

    1. animation시작 시간 또는 보류 시간 중 적어도 하나가 해결됨임을 단언한다.

    2. ready timeanimation준비됨 상태가 된 순간에 animation과 연결된 타임라인시간 값으로 둔다.

    3. 해당하는 것이 있는 경우 아래의 처음으로 일치하는 조건에 대응하는 단계를 수행한다:

      animation보류 시간해결됨이면,
      1. animation대기 중인 재생 속도를 적용한다.

      2. new start timeanimation에 대해 ready time - 보류 시간 / 재생 속도를 평가한 결과로 둔다. 재생 속도가 0이면, new start time을 단순히 ready time으로 둔다.

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

      4. animation재생 속도가 0이 아니면, animation보류 시간미해결로 만든다.

      animation시작 시간이 해결됨이고 animation대기 중인 재생 속도가 있으면,
      1. current time to matchanimation에 대해 (ready time - 시작 시간) × 재생 속도를 평가한 결과로 둔다.

      2. animation대기 중인 재생 속도를 적용한다.

      3. animation재생 속도가 0이면, animation보류 시간current time to match으로 둔다.

      4. new start timeanimation에 대해 ready time - current time to match / 재생 속도를 평가한 결과로 둔다. 재생 속도가 0이면, new start time을 단순히 ready time으로 둔다.

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

    4. animation현재 준비 프로미스animation으로 이행한다.

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

      위 두 단계의 순서가 중요하다는 점에 유의한다. 이 순서로 인해 길이가 0인 연관 효과를 가진 애니메이션은 현재 완료 프로미스보다 먼저 현재 준비 프로미스를 이행한다.

    위 태스크가 예약되었지만 아직 실행되지 않은 동안에는 animation대기 중인 재생 태스크가 있다고 설명한다. 그러나 태스크가 실행 중인 동안에는 animation대기 중인 재생 태스크없다.

    사용자 에이전트가 animation이 즉시 준비됨이라고 판단하는 경우, 다음 마이크로태스크 체크포인트에서 실행되도록 위 태스크를 마이크로태스크로 예약할 수 있지만, 태스크를 동기적으로 수행해서는 안 된다.

    위의 대기 중인 재생 태스크를 비동기적으로 실행해야 한다는 요구사항은 다음과 같은 코드가 구현 간에 일관되게 동작하도록 보장한다:

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

    위 코드에서 대기 중인 재생 태스크가 동기적으로 실행되었다면, 현재 준비 프로미스는 거부되지 않았을 것이다.

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

4.4.9. 애니메이션 일시 중지

애니메이션미해결 시작 시간이 있을 때마다, 그 현재 시간은 정지된다.

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

animation이라는 애니메이션을 일시 중지하는 절차는 다음과 같다:

  1. animation대기 중인 일시 중지 태스크가 있으면 이 단계를 중단한다.

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

  3. seek time을 처음에는 미해결시간 값으로 둔다.

  4. animation단조 증가하지 않는 연결된 타임라인이 있으면 has finite timeline을 true로 둔다.

  5. animation현재 시간미해결이면, 아래에서 처음으로 일치하는 조건에 따라 단계를 수행한다:

    animation재생 속도가 ≥ 0이면,

    seek time을 0으로 설정한다.

    그렇지 않으면,
    animation연관 효과 종료가 양의 무한대이면,

    "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현재 준비 프로미스animation관련 Realm에 있는 새 프로미스로 설정한다.

  10. 다음 두 조건이 모두 참이 되는 최초의 가능한 순간에 실행될 태스크를 예약한다:

    • 존재하는 경우 사용자 에이전트가 animation연관 효과의 재생을 정지하는 데 필요한 모든 처리를 수행했다.

    • 애니메이션이 비활성이 아닌 타임라인과 연결되어 있다.

    태스크는 다음 단계를 수행해야 한다:

    1. ready time을 사용자 에이전트가 animation연관 효과의 재생을 정지하는 데 필요한 처리를 완료한 순간에 animation과 연결된 타임라인의 시간 값으로 둔다.

    2. animation시작 시간해결됨이고 그 보류 시간이 해결됨이 아니면, animation보류 시간(ready time - 시작 시간) × 재생 속도를 평가한 결과로 둔다.

      참고: 애니메이션이 완료됨 상태이거나 애니메이션에 대기 중인 재생 태스크가 있는 경우에는 보류 시간이 이미 설정되어 있을 수 있다. 어느 경우든 일시 중지됨 상태로 진입할 때 보류 시간을 유지하고자 한다.

    3. animation대기 중인 재생 속도를 적용한다.

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

    5. animation현재 준비 프로미스animation으로 이행한다.

    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을 지나 역방향으로 재생되지 않는다.

재생 범위의 자연스러운 경계에 도달한 애니메이션을 완료됨 상태라고 한다.

그래픽으로 현재 시간을 제한하는 효과는 아래와 같이 나타난다.

애니메이션의 현재 시간을 제한하는 효과.
시작 시간이 1s이고, 길이가 3s인 연관 효과와 양의 재생 속도를 가진 애니메이션현재 시간을 제한하는 효과. 애니메이션의 현재 시간이 연관 효과의 끝에 도달한 후에는 3s로 제한된다.

그러나 애니메이션현재 시간연관 효과의 끝을 지난 시간으로 탐색할 수 있다. 그렇게 하면 현재 시간은 진행하지 않지만 애니메이션은 탐색된 시간에서 일시 중지된 것처럼 동작한다.

예를 들어 이를 통해 연관 효과없는 애니메이션의 현재 시간을 5s로 탐색할 수 있다. 나중에 종료 시간이 5s보다 늦은 종료 시간을 가진 연관 효과가 해당 애니메이션과 연결되면, 재생은 5s 지점에서 시작된다.

애니메이션의 연관 효과 길이가 변경될 때에도 위 시나리오와 유사한 동작이 발생할 수 있다.

마찬가지로 재생 속도가 음수이면, 현재 시간은 시간 0을 지나 진행하지 않는다.

4.4.11. 현재 완료 프로미스

각 애니메이션에는 현재 완료 프로미스가 있다. 현재 완료 프로미스는 처음에는 대기 중인 Promise 객체이다.

애니메이션이 완료 재생 상태를 벗어날 때마다 이 객체는 새로운 프로미스로 대체된다.

4.4.12. 완료 상태 업데이트

양의 재생 속도를 가진 애니메이션의 경우, 현재 시간연관 효과 종료에 도달할 때까지 계속 증가한다.

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

음의 재생 속도를 가진 애니메이션의 경우, 현재 시간은 0에 도달할 때까지 계속 감소한다.

이 경계에 도달했거나 넘어섰으며 해결됨 시작 시간을 가진 실행 중인 애니메이션을 완료됨 상태라고 한다.

이 경계를 넘었는지는 애니메이션 객체를 수정할 때마다 아래에 정의된 애니메이션의 완료 상태 업데이트 절차를 사용하여 확인한다. 이 절차는 애니메이션을 업데이트하고 이벤트를 전송하는 절차의 일부로도 실행된다. 두 경우 모두 아래에 정의된 did seek 플래그는 false로 설정된다.

각 애니메이션에 대해 사용자 에이전트는 처음에는 미해결이전 현재 시간 시간 값을 유지한다.

일반적인 재생 중에는 애니메이션현재 시간이 위에서 설명한 경계로 제한되지만, 애니메이션의 현재 시간을 설정하는 절차를 사용하여 애니메이션의 현재 시간을 해당 경계 밖의 시간으로 탐색할 수 있다.

did seek 플래그(현재 시간을 설정한 후 업데이트가 수행되는지를 나타냄)와 synchronously notify 플래그(업데이트가 완료 이벤트 큐잉과 완료 프로미스 이행이 발생한다면 즉시 발생할 것으로 예상하는 컨텍스트에서 호출되었음을 나타냄)가 주어진 경우, animation에 대해 애니메이션의 완료 상태를 업데이트하는 절차는 다음과 같다:

  1. did seek가 false이면, 보류 시간미해결 시간 값으로 대체하여 현재 시간을 계산한 결과를 unconstrained current time으로 둔다. did seek가 true이면, unconstrained current time현재 시간과 같다.

    참고: 이는 방향이 변경될 수 있는 타임라인을 수용하기 위해 필요하다. 이 정의가 없으면 한 번 완료된 애니메이션은 타임라인이 반대 방향으로 진행하더라도 완료된 상태로 남게 된다.

  2. 다음 세 조건 모두가 참이면,

    해당하는 것이 있는 경우 아래에서 animation에 대해 처음으로 일치하는 조건에 따라 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. animation재생 상태완료됨이면 current finished state을 true로 둔다. 그렇지 않으면 false로 둔다.

  5. current finished state이 true이고 현재 완료 프로미스가 아직 이행되지 않았으면 다음 단계를 수행한다:

    1. 완료 알림 단계가 다음 절차를 참조하도록 둔다:

      1. animation재생 상태완료됨과 같지 않으면 이 단계를 중단한다.

      2. animation현재 완료 프로미스 객체를 animation으로 이행한다.

      3. AnimationPlaybackEvent finishEvent생성한다.

      4. finishEventtype 속성을 finish로 설정한다.

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

      6. finishEventtimelineTime 속성을 animation과 연결된 타임라인현재 시간으로 설정한다. animation이 타임라인과 연결되어 있지 않거나 타임라인이 비활성이면, timelineTimenull로 둔다.

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

        그렇지 않으면, animation에서 finishEvent디스패치하도록 태스크를 큐에 넣는다. 이 태스크의 태스크 소스는 DOM 조작 태스크 소스이다.

    2. synchronously notify가 true이면, 이 animation에 대해 완료 알림 단계를 실행하도록 큐에 넣어진 모든 마이크로태스크를 취소하고, 완료 알림 단계를 즉시 실행한다.

      그렇지 않고 synchronously notify가 false이면, animation에 대해 해당 단계를 실행하도록 이미 큐에 넣어진 마이크로태스크가 없는 경우에만 animation에 대해 완료 알림 단계를 실행하도록 마이크로태스크를 큐에 넣는다.

  6. current finished state이 false이고 animation현재 완료 프로미스가 이미 이행되었으면, animation현재 완료 프로미스animation관련 Realm에 있는 새 프로미스로 설정한다.

일반적으로 애니메이션의 완료 상태에 대한 알림은 비동기적으로 수행된다. 이를 통해 애니메이션은 이벤트가 발생하거나 프로미스가 이행되는 것을 유발하지 않고 일시적으로 완료 재생 상태에 들어갈 수 있다.

예를 들어 다음 코드 조각에서 animation은 일시적으로 완료 상태에 들어간다. 완료 상태에 대한 알림이 동기적으로 발생한다면 이 코드는 finish 이벤트를 큐에 넣고 현재 완료 프로미스를 이행하게 한다. 그러나 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 이벤트가 즉시 큐에 들어가고 완료 프로미스가
                    // 다음 문이 애니메이션을 완료 상태에서 벗어나게 함에도
                    // 이행된다
animation.currentTime = 0;

애니메이션을 완료하는 절차와 마찬가지로, 애니메이션을 취소하는 절차도 이와 유사하게 cancel 이벤트를 큐에 넣고 현재 완료 프로미스현재 준비 프로미스동기적으로 거부한다는 점에 유의한다.

4.4.13. 애니메이션 완료

아래에 정의된 animation에 대한 애니메이션을 완료하는 절차를 사용하여 애니메이션을 현재 재생 방향의 자연스러운 끝까지 진행시킬 수 있다:

  1. animation유효 재생 속도가 0이거나, animation유효 재생 속도 > 0이고 연관 효과 종료가 무한대이면, "InvalidStateError" DOMException던지고 이 단계를 중단한다.

  2. animation대기 중인 재생 속도를 적용한다.

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

    재생 속도 > 0이면,

    limit연관 효과 종료로 둔다.

    그렇지 않으면,

    limit을 0으로 둔다.

  4. 현재 시간을 limit으로 조용히 설정한다.

  5. animation시작 시간미해결이고 animation에 연결된 활성 타임라인이 있으면, 시작 시간timeline time - (limit / 재생 속도)를 평가한 결과로 둔다. 여기서 timeline time은 연결된 타임라인의 현재 시간 값이다.

  6. 대기 중인 일시 중지 태스크가 있고 시작 시간해결됨이면,

    1. 보류 시간미해결로 둔다.

      일반적으로 애니메이션이 이전에 유휴 상태였던 경우를 제외하면 보류 시간은 이미 미해결일 것이다.
    2. 대기 중인 일시 중지 태스크를 취소한다.

    3. animation현재 준비 프로미스animation으로 이행한다.

  7. 대기 중인 재생 태스크가 있고 시작 시간해결됨이면, 해당 태스크를 취소하고 animation현재 준비 프로미스animation으로 이행한다.

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

4.4.14. 애니메이션 취소

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

animation에 대해 애니메이션을 취소하는 절차는 다음과 같다:

  1. animation재생 상태유휴아니면, 다음 단계를 수행한다:

    1. animation에 대해 애니메이션의 대기 중인 태스크 재설정 절차를 실행한다.

    2. 현재 완료 프로미스를 "AbortError"라는 이름의 DOMException으로 거부한다.

    3. 현재 완료 프로미스의 [[PromiseIsHandled]] 내부 슬롯을 true로 설정한다.

    4. 현재 완료 프로미스animation관련 Realm에 있는 새 프로미스로 둔다.

    5. AnimationPlaybackEvent, cancelEvent생성한다.

    6. cancelEventtype 속성을 cancel로 설정한다.

    7. cancelEventcurrentTimenull로 설정한다.

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

    9. cancelEventtimelineTimetimeline time으로 설정한다. timeline time미해결이면, 이를 null로 설정한다.

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

      그렇지 않으면 animation에서 cancelEvent디스패치하도록 태스크를 큐에 넣는다. 이 태스크의 태스크 소스는 DOM 조작 태스크 소스이다.

  2. animation보류 시간미해결로 만든다.

  3. animation시작 시간미해결로 만든다.

animation에 대해 애니메이션의 대기 중인 태스크를 재설정하는 절차는 다음과 같다:

  1. animation대기 중인 재생 태스크 또는 대기 중인 일시 중지 태스크가 없으면, 이 절차를 중단한다.

  2. animation대기 중인 재생 태스크가 있으면 해당 태스크를 취소한다.

  3. animation대기 중인 일시 중지 태스크가 있으면 해당 태스크를 취소한다.

  4. animation대기 중인 재생 속도를 적용한다.

  5. animation현재 준비 프로미스를 "AbortError"라는 이름의 DOMException으로 거부한다.

  6. animation현재 준비 프로미스의 [[PromiseIsHandled]] 내부 슬롯을 true로 설정한다.

  7. animation현재 준비 프로미스animation관련 Realm에서 값 animation으로 새 이행된 Promise 객체를 생성한 결과로 둔다.

4.4.15. 속도 제어

애니메이션의 재생 속도는 재생 속도를 설정하여 제어할 수 있다. 예를 들어 재생 속도를 2로 설정하면 애니메이션의 현재 시간이 그 타임라인의 두 배 속도로 증가한다. 마찬가지로 재생 속도가 -1이면 애니메이션의 현재 시간은 그 타임라인시간 값이 증가하는 것과 동일한 속도로 감소한다.

애니메이션에는 연관된 타임라인시간 값의 변화율에서 애니메이션의 현재 시간으로의 배율 계수를 제공하는 재생 속도가 있다. 재생 속도는 처음에는 1이다.

애니메이션의 재생 속도를 0으로 설정하면 실질적으로 애니메이션이 일시 중지된다(그러나 재생 상태가 반드시 일시 중지됨이 되는 것은 아니다).

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

애니메이션 animation재생 속도를 설정하여 new playback rate으로 만드는 절차는 다음과 같다:

  1. animation의 모든 대기 중인 재생 속도를 지운다.

  2. previous time재생 속도를 변경하기 전 animation현재 시간 값으로 둔다.

  3. previous playback rateanimation의 현재 유효 재생 속도로 둔다.

  4. 재생 속도new playback rate으로 설정한다.

  5. 해당하는 것이 있는 경우 다음 조건 중 처음으로 일치하는 조건에 대응하는 단계를 수행한다:

    animation단조 증가하는 타임라인과 연결되어 있고 previous time해결됨이면,

    animation현재 시간을 설정하여 previous time으로 만든다.

    animation이 null이 아닌 타임라인과 연결되어 있고 그 타임라인이 단조 증가하지 않으며, animation시작 시간해결됨이고, 연관 효과 종료가 무한대가 아니며, 다음 중 하나이면:

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

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

    animation시작 시간animation에 대해 연관 효과 종료 - 시작 시간을 평가한 결과로 설정한다.

    참고: 이는 비단조 타임라인에서 애니메이션의 시작/종료 시간을 효과적으로 뒤집어, 다른 방향에서 시작 시간의 상대적 오프셋을 유지한다.

4.4.15.2. 애니메이션의 재생 속도를 매끄럽게 업데이트하기

다른 프로세스나 스레드에서 실행 중인 애니메이션의 경우, 애니메이션을 실행하는 프로세스나 스레드가 현재 업데이트를 수행하는 프로세스나 스레드와 동기화되어 있지 않다면 재생 속도를 설정하는 절차로 인해 애니메이션이 점프할 수 있다.

애니메이션재생 속도를 매끄럽게 변경하기 위해, 애니메이션에는 필요한 동기화가 이루어진 후 적용할 재생 속도를 정의하는 대기 중인 재생 속도가 있을 수 있다 (다른 스레드나 프로세스에서 실행되는 애니메이션의 경우).

처음에는 애니메이션대기 중인 재생 속도가 설정되어 있지 않다.

animation유효 재생 속도는 설정되어 있다면 그 대기 중인 재생 속도이고, 그렇지 않으면 애니메이션의 재생 속도이다.

애니메이션 animation대기 중인 재생 속도를 적용하려면 다음 단계를 수행한다:

  1. animation대기 중인 재생 속도가 없으면 이 단계를 중단한다.

  2. animation재생 속도를 그 대기 중인 재생 속도로 설정한다.

  3. animation대기 중인 재생 속도를 지운다.

애니메이션 animation현재 시간을 유지하면서 재생 속도를 new playback rate으로 매끄럽게 업데이트하는 절차는 다음과 같다:

  1. previous play stateanimation재생 상태로 둔다.

    참고: animation유효 재생 속도를 업데이트하기 전에 재생 상태를 기록할 필요가 있다. 이는 다음 로직에서, animation이 대기 중인 재생 속도를 적용한 뒤에도 완료된 상태인지 여부와 관계없이 현재 완료됨 상태이면 animation대기 중인 재생 속도를 즉시 적용하고자 하기 때문이다. 대기 중인 재생 속도를 적용한 후에도 완료된 상태인지 여부와는 관계없다.

  2. animation대기 중인 재생 속도new playback rate으로 둔다.

  3. 아래에서 처음으로 일치하는 조건에 대응하는 단계를 수행한다:

    animation대기 중인 재생 태스크 또는 대기 중인 일시 중지 태스크가 있으면,

    이 단계를 중단한다.

    참고: 서로 다른 유형의 대기 중인 태스크는 실행될 때 대기 중인 재생 속도를 적용하므로 이 경우에는 추가 작업이 필요하지 않다.

    previous play state유휴 또는 일시 중지됨이거나, animation현재 시간미해결이면,

    animation대기 중인 재생 속도를 적용한다.

    참고: 위의 두 번째 조건은 현재 시간이 미해결이고 대기 중인 재생 태스크가 없는 실행 중 애니메이션이 있는 경우 아래에서 이를 재생하려고 시도하지 않도록 하기 위해 필요하다.

    previous play state완료됨이면,
    1. animation보류 시간미해결 시간 값으로 대체하여 animation현재 시간을 계산한 결과를 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과 연결된 타임라인이 없거나, 연결된 타임라인비활성이면 "InvalidStateError" DOMException던지고 이 단계를 중단한다.

  2. original pending playback rateanimation대기 중인 재생 속도로 둔다.

  3. animation대기 중인 재생 속도를 그 유효 재생 속도의 덧셈 역원(즉, -유효 재생 속도)으로 둔다.

  4. animation에 대해 auto-rewind 플래그를 true로 설정하여 애니메이션을 재생하는 단계를 실행한다.

    애니메이션을 재생하는 단계에서 예외가 발생하면, animation대기 중인 재생 속도original pending playback rate으로 설정하고 예외를 전파한다.

4.4.17. 재생 상태

애니메이션은 다음 재생 상태 중 하나에 있다고 설명할 수 있으며, 각각에 대해 비규범적 설명도 제공된다:

유휴

애니메이션의 현재 시간미해결이고, 애니메이션의 시작 시간미해결이며, 대기 중인 태스크가 없다. 이 상태에서는 애니메이션에 효과가 없다.

실행 중

애니메이션에는 각 애니메이션 프레임마다 변경되는 해결된 현재 시간이 있다(재생 속도가 0이 아니고, 타임라인활성이며 단조 증가하는 경우).

일시 중지됨

애니메이션이 정지되었으며 현재 시간은 더 이상 변경되지 않는다.

완료됨

애니메이션이 재생 범위의 자연스러운 경계에 도달했으며 현재 시간은 더 이상 업데이트되지 않는다.

주어진 시점에서 애니메이션 animation재생 상태는 다음 조건 중 처음으로 일치하는 조건에 해당하는 상태이다:

다음 조건이 모두 참이다:

유휴

다음 조건 중 하나가 참이다:

일시 중지됨

animation현재 시간해결됨이고 다음 조건 중 하나가 참이다:

완료됨

그렇지 않으면,

실행 중

일시 중지 재생 상태가 실질적으로 완료 재생 상태보다 "우선"한다는 점에 유의한다.

그러나 자연스러운 재생 범위 밖에서 일시 중지된 애니메이션은 아래와 같이 시작 시간을 설정하여 다시 시작하지 않고도 일시 중지됨 애니메이션에서 완료됨 애니메이션으로 변환할 수 있다:

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은 각각 animation재생 속도시작 시간이다).

타임라인 timeline시간 값과 동일한 척도로 표현되는 시간 값 time에 대해 타임라인 시간을 원점 기준 시간으로 변환하려면 다음 단계를 수행한다:

  1. timeline timetime을 애니메이션 시간에서 타임라인 시간으로 변환한 결과로 둔다.

  2. timeline time미해결이면, time을 반환한다.

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

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

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

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

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

애니메이션은 재생되면서 애니메이션 재생 이벤트를 통해 상태 변경을 보고한다.

애니메이션 재생 이벤트는 타이밍 모델의 속성이다. 따라서 애니메이션연관 효과가 없거나 관찰 가능한 결과가 없는 경우에도 디스패치된다.

4.4.18.3. 애니메이션 재생 이벤트의 유형
finish

애니메이션이 완료 재생 상태에 들어갈 때마다 큐에 넣어진다.

cancel

애니메이션이 다른 상태에서 유휴 재생 상태로 들어갈 때마다 큐에 넣어진다. 처음부터 유휴 상태인 새 애니메이션을 생성하는 것은 새 cancel 이벤트를 생성하지 않는다.

remove

애니메이션이 자동으로 제거될 때마다 큐에 넣어진다. § 5.5 애니메이션 대체를 참조한다.

4.5. 애니메이션 효과

애니메이션 효과는 타이밍 계층 구조의 항목을 가리키는 추상 용어이다.

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

설정된 경우 애니메이션연관 효과애니메이션 효과의 한 유형이다. 애니메이션연관 효과는 해당 애니메이션과 연결되어 있다고 한다. 주어진 시점에서 애니메이션 효과는 최대 하나의 애니메이션과만 연결될 수 있다.

애니메이션 효과 effecttimeline과 연결된 애니메이션과 연결되어 있다면, effect는 타임라인 timeline연결되어 있다.

4.5.2. 애니메이션 효과의 유형

이 명세는 한 가지 유형의 애니메이션 효과, 즉 키프레임 효과를 정의한다. 이 명세의 후속 레벨에서는 추가 유형의 애니메이션 효과를 정의할 것이다.

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

4.5.3. 활성 구간

애니메이션 효과가 실행되도록 예정된 기간을 그 활성 구간이라고 한다. 각 애니메이션 효과에는 이러한 구간이 하나만 있다.

활성 구간의 하한은 일반적으로 이 애니메이션 효과와 연결된 애니메이션시작 시간에 해당하지만, 애니메이션 효과시작 지연에 의해 이동될 수 있다.

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

시작 시간, 시작 지연, 활성 지속 시간 사이의 관계는 아래에 나타나 있다.

활성 구간의 끝점에 대한 시작 지연 효과의 예
활성 구간의 끝점에 대한 시작 지연 효과의 예.
(a) 지연이 없는 애니메이션 효과; 시작 시간활성 구간의 시작이 일치한다.
(b) 양의 지연이 있는 애니메이션 효과; 활성 구간의 시작이 지연만큼 늦춰진다.
(c) 음의 지연이 있는 애니메이션 효과; 활성 구간의 시작이 지연만큼 앞당겨진다.

종료 지연도 지정할 수 있지만, 주로 애니메이션의 순서를 지정할 때만 유용하다.

애니메이션 효과는 효과가 그 효과를 생성하도록 예정된 기간인 활성 구간을 정의한다. 단, 활성 구간 밖에서 적용되는 채우기 모드는 예외이다.

활성 구간의 하한은 시작 지연에 의해 정의된다.

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

활성 구간의 길이를 활성 지속 시간이라고 하며, 그 계산은 § 4.8.2 활성 지속 시간 계산에 정의되어 있다.

시작 지연과 마찬가지로, 애니메이션 효과에는 주로 다른 애니메이션 효과종료 시간을 기준으로 애니메이션의 순서를 지정할 때 사용하는 종료 지연도 있다. 이는 일반적으로 이 명세의 후속 레벨에서 도입되는 시퀀스 효과와 함께 사용할 때만 유용하지만, SVG의 min 속성을 표현하기 위해 여기에 포함되어 있다([SVG11], 제19장).

애니메이션 효과종료 시간max(시작 지연 + 활성 지속 시간 + 종료 지연, 0)을 평가한 결과이다.

4.5.4. 로컬 시간

주어진 시점에서 애니메이션 효과로컬 시간은 다음 중 처음으로 일치하는 조건을 기반으로 한다:

애니메이션 효과애니메이션과 연결되어 있으면,

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

그렇지 않으면,

로컬 시간은 미해결이다.

4.5.5. 애니메이션 효과 단계 및 상태

이 절은 비규범적이다

주어진 시점에서 애니메이션 효과는 가능한 세 가지 단계 중 하나에 있을 수 있다. 애니메이션 효과로컬 시간미해결이면 어떤 단계에도 속하지 않는다.

서로 다른 단계는 아래에 나타나 있다.

애니메이션 효과를 설명하는 데 사용되는 서로 다른 단계와 상태의 예.
애니메이션 효과를 설명하는 데 사용되는 서로 다른 단계와 상태의 예.

단계는 다음과 같다:

이전 단계

애니메이션 효과로컬 시간이 효과의 활성 구간종료 시간보다 앞에 있거나, 또는 음의 시작 지연이 적용되는 범위 중에 발생한다.

활성 단계

애니메이션 효과로컬 시간이 효과의 활성 구간 안에 있고, 음의 시작 지연 또는 음의 종료 지연 범위 밖에 있다.

이후 단계

애니메이션 효과로컬 시간이 효과의 활성 구간 뒤에 있거나, 음의 종료 지연으로 인해 종료 시간이 먼저 오는 경우 그 뒤에 있지만, 음의 시작 지연이 적용되는 범위 중에는 아니다.

이러한 단계 외에도 애니메이션 효과는 서로 겹칠 수 있는 여러 상태 중 하나에 있다고 설명할 수도 있다. 이러한 상태는 하나의 애니메이션 프레임 동안에만 설정되며, 주로 모델의 상태적 부분을 설명하기 위한 편의 수단이다.

이러한 상태와 모델 내에서의 용도는 다음과 같이 요약된다:

재생 중

활성 시간이 각 프레임마다 변경되는 애니메이션 효과에 해당한다.

현재

재생 중이거나, 해당 애니메이션의 현재 재생 속도를 기반으로 향후 재생 중이 될 수 있는 애니메이션 효과에 해당한다.

효과 적용 중

해결된 활성 시간을 가진 애니메이션 효과에 해당한다. 이는 애니메이션 효과활성 단계에 있거나, 활성 단계 밖에 있지만 효과의 채우기 모드(§ 4.6 채우기 동작 참조)로 인해 활성 시간이 해결되는 시점에 발생한다. 효과 적용 중애니메이션 효과만 대상에 결과를 적용한다.

이러한 각 상태의 규범적 정의는 다음과 같다.

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

애니메이션 방향

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

활성 이전 경계 시간

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

활성 이후 경계 시간

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

애니메이션 효과로컬 시간미해결이 아니고 다음 조건 중 하나가 충족되면 해당 애니메이션 효과는 이전 단계에 있다:

  1. 로컬 시간활성 이전 경계 시간보다 작거나, 또는

  2. 애니메이션 방향이 "backwards"이고 로컬 시간활성 이전 경계 시간과 같다.

애니메이션 효과로컬 시간미해결이 아니고 다음 조건 중 하나가 충족되면 해당 애니메이션 효과는 이후 단계에 있다:

  1. 로컬 시간활성 이후 경계 시간보다 크거나, 또는

  2. 애니메이션 방향이 "forwards"이고 로컬 시간활성 이후 경계 시간과 같다.

애니메이션 효과로컬 시간미해결이 아니며, 이전 단계에도 이후 단계에도 속하지 않으면 해당 애니메이션 효과는 활성 단계에 있다.

또한 애니메이션 효과가 위의 어느 단계에도 속하지 않는 경우를 유휴 단계에 있다고 표현하면 편리한 경우가 많다.

애니메이션 효과는 다음 조건이 모두 충족되면 재생 중이다:

  1. 애니메이션 효과활성 단계에 있고, 또한

  2. 애니메이션 효과완료됨이 아닌 애니메이션과 연결되어 있다.

애니메이션 효과는 다음 조건 중 하나라도 참이면 현재이다:

애니메이션 효과는 § 4.8.3.1 활성 시간 계산의 절차에 따라 계산된 활성 시간미해결아니면 효과 적용 중이다.

4.5.6. 관련 애니메이션

애니메이션연결된 애니메이션 효과를 기반으로 해당 애니메이션이 관련됨이라고 정의할 수 있다.

애니메이션은 다음과 같은 경우 관련됨이다:

요소 또는 의사 요소 target에 대한 관련 애니메이션효과 대상target애니메이션 효과를 하나 이상 포함하는 모든 애니메이션의 집합이다.

요소, 의사 요소, 문서 또는 섀도 루트target—의 하위 트리에 대한 관련 애니메이션효과 대상target포괄적 자손(또는 target문서섀도 루트인 경우 자손)이거나 그러한 자손의 의사 요소애니메이션 효과를 하나 이상 포함하는 모든 애니메이션의 집합이다.

4.6. 채우기 동작

애니메이션 효과재생 중이 아닐 때의 효과는 그 채우기 모드에 의해 결정된다.

가능한 채우기 모드는 다음과 같다:

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

작성자는 효과가 무기한 적용되는 애니메이션을 만들기 위해 채우기 모드를 사용하는 것을 권장하지 않는다. 채우기 모드는 CSS 애니메이션 [CSS-ANIMATIONS-1]에서 정의한 animation-fill-mode 속성을 표현하기 위해 도입되었다. 그러나 이러한 모드는 애니메이션 상태가 무기한 누적되는 상황을 만들어 § 5.5 애니메이션 대체에 정의된 애니메이션의 자동 제거가 필요하게 된다. 또한 무기한 채우기를 수행하는 애니메이션은 애니메이션 스타일이 CSS 캐스케이드 [css-cascade-3]에서 우선하므로 모든 애니메이션이 완료된 뒤 오랜 시간이 지나도 지정된 스타일의 변경이 효과가 없게 만들 수 있다.

가능한 경우 작성자는 애니메이션의 최종 상태를 지정된 스타일에 직접 설정하는 것을 선호해야 한다. 이는 아래와 같이 애니메이션이 완료될 때까지 기다린 다음 스타일을 업데이트하여 달성할 수 있다:

// 다음 애니메이션이 완료된 후 첫 번째 프레임에서 콜백은
// `finished` 프로미스에 대해 스타일이 업데이트되기 전에 실행되므로
// 깜박이지 않는다.
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

애니메이션 효과가 이후 단계에 있을 때, 애니메이션 효과는 재생 중이 되도록 예정된 마지막 순간과 동일한 반복 진행률 값을 생성한다.

애니메이션 효과가 재생 중이 아닌 다른 모든 시간에는 효과가 없다.

backwards

애니메이션 효과가 이전 단계에 있을 때, 애니메이션 효과는 재생 중이 되도록 예정된 가장 이른 순간과 동일한 반복 진행률 값을 생성한다.

애니메이션 효과가 재생 중이 아닌 다른 모든 시간에는 효과가 없다.

both

애니메이션 효과가 이전 단계에 있을 때는 backwards 채우기 동작을 사용한다.

애니메이션 효과가 이후 단계에 있을 때는 forwards 채우기 동작을 사용한다.

이러한 채우기 모드의 몇 가지 예는 아래에 나타나 있다.

다양한 채우기 모드와 그로 인해 생성되는 상태의 예.
다양한 채우기 모드와 생성되는 상태의 예.
(a) 채우기 모드 "none". 애니메이션 효과는 활성 단계 밖에서 효과가 없다.
(b) 채우기 모드 "forwards". 활성 단계가 종료된 후에도 반복 진행률 값은 계속 채우기 값을 유지한다.
(c) 채우기 모드 "backwards". 애니메이션 효과는 활성 단계가 시작될 때까지 채우기 값을 생성한다.
(d) 채우기 모드 "both". 활성 단계의 이전과 이후 모두에서 애니메이션 효과가 채우기 값을 생성한다.

참고: 채우기 모드를 설정하는 것은 활성 구간의 끝점이나 단계 사이의 경계에는 영향을 주지 않는다. 그러나 채우기 모드는 타이밍 모델의 여러 다른 속성에는 영향을 준다. 애니메이션 효과의 활성 시간활성 단계 안에 있거나 또는 채우기가 적용될 때만 정의되기 때문이다(즉, 미해결이 아니다).

4.7. 반복

4.7.1. 반복 구간

애니메이션 효과가 고정된 횟수 또는 무기한 반복하도록 지정할 수 있다. 이러한 반복은 활성 구간 내에서 발생한다. 한 번의 반복이 이루어지는 시간 범위를 반복 구간이라고 한다.

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

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

이 절은 비규범적이다

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

반복 지속 시간

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

활성 지속 시간

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

반복 지속 시간활성 지속 시간 사이의 관계는 아래에 나타나 있다.

반복 지속 시간과 활성 시간의 비교.
반복 횟수가 2.5인 애니메이션 효과의 반복 지속 시간활성 지속 시간의 비교. 마지막 반복의 반복 지속 시간은 변경되지 않으며, 단지 활성 지속 시간에 의해 잘릴 뿐이라는 점에 유의한다.

4.7.2. 반복 제어

애니메이션 효과가 반복되는 횟수를 그 반복 횟수라고 한다. 반복 횟수는 0보다 크거나 같은 실수이다. 반복 횟수애니메이션 효과가 무기한 반복됨을 나타내기 위해 양의 무한대일 수도 있다.

반복 횟수 외에도 애니메이션 효과에는 반복 시퀀스에서 애니메이션 효과가 시작해야 하는 오프셋을 지정하는 반복 시작 속성도 있다. 반복 시작은 0보다 크거나 같은 유한 실수이다.

이러한 매개변수의 동작은 § 4.8 핵심 애니메이션 효과 계산의 계산에 정의되어 있다.

이 절은 비규범적이다

반복 횟수반복 시작 매개변수의 효과는 아래에 나타나 있다.

반복 횟수 및 반복 시작 매개변수의 효과
반복 횟수반복 시작 매개변수의 효과.
첫 번째 경우 반복 횟수는 2.5이며, 그 결과 세 번째 반복이 반복 구간의 절반 지점에서 잘린다.
두 번째 경우도 동일하지만 반복 시작이 0.5이다. 이로 인해 애니메이션 효과가 첫 번째 반복의 절반 지점에서 시작한다.

반복 횟수 매개변수와 달리, 반복 시작 매개변수는 활성 지속 시간의 길이에 영향을 주지 않는다.

반복 시작 값이 1보다 크거나 같은 경우는 일반적으로 반복 합성 연산accumulate애니메이션 효과와 함께 사용하는 경우를 제외하면 유용하지 않다는 점에 유의한다.

4.7.3. 반복 시간 공간

이 절은 비규범적이다

웹 애니메이션에서 모든 시간은 어떤 기준점을 기준으로 한다. 이러한 서로 다른 기준점은 서로 다른 시간 공간을 생성한다.

이는 컴퓨터 그래픽에서 사용하는 좌표 공간과 비교할 수 있다. 시간 공간의 0 시간은 좌표 공간의 원점과 유사하다.

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

반복 시간 공간은 0 시간이 애니메이션 효과의 현재 반복 시작인 시간 공간이다.

웹 애니메이션 모델에서는 활성 구간의 시작을 기준으로 하는 시간인 활성 시간도 참조한다. 그러나 이 시간 공간은 모델 내부에 있으며 프로그래밍 인터페이스나 마크업에는 노출되지 않는다.

이러한 시간 공간은 아래에 나타나 있다.

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

참고: 시간 공간 자체에는 경계가 없지만, 웹 애니메이션은 활성 시간반복 진행률이 그림에 표시된 것처럼 일정 범위로 제한되도록 정의한다. 예를 들어 -1초라는 시간은 활성 시간 공간에서 유효한 시간이지만, § 4.8.3.1 활성 시간 계산에 정의된 활성 시간 계산 절차는 음수 값을 반환하지 않는다.

이러한 시간 공간 외에도 현재 전역 객체Document기본 문서 타임라인시간 값의 시간 공간인 문서 시간 공간도 참조할 수 있다.

4.7.4. 구간 타이밍

이 절은 비규범적이다

애니메이션 효과가 반복될 때는 반복 경계에서의 동작을 정의해야 한다. 이를 위해, 그리고 실제로 모든 구간 타이밍에 대해 웹 애니메이션은 끝점 제외 타이밍 모델을 사용한다. 이는 구간의 시작 시간은 구간에 포함되지만 종료 시간은 포함되지 않음을 의미한다. 구간 표기법으로는 [begin, end)로 쓸 수 있다. 이 모델은 구간 사이에 겹침이 없으므로 구간을 반복하고 순서대로 배치할 때 합리적인 동작을 제공한다.

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

끝점 제외 타이밍의 예시.
끝점 제외 타이밍의 예시. 반복되는 애니메이션 효과와 순서대로 배치된 애니메이션 효과 모두 구간 사이의 경계에서 겹침이 없다.

이 동작의 한 가지 예외는 채우기를 수행할 때 채우기가 구간 끝점에서 시작되면 해당 끝점이 사용된다는 것이다. 이 동작은 § 4.8.3.3 단순 반복 진행률 계산에 제시된 알고리즘에서 자연스럽게 도출되며 아래에 나타나 있다.

반복과 채우기가 반복 시간에 미치는 효과.
한 번 반복한 후에는 반복 진행률이 0이지만, 두 번 반복한 후(그리고 그 이후)에는 애니메이션 효과가 채우기를 수행할 때 정의된 특수 동작으로 인해 반복 진행률이 1이다.

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

4.8.1. 개요

이 절은 비규범적이다

웹 애니메이션 타이밍 모델의 핵심에는 로컬 시간 값을 받아 반복 진행률로 변환하는 과정이 있다.

이 과정의 첫 번째 단계는 활성 지속 시간에 의해 결정되는 활성 구간의 경계를 계산하는 것이다.

이 과정은 아래에 나타나 있다.

활성 지속 시간 계산.
반복 지속 시간반복 횟수를 곱한 값을 기반으로 활성 지속 시간을 계산한다.

활성 지속 시간을 계산하는 과정은 § 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. 활성 지속 시간 계산

활성 지속 시간은 다음과 같이 계산된다:

활성 지속 시간 = iteration duration × iteration count

반복 지속 시간 또는 반복 횟수 중 하나가 0이면, 활성 지속 시간은 0이다.

IEEE 754-2008에 따르면 무한대에 0을 곱한 결과가 정의되지 않으므로 이러한 명확화가 필요하다.

4.8.3. 로컬 시간 변환

4.8.3.1. 활성 시간 계산

활성 시간로컬 시간시작 지연을 기반으로 한다. 그러나 애니메이션 효과가 출력을 생성해야 할 때만 정의되므로, 다음과 같이 그 채우기 모드와 단계에 따라 달라진다.

애니메이션 효과가 이전 단계에 있으면,

결과는 다음 중 처음으로 일치하는 조건에 따라 달라진다.

채우기 모드backwards 또는 both이면,

다음을 평가한 결과를 반환한다: max(local time - start delay, 0).

그렇지 않으면,

미해결 시간 값을 반환한다.

애니메이션 효과가 활성 단계에 있으면,

다음을 평가한 결과를 반환한다: local time - start delay.

애니메이션 효과가 이후 단계에 있으면,

결과는 다음 중 처음으로 일치하는 조건에 따라 달라진다.

채우기 모드forwards 또는 both이면,

다음을 평가한 결과를 반환한다: max(min(local time - start delay, active duration), 0).

그렇지 않으면,

미해결 시간 값을 반환한다.

그렇지 않으면(로컬 시간미해결이면),

미해결 시간 값을 반환한다.

4.8.3.2. 전체 진행률 계산

전체 진행률은 완료된 반복 횟수(부분 반복 포함)를 나타내며 다음과 같이 정의된다:

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

  2. 아래에서 처음으로 일치하는 조건을 기반으로 overall progress의 초기 값을 계산한다.

    반복 지속 시간이 0이면,

    애니메이션 효과가 이전 단계에 있으면 overall progress를 0으로 두고, 그렇지 않으면 반복 횟수와 같게 둔다.

    그렇지 않으면,

    overall progress를 다음을 계산한 결과로 둔다: active time / iteration duration.

  3. 다음을 계산한 결과를 반환한다: overall progress + iteration start.

4.8.3.3. 단순 반복 진행률 계산

단순 반복 진행률재생 방향 또는 효과에 적용되는 타이밍 함수가 시간에 도입하는 변환을 무시한 현재 반복 진행의 비율이며, 다음과 같이 계산된다:

  1. 전체 진행률미해결이면 미해결을 반환한다.

  2. 전체 진행률이 무한대이면 simple iteration progressiteration start % 1.0으로 두고, 그렇지 않으면 simple iteration progressoverall progress % 1.0으로 둔다.

  3. 다음 조건이 모두 참이면,

    simple iteration progress를 1.0으로 둔다.

    위 단계는 애니메이션의 활성 구간이 반복의 끝에서 정확히 끝날 때 다음 반복의 시작이 아니라 마지막 반복의 끝점을 유지하여 채우기를 수행하는 동작을 구현한다.

    마지막 조건은 반복 횟수가 0이어서 처음부터 애니메이션의 반복을 전혀 재생하지 않은 경우에는 이 동작이 적용되지 않도록 한다.

  4. simple iteration progress를 반환한다.

4.8.4. 현재 반복 계산

현재 반복은 다음 단계를 사용하여 계산할 수 있다:

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

  2. 애니메이션 효과가 이후 단계있고 반복 횟수가 무한대이면 무한대를 반환한다.

  3. 단순 반복 진행률이 1.0이면 다음을 반환한다: floor(overall progress) - 1.

  4. 그렇지 않으면 다음을 반환한다: floor(overall progress).

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로 두고, 그렇지 않으면 current direction을 reverse로 둔다. d가 무한대이면 current direction을 forwards로 둔다.

  3. current direction이 forwards이면 단순 반복 진행률을 반환한다.

    그렇지 않으면 1.0 - simple iteration progress를 반환한다.

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. 애니메이션 효과가 이전 단계에 있고 going forwards가 true이거나, 애니메이션 효과가 이후 단계에 있고 going forwards가 false이면 before flag가 설정된다.

  3. 방향이 적용된 진행률입력 진행률 값으로, before flagbefore 플래그로 전달하여 애니메이션 효과타이밍 함수를 평가한 결과를 반환한다.

4.11. 반복 진행률

애니메이션 효과반복 진행률은 단순히 그 변환된 진행률이다.

5. 애니메이션 모델

이 절은 비규범적이다

일부 종류의 애니메이션 효과에 대해 웹 애니메이션의 애니메이션 모델타이밍 모델이 생성한 반복 진행률현재 반복 값을 받아 해당 출력을 계산하는 데 사용한다.

그런 다음 이러한 각 애니메이션 효과의 출력은 대상 속성에 적용되기 전에 효과 스택을 사용하여 다른 효과의 출력과 결합된다 (§ 5.4 효과 결합 참조).

5.1. 소개

애니메이션 효과에는 타이밍 출력의 변경에 응답하여 영향을 미치는 0개 이상의 연결된 속성이 있다. 이러한 속성을 효과의 대상 속성이라고 한다.

반복 진행률, 현재 반복, 기저 값이 주어지면, 애니메이션 효과는 해당 속성에 적합한 애니메이션 유형의 절차를 적용하여 각 애니메이션 가능 대상 속성에 대해 효과 값을 생성한다.

5.2. 속성 애니메이션

달리 명시되지 않는 한 모든 CSS 속성은 애니메이션 가능이다. 속성 값이 결합되는 방식은 각 속성의 속성 정의 표에 있는 애니메이션 유형 행에 정의되어 있다:

애니메이션 불가
해당 속성은 애니메이션할 수 없다. 애니메이션 키프레임에 나열되어 있어도 처리되지 않으며, 전환의 영향도 받지 않는다.

참고: 속성을 애니메이션하면 과도한 복잡성이 발생하는 경우 일반적으로 애니메이션에서 제외된다. 예를 들어 애니메이션 매개변수를 정의하는 속성을 애니메이션하면 복잡한 재귀적 동작이 발생하므로 애니메이션 불가이다.

참고: 애니메이션 불가인 속성만 대상으로 하는 애니메이션 효과도 이벤트 발생 및 애니메이션현재 완료 프로미스 이행 지연과 같은 일반적인 애니메이션 효과의 동작은 여전히 나타낸다.

이산
속성의 값은 의미 있게 결합할 수 없으므로, 가산적이지 않으며, 보간은 50%(p=0.5)에서 Va에서 Vb로 전환한다. 즉,
V result = V start if p < 0.5 V end if p 0.5
계산된 값에 따라
계산된 값의 대응하는 개별 구성 요소는 해당 값 유형에 지정된 절차를 사용하여 결합(보간, 덧셈 또는 누적)된다 (CSS Values 4 § 3 값 결합: 보간, 덧셈 및 누적 참조). 구성 요소의 수나 대응하는 구성 요소의 유형이 일치하지 않거나, 어떤 구성 요소 값이 이산 애니메이션을 사용하고 대응하는 두 값이 일치하지 않으면, 속성 값은 이산 방식으로 결합된다.
반복 가능 목록
계산된 값에 따라와 동일하지만, 두 목록의 항목 수가 서로 다르면 먼저 항목 수의 최소공배수까지 반복한다. 그런 다음 각 항목을 계산된 값에 따라 결합한다. 값 쌍을 결합할 수 없거나 어떤 구성 요소 값이 이산 애니메이션을 사용하면, 속성 값은 이산 방식으로 결합된다.

참고: 반복 가능 목록 개념은 개념적으로 특정 길이까지 반복되는 목록 (예: background-originbackground-image 목록의 길이만큼 반복되는 경우) 또는 무한히 반복되는 목록이 어떤 값 사이에서도 부드럽게 전환되고, 계산된 값이 결과를 올바르게 나타내도록 (그리고 잠재적으로 올바르게 상속되도록) 보장한다.

(본문 참조)
일부 속성에는 위의 경우에 포함되지 않는 특정 보간 동작이 있으며, 이 경우 해당 속성의 애니메이션 동작은 명시적으로 지정된다.

아직 속성 정의에 애니메이션 유형 행이 포함되지 않은 속성의 애니메이션 유형부록 A: 기존 속성의 애니메이션 유형에 정의되어 있다.

5.2.1. 사용자 지정 속성

사용자 지정 속성현재 전역 객체에 대해 registerProperty() 메서드를 사용하여 등록된 경우, 애니메이션 유형계산된 값에 따라이며, 속성의 구문 정의에 사용된 유형에서 파생된다. 속성에 지정된 구문에 대응하는 계산된 값 유형이 없는 경우 (예: 구문이 범용 구문 정의인 경우) 또는 사용자 지정 속성이 등록되지 않은 경우, 애니메이션 유형이산이다.

5.3. 키프레임 효과

키프레임 효과는 타이밍 모델의 출력을 사용하여 효과 대상이라고 하는 요소 또는 의사 요소(예: ::before 또는 ::after [select])의 CSS 속성을 업데이트하는 애니메이션 효과의 한 종류이다.

효과 대상대상 요소라고 하는 Element대상 의사 선택자라고 하는 의사 요소 선택자로 구성된다. 효과 대상Element이면, 대상 요소는 해당 요소이고 대상 의사 선택자null이다. 효과 대상의사 요소이면, 대상 요소는 그 기원 요소이고 대상 의사 선택자는 해당 특정 의사 요소를 지정하는 데 필요한 값이다.

이 방식으로 지정된 모든 효과 대상(예: ::part() 의사 요소 및 지원되지 않는 의사 요소)에 계산된 속성 값이 정의되어 있는 것은 아니라는 점에 유의한다.

5.3.1. 키프레임

키프레임 효과효과 값은 분수 오프셋에 배치된 일련의 속성 값 사이를 보간하여 계산된다. 오프셋으로 색인되는 각 속성 값 집합을 키프레임이라고 한다.

키프레임의 오프셋은 [0, 1] 범위의 값 또는 특수 값 null이다. 키프레임 효과키프레임 목록은 오프셋을 기준으로 느슨하게 정렬되어야 한다. 이는 목록에서 null이 아닌 키프레임 오프셋을 가진 각 키프레임에 대해, 그 오프셋이 존재하는 경우 앞에 있는 null이 아닌 키프레임 오프셋을 가진 키프레임의 오프셋보다 크거나 같음을 의미한다.

키프레임이 겹치거나 지원되지 않는 값을 갖는 경우의 동작은 § 5.3.4 키프레임 효과의 효과 값에 정의되어 있다.

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

키프레임에는 설정된 경우 해당 키프레임에 지정된 모든 값에 적용되는 키프레임별 합성 연산이 있을 수 있다. 가능한 연산과 그 의미는 § 5.4.4 효과 합성에서 키프레임 효과 전체에 연결된 합성 연산에 대해 정의된 것과 동일하다. 키프레임키프레임별 합성 연산이 설정되지 않은 경우, 해당 키프레임에 지정된 값에는 키프레임 효과 전체에 지정된 합성 연산이 사용된다.

5.3.2. 속성 값 계산

속성 property, 값 value, 그리고 Element element가 주어졌을 때 속성 값을 계산하려면: 의존성을 해석하기 위한 컨텍스트로 element계산된 값을 사용하여 property 정의 표의 "계산된 값" 행에 따라 value를 해석하고 그 결과를 반환한다.

참고: 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효과 값에 의해 결정되고, 이는 다시 font-size에 대한 속성 값을 계산해야 한다. 따라서 속성 값 계산에는 순서 제약이 적용된다.

5.3.3. 계산된 키프레임 계산

키프레임 효과효과 값을 계산하기 전에, 그 키프레임의 속성 값이 계산되고, null인 키프레임 오프셋을 가진 모든 키프레임에 사용할 오프셋이 계산된다. 이러한 값을 해석한 결과는 계산된 키프레임 집합이다.

null인 각 키프레임 오프셋에 적합한 값을 포함하는 키프레임 집합의 계산된 키프레임 오프셋계산된 키프레임 오프셋이라고 한다.

계산된 키프레임 오프셋을 생성하기 위해, 키프레임 시퀀스 keyframes를 받아 다음 단계를 수행하는 누락된 키프레임 오프셋을 계산하는 절차를 정의한다:

  1. keyframes의 각 키프레임에 대해, 해당 키프레임계산된 키프레임 오프셋을 그 키프레임 오프셋 값과 같게 둔다.

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

  3. keyframes의 마지막 키프레임계산된 키프레임 오프셋이 null이면, 그 계산된 키프레임 오프셋을 1로 설정한다.

  4. 다음 조건을 만족하는 각 키프레임AB에 대해:

    AB 사이의 각 키프레임계산된 키프레임 오프셋을 다음과 같이 계산한다:

    1. 키프레임 k계산된 키프레임 오프셋offsetk로 둔다.

    2. nAB를 포함한 그 사이의 키프레임 수에서 1을 뺀 값으로 둔다.

    3. indexA 바로 뒤의 첫 번째 키프레임에서 1이 되도록, AB 사이 키프레임 시퀀스에서 keyframe의 위치를 index가 나타내도록 둔다.

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

계산된 키프레임은 다음 절차를 사용하여 생성된다. 이 절차는 계산된 속성 값을 계산할 수 있는 효과 대상을 가진 키프레임 효과에 대해서만 수행된다는 점에 유의한다.

  1. computed keyframes를 빈 키프레임 목록으로 둔다.

  2. 키프레임 효과에 지정된 키프레임 목록의 각 keyframe에 대해 다음 단계를 수행한다:

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

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

      예를 들어 keyframeborder-width 속성의 값으로 "12pt"가 있으면, 사용자 에이전트는 각 장축 속성인 border-bottom-width, border-left-width, border-right-width, 그리고 border-top-width에 대해 "16px"이라는 속성 값을 계산할 수 있다. 그 결과 computed keyframe에는 border-width 속성의 값이 없고, 대신 각 장축 속성이 포함되며 각각 "16px" 값을 갖게 된다.

      단축 속성을 확장하거나 논리 속성을 물리적 속성으로 대체할 때 충돌이 발생하면, 충돌이 해결될 때까지 다음 규칙을 순서대로 적용한다:

      1. 장축 속성은 단축 속성을 재정의한다(예: border-top-colorborder-top을 재정의한다).

      2. 장축 구성 요소 수가 더 적은 단축 속성이 장축 구성 요소 수가 더 많은 단축 속성을 재정의한다(예: border-topborder-color를 재정의한다).

      3. 물리적 속성이 논리 속성을 재정의한다.

      4. 장축 구성 요소 수가 동일한 단축 속성의 경우, 각 IDL 이름을 구성하는 유니코드 코드 포인트를 기준으로 오름차순 정렬했을 때 IDL 이름(CSS 속성을 IDL 속성으로 변환 알고리즘 [CSSOM] 참조)이 더 앞에 나타나는 속성이 뒤에 나타나는 속성을 재정의한다.

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

  4. computed keyframes를 반환한다.

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

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

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

  2. target property효과 값을 계산할 장축 속성으로 둔다.

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

  4. 키프레임 효과효과 대상이 없거나, 효과 대상에 대해 계산된 속성 값을 계산할 수 없으면 이 절차를 중단한다.

  5. 합성을 위한 중립 값기저 값add 합성 연산을 사용하여 결합했을 때 기저 값을 생성하는 값으로 정의한다.

  6. property-specific keyframes를 이 키프레임 효과에 대한 계산된 키프레임 집합을 가져온 결과로 둔다.

  7. target property에 대한 속성 값이 없는 모든 키프레임property-specific keyframes에서 제거한다.

  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에 추가한다. 그러한 키프레임이 없으면(예를 들어 반복 진행률이 음수인 경우), 계산된 키프레임 오프셋이 0인 마지막 키프레임을 추가한다.

    2. 이전 단계에서 추가한 키프레임 다음에 있는 property-specific keyframes의 다음 키프레임interval endpoints에 추가한다.

  13. interval endpoints의 각 keyframe에 대해:

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

      1. composite operation to usekeyframe합성 연산으로 두고, 해당 연산이 없으면 이 키프레임 효과합성 연산으로 둔다.

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

      3. keyframetarget property 속성 값을, target property애니메이션 유형에 대응하는 composite operation to use의 절차를 사용하여 underlying value (Va)와 value to combine (Vb)을 결합한 결과로 대체한다.

  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 값에 대해, 첫 번째 값을 Vstart로, 두 번째 값을 Vend로 하고 transformed distance를 보간 매개변수 p로 사용하여, target property애니메이션 유형에서 정의한 보간 절차를 적용한 결과를 반환한다.

이 절차는 효과에 지정된 키프레임 목록에 대해 다음을 가정한다는 점에 유의한다:

이러한 조건이 충족되도록 보장하는 것은 모델 사용자(예: 선언적 마크업 또는 프로그래밍 인터페이스)의 책임이다.

예를 들어 이 명세에서 정의하는 프로그래밍 인터페이스의 경우, 이 절차의 입력이 되는 계산된 키프레임을 생성하는 절차에 의해 이러한 조건이 충족된다.

참고: 이 절차는 겹치는 키프레임을 허용한다. 겹치는 지점에서는 출력 값이 해당 오프셋에서 마지막으로 정의된 키프레임의 값으로 점프한다. 0 또는 1에서 겹치는 키프레임의 경우, 반복 진행률 값이 0보다 작거나 1보다 크거나 같은 경우의 출력 값은 각각 keyframes의 첫 번째 키프레임 또는 마지막 키프레임의 값이다.

계산된 키프레임은 "라이브"라는 점에 유의한다: 사용자 에이전트는 효과 값이 계산될 때마다 키프레임이 다시 생성되는 것처럼 동작해야 한다.

예를 들어 font-size 속성에 10px에서 20px로 진행 중인 전환이 있다면, 키프레임1em으로 지정된 속성 값은 키프레임 계산font-size의 전환에서 생성되는 [10px, 20px] 범위의 계산된 값을 기준으로 해석된다.

특정 타이밍 함수가 존재하는 경우, 애니메이션 효과에 입력되는 반복 진행률은 [0, 1] 범위로 제한되지 않는다. 그러나 현재 키프레임 오프셋은 여전히 [0, 1] 범위로 제한되며, 이 범위를 벗어난 입력 반복 진행률 값에 대해서는 속성 값이 단순히 외삽된다.

반복 진행률 값이 [0, 1] 범위를 벗어난 곳에서 속성 값의 비선형 변화를 지정할 수 있는 것이 유용한 경우가 있으므로 이 제한을 제거하는 방안을 검토했다. 한 가지 예는 녹색에서 노란색으로 보간하지만 오버슈트 타이밍 함수 때문에 일시적으로 노란색을 "넘어" 빨간색까지 보간한 다음 다시 노란색으로 돌아오는 애니메이션이다.

키프레임과 타이밍 함수를 수정하여 이 효과를 구현할 수는 있지만, 이 접근 방식은 타이밍 관련 사항과 애니메이션 효과를 분리하는 모델의 구조를 깨는 것으로 보인다.

이 효과를 어떻게 구현해야 하는지는 명확하지 않지만, [0, 1] 밖의 키프레임 오프셋을 허용하면 필요에 따라 오프셋 0과 1의 키프레임을 합성하도록 현재 지정된 동작과 일관되지 않을 수 있다는 점에 유의한다.

2013년 도쿄 F2F 회의록 논의의 4절([0, 1] 밖의 키프레임 오프셋)을 참조한다.

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

5.4. 효과 결합

이 절은 비규범적이다

키프레임 효과효과 값을 계산한 후, 이 값은 애니메이션 효과대상 속성에 적용된다.

동일한 속성을 대상으로 하는 여러 효과 적용 중키프레임 효과가 있을 수 있으므로 여러 키프레임 효과의 결과를 함께 결합해야 하는 경우가 많다. 이 과정을 합성이라고 하며, 효과 적용 중애니메이션 효과가 대상으로 하는 각 속성에 대해 효과 스택을 설정하는 것을 기반으로 한다.

키프레임 효과의 결과를 함께 합성한 후, 합성된 결과는 대상 속성에 지정된 다른 값과 결합된다.

이 구성은 아래에 나타나 있다:

효과 값을 대상 속성에 적용하는 과정의 개요
효과 값을 그 대상 속성에 적용하는 과정의 개요.
동일한 속성을 대상으로 하는 키프레임 효과의 결과는 효과 스택을 사용하여 함께 합성된다.
그런 다음 이 합성 결과는 적절한 지점에서 CSS 캐스케이드에 삽입된다.

이 연산의 첫 번째 부분, 즉 동일한 속성을 대상으로 하는 효과 값을 결합하려면 키프레임 효과가 서로 어떻게 결합되는지뿐만 아니라, 적용되는 순서, 즉 상대적 합성 순서도 결정해야 한다.

효과 값어떻게 결합할지는 해당 키프레임 효과합성 연산에 의해 결정된다.

효과 값의 상대적 합성 순서는 각 애니메이션된 속성에 대해 설정된 효과 스택에 의해 결정된다.

5.4.1. 애니메이션 클래스

이 명세는 이 모델을 기반으로 마크업 또는 프로그래밍 인터페이스를 정의하는 다른 명세에서 사용하도록 의도된 공통 애니메이션 모델을 제공한다. 애니메이션을 생성한 특정 마크업 또는 프로그래밍 인터페이스가 그 애니메이션 클래스를 정의한다.

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

이 절은 비규범적이다

예를 들어 클래스가 "CSS animation"인 애니메이션은 클래스가 "CSS transition"인 애니메이션보다 높은 합성 순서를 갖지만, 특정 클래스가 없는 다른 애니메이션보다는 낮은 합성 순서를 갖는 것으로 정의된다.

"CSS animation" 객체 집합 내에서는 animation-name 속성을 비롯한 여러 요소를 기반으로 특수한 합성 순서가 정의된다.

5.4.2. 효과 스택

효과 스택은 하나 이상의 키프레임 효과대상으로 하는 각 속성에 연결된다. 효과 스택키프레임 효과의 상대적 합성 순서를 설정한다.

키프레임 효과 AB 두 개의 상대적 합성 순서효과 스택 내에서 다음과 같이 그 속성을 비교하여 설정된다:

  1. 애니메이션 효과의 연관 애니메이션애니메이션 효과연결된 애니메이션으로 둔다.

  2. 순서가 결정될 때까지 다음 조건을 차례로 적용하여 AB를 정렬한다.

    1. AB연관 애니메이션클래스가 다르면, 해당 클래스에 대해 정의된 클래스 간 합성 순서에 따라 정렬한다.

    2. AB가 여전히 정렬되지 않았으면, AB연관 애니메이션이 공유하는 클래스에 대해 정의된 클래스별 합성 순서에 따라 정렬한다.

    3. AB가 여전히 정렬되지 않았으면, 전역 애니메이션 목록에서 그 연관 애니메이션의 위치에 따라 정렬한다.

더 앞에 정렬되는 애니메이션 효과더 낮은 합성 순서를 갖는다.

5.4.3. 효과 스택 결과 계산

효과 스택의 최종 값을 계산하기 위해, 스택의 각 키프레임 효과효과 값을 합성 순서에 따라 결합한다.

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

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

효과 스택의 최종 값인 합성된 값은 단순히 스택의 마지막 (가장 높은 합성 순서의) 키프레임 효과효과 값을 그 시점의 기저 값과 결합한 결과이다.

5.4.4. 효과 합성

효과 값기저 값과 결합하는 데 사용되는 특정 연산은 해당 효과 값을 생성한 키프레임 효과합성 연산에 의해 결정된다.

이 명세는 다음과 같이 세 가지 합성 연산을 정의한다:

replace

효과 값기저 값과 합성한 결과는 단순히 효과 값이다.

add

효과 값기저 값더해진다. 덧셈 연산이 교환 법칙을 만족하지 않도록 정의된 애니메이션 유형의 경우, 피연산자의 순서는 기저 값 + 효과 값이다.

accumulate

효과 값기저 값누적된다. 누적 연산이 교환 법칙을 만족하지 않도록 정의된 애니메이션 유형의 경우, 피연산자의 순서는 기저 값 다음에 효과 값이 오는 순서이다.

5.4.5. 합성된 결과 적용

합성된 값대상 속성에 적용하는 것은 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 채우기 애니메이션을 생성하여, 빠르게 수백 개, 심지어 수천 개의 forwards 채우기 애니메이션을 생성한다.

사용자 에이전트가 이러한 애니메이션을 모두 유지해야 한다면, 애니메이션 목록은 제한 없이 증가하여 메모리 누수를 발생시킨다.

이 절에서는 작성자가 명시적으로 유지하도록 요청하지 않는 한 재정의된 애니메이션이 자동으로 제거되도록 하는 메커니즘을 정의한다.

5.5.1. 대체 상태

애니메이션은 다음 값 중 하나일 수 있는 대체 상태를 유지한다:

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

대체 상태제거됨애니메이션애니메이션 효과는 그 대상 속성효과 스택에 포함되지 않는다.

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

애니메이션은 다음 조건이 모두 참이면 대체 가능이다:

Document doc에 대해 대체된 애니메이션을 제거하도록 요청되면, 다음 조건을 만족하는 모든 애니메이션 animation에 대해:

다음 단계를 수행한다:

  1. animation대체 상태제거됨으로 설정한다.

  2. AnimationPlaybackEvent, removeEvent생성한다.

  3. removeEventtype 속성을 remove로 설정한다.

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

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

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

    그렇지 않으면 animation에서 removeEvent디스패치하도록 태스크를 큐에 넣는다. 이 태스크의 태스크 소스는 DOM 조작 태스크 소스이다.

5.6. 애니메이션의 부작용

현재이거나 효과 적용 중인 하나 이상의 애니메이션 효과가 대상으로 하고, 대체 상태제거됨아닌 애니메이션과 연결된 모든 속성에 대해, 사용자 에이전트는 효과 대상will-change 속성([css-will-change-1])에 해당 속성이 포함된 것처럼 동작해야 한다.

이 절은 비규범적이다

위 요구사항의 결과로, 예를 들어 애니메이션이 요소의 transform 속성을 대상으로 하면, 애니메이션이전 단계, 활성 단계, 또는 채우기 모드가 "forwards" 또는 "both"인 경우 이후 단계에 있는 동안 효과 대상쌓임 맥락이 생성된다.

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

이 절은 비규범적이다

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

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

시간 값은 프로그래밍 인터페이스에서 double 유형으로 표현된다. 미해결 시간 값은 null 값으로 표현된다.

6.2. AnimationTimeline 인터페이스

타임라인은 웹 애니메이션 API에서 AnimationTimeline 인터페이스로 표현된다.

[Exposed=Window]
interface AnimationTimeline {
    readonly attribute double? currentTime;
};
currentTime, 유형은 double, 읽기 전용, null 허용

이 타임라인의 현재 시간을 반환하거나, 이 타임라인이 비활성이면 null을 반환한다.

6.3. DocumentTimeline 인터페이스

문서 타임라인기본 문서 타임라인을 포함하여 웹 애니메이션 API에서 DocumentTimeline 인터페이스로 표현된다.

dictionary DocumentTimelineOptions {
  DOMHighResTimeStamp originTime = 0;
};

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

타임라인의 원점 시간으로, 시간 원점을 기준으로 한 밀리초의 실수로 지정된다.

DocumentTimeline (options)

DocumentTimeline을 생성한다. 타임라인과 연결되는 Document현재 전역 객체Window연결된 Document이다.

options

새로 생성된 타임라인의 구성 매개변수. 이 명세는 originTime 멤버만 정의하지만 다른 명세에서 이 집합을 확장할 수 있다.

6.4. Animation 인터페이스

애니메이션은 웹 애니메이션 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. timelinenew timeline으로 전달하여 animation에 대해 애니메이션의 타임라인을 설정하는 절차를 실행한다. 또는 timeline 인수가 누락된 경우, 현재 전역 객체Window연결된 Document기본 문서 타임라인을 전달한다.

  3. sourcenew effect로 전달하여 animation에 대해 애니메이션의 연관 효과를 설정하는 절차를 실행한다.

effect

null이 아닌 경우 새로 생성된 애니메이션에 할당할 연관 효과를 지정하는 선택적 값.

timeline

존재하는 경우 새로 생성된 애니메이션과 연결할 타임라인을 지정하는 선택적 값. 누락된 경우 현재 전역 객체Window연결된 Document기본 문서 타임라인이 사용된다.

id, 유형은 DOMString

애니메이션을 식별하는 데 사용되는 문자열.

effect, 유형은 AnimationEffect, null 허용

이 애니메이션의 연관 효과. 이 속성을 설정하면 애니메이션의 연관 효과를 설정하는 절차를 사용하여 객체의 연관 효과를 업데이트한다.

timeline, 유형은 AnimationTimeline, null 허용

이 애니메이션과 연결된 타임라인. 이 속성을 설정하면 애니메이션의 타임라인을 설정하는 절차를 사용하여 객체의 타임라인을 업데이트한다.

startTime, 유형은 double, null 허용

이 애니메이션의 시작 시간을 반환한다. 이 속성을 설정하면 시작 시간을 설정하는 절차를 사용하여 이 객체의 시작 시간을 새 값으로 업데이트한다.

currentTime, 유형은 double, null 허용

이 애니메이션의 현재 시간. 이 속성을 설정하면 현재 시간을 설정하는 절차에 따라 이 객체의 현재 시간을 새 값으로 설정한다.

playbackRate, 유형은 double

이 애니메이션의 재생 속도. 이 속성을 설정하면 재생 속도를 설정하는 절차에 따라 이 객체의 재생 속도를 새 값으로 설정한다.

이 속성을 설정하면 재생 속도가 동기적으로 업데이트된다. 즉, 별도의 프로세스나 스레드에서 실행 중인 애니메이션의 재생 상태와 동기화하려는 시도를 하지 않는다. 따라서 실행 중인 애니메이션의 playbackRate를 설정하면 애니메이션이 점프할 수 있다.

실행 중인 애니메이션의 재생 속도가 부드럽게 업데이트되도록 설정하려면, 비동기 updatePlaybackRate() 메서드를 사용한다.

playState, 유형은 AnimationPlayState, 읽기 전용

이 애니메이션의 재생 상태.

replaceState, 유형은 AnimationReplaceState, 읽기 전용

이 애니메이션의 대체 상태.

pending, 유형은 boolean, 읽기 전용

이 애니메이션에 대기 중인 재생 태스크 또는 대기 중인 일시 중지 태스크가 있으면 true를 반환한다.

ready, 유형은 Promise<Animation>, 읽기 전용

이 객체의 현재 준비 프로미스를 반환한다.

finished, 유형은 Promise<Animation>, 읽기 전용

이 객체의 현재 완료 프로미스를 반환한다.

onfinish, 유형은 EventHandler

finish 이벤트의 이벤트 핸들러.

oncancel, 유형은 EventHandler

cancel 이벤트의 이벤트 핸들러.

onremove, 유형은 EventHandler

remove 이벤트의 이벤트 핸들러.

void cancel()

이 객체에 대해 애니메이션을 취소하는 절차를 실행하여 이 애니메이션으로 인해 발생한 모든 효과를 지우고 재생을 중단한다.

void finish()

이 객체에 대해 애니메이션을 완료하는 절차를 실행하여 현재 방향에서 애니메이션을 연관 효과 종료로 탐색한다.

InvalidStateError 유형의 DOMException

이 애니메이션의 재생 속도가 0이거나, 이 애니메이션의 재생 속도가 > 0이고 연관 효과 종료가 무한대이면 발생한다.

void play()

auto-rewind 플래그의 값으로 true를 전달하여 애니메이션을 재생하는 절차를 실행함으로써 애니메이션 재생을 시작하거나 재개한다.

void pause()

이 객체에 대해 애니메이션을 일시 중지하는 절차를 실행하여 이 애니메이션의 재생을 중지한다.

void updatePlaybackRate(playbackRate)

playbackRatenew playback rate으로 전달하여 재생 속도를 매끄럽게 업데이트하는 절차를 수행함으로써 이 애니메이션의 재생 속도를 비동기적으로 업데이트한다.

playbackRate

사용할 업데이트된 재생 속도를 지정하는 유한 실수.

void reverse()

이 애니메이션의 재생 속도를 반전시키고, 이 객체에 대한 애니메이션을 역재생하는 절차를 사용하여 재생한다. play()와 마찬가지로 이 메서드는 애니메이션의 일시 중지를 해제하고, 애니메이션이 이미 반대 방향으로 재생을 완료한 경우 연관 효과의 시작으로 탐색한다.

void persist()

이 애니메이션의 대체 상태유지됨으로 설정한다.

void commitStyles()

계산된 스타일을 커밋하는 절차를 사용하여 이 애니메이션의 애니메이션 효과가 생성한 현재 효과 값을 해당 효과 대상의 인라인 스타일에 기록한다.

이 인터페이스에 정의된 대부분의 다른 메서드와 달리, 이 메서드를 호출하면 실제로 스타일 변경 이벤트가 트리거된다(§ 6.13 모델 활성성 참조).

계산된 스타일을 커밋하는 절차는 애니메이션이 제거됨 상태인 경우에도 해당 애니메이션의 효과 값을 포함하므로, 이 메서드는 실제 애니메이션을 유지하지 않고도 대체된 후(§ 5.5.2 대체된 애니메이션 제거 참조) 애니메이션의 효과를 유지하는 데 유용하다.

커밋되는 값은 이 메서드가 호출되는 시점에 애니메이션 효과가 생성한 계산된 값이라는 점에 유의한다. 이러한 값은 계산된 값이므로, 라이브 애니메이션이 생성하는 값과 달리 CSS 변수의 변경에 응답하거나 계산된 font-size의 변경을 기반으로 em 단위를 다시 계산하는 것과 같은 컨텍스트 변경을 반영하지 않는다.

대체된 후(§ 5.5 애니메이션 대체 참조) 채우기 애니메이션 결과의 완전한 충실도를 유지하려면 persist() 메서드를 사용할 수 있지만, 그렇게 하면 애니메이션이 계속 리소스를 소비한다는 점에 유의한다.

애니메이션 animation에 대해 계산된 스타일을 커밋하려면:

  1. targetsanimation연결된 애니메이션 효과의 모든 효과 대상집합으로 둔다.

  2. targets의 각 target에 대해 반복한다:

    1. targetstyle 속성 [CSS-STYLE-ATTR]을 가질 수 있는 요소가 아니면 (예를 들어 의사 요소이거나, style 속성이 정의되지 않은 문서 형식의 요소인 경우) "NoModificationAllowedError" DOMException던지고 이 단계를 중단한다.

    2. 대기 중인 모든 스타일 변경을 적용한 후 target렌더링 중이 아니면, "InvalidStateError" DOMException던지고 이 단계를 중단한다.

      display: contents와 관련된 렌더링 중 [HTML]의 정의는 아직 논의 중이다. 이 절차의 목적상, 다른 경우라면 연관된 레이아웃 박스를 가질 display: contents인 요소 (즉, 연결되어 있고 display: none 하위 트리의 일부가 아닌 요소)는 렌더링 중이라고 가정한다.

    3. inline styletargetstyle 속성에 대응하는 CSS 선언 블록을 가져온 결과로 둔다. targetstyle 속성가지지 않으면, inline style소유자 노드target으로 설정된 새로운 빈 CSS 선언 블록으로 둔다.

    4. targeted propertiesanimation연결되어 있고 효과 대상target인 하나 이상의 애니메이션 효과대상 속성인 물리적 장축 속성의 집합으로 둔다.

    5. targeted properties의 각 속성 property에 대해:

      1. partialEffectStacktargetproperty에 대한 효과 스택의 복사본으로 둔다.

      2. animation대체 상태제거됨이면, animation연결되어 있고, 효과 대상target이며 property대상 속성으로 포함하는 모든 애니메이션 효과partialEffectStack에 추가한다.

      3. partialEffectStack에서 연결된 애니메이션합성 순서animation보다 높은 모든 애니메이션 효과를 제거한다.

      4. effect valuetarget의 계산된 스타일을 사용하여 property에 대한 partialEffectStack의 결과를 계산한 값으로 둔다 (§ 5.4.3 효과 스택 결과 계산 참조).

      5. inline style에서 effect value에 대한 property CSS 선언을 설정한다.

    6. inline style에 대해 style 속성을 업데이트한다.

6.4.1. AnimationPlayState 열거형

enum AnimationPlayState { "idle", "running", "paused", "finished" };
idle

유휴 재생 상태에 대응한다.

running

실행 중 재생 상태에 대응한다.

paused

일시 중지됨 재생 상태에 대응한다.

finished

완료됨 재생 상태에 대응한다.

6.4.2. AnimationReplaceState 열거형

enum AnimationReplaceState { "active", "removed", "persisted" };
active

활성 대체 상태에 대응한다.

removed

제거됨 대체 상태에 대응한다.

persisted

유지됨 대체 상태에 대응한다.

6.5. AnimationEffect 인터페이스

애니메이션 효과는 웹 애니메이션 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에 유지하고 단순히 애니메이션 효과를 그 애니메이션에서 제거하는 것으로 정의해야 하는가? [이슈 #2082]

6.5.1. EffectTimingOptionalEffectTiming 딕셔너리

EffectTiming 딕셔너리는 AnimationEffect의 타이밍 속성을 나타낸다.

OptionalEffectTiming 딕셔너리는 일부 멤버가 존재하지 않을 수 있도록 하는 EffectTiming 딕셔너리의 변형이다. 이는 AnimationEffect 인터페이스의 updateTiming() 메서드에서 애니메이션 효과의 타이밍 속성을 델타 업데이트하는 데 사용된다.

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보다 크거나 같은 경우는 일반적으로 반복 합성 연산accumulate인 애니메이션 효과와 함께 사용하거나, 현재 반복 인덱스가 다른 이유로 중요한 경우에만 유용하다는 점에 유의한다.

iterations, 유형은 unrestricted double, 기본값은 1.0

애니메이션 효과반복 횟수 속성으로, 애니메이션 효과가 반복되는 횟수를 나타내는 0보다 크거나 같은 실수(양의 무한대 포함)이다.

+Infinity로 설정하면 애니메이션 효과가 영원히 반복되도록 할 수 있다(효과의 지속 시간이 0인 경우에는 즉시 완료된다).

duration, 유형은 (unrestricted double or DOMString), 기본값은 "auto"

애니메이션 효과의 한 번의 반복을 완료하는 데 걸리는 시간을 나타내는 0보다 크거나 같은 실수(양의 무한대 포함)인 반복 지속 시간.

이 명세의 이 레벨에서는 문자열 값 auto를 타이밍 모델 계산과 getComputedTiming()에서 반환되는 duration 멤버의 결과에 대해 0으로 취급한다. 그러나 작성자가 auto 값을 지정한 경우 사용자 에이전트는 getTiming()에서 반환되는 duration 멤버에 대해 auto를 반환해야 한다.

이는 이 명세의 향후 레벨에서 auto 값이 자식 효과의 지속 시간을 포함하도록 확장되는 그룹 효과가 도입될 것으로 예상되기 때문에 마련된 순방향 호환성 조치이다.

direction, 유형은 PlaybackDirection, 기본값은 "normal"

각 반복에서 재생이 순방향, 역방향 또는 교대로 진행되는지를 정의하는 애니메이션 효과재생 방향.

easing, 유형은 DOMString, 기본값은 "linear"

이징 효과를 생성하기 위해 시간을 스케일링하는 데 사용되는 타이밍 함수.

문자열의 구문은 <easing-function> 생성 규칙 [CSS-EASING-1]에 의해 정의된다.

6.5.2. FillMode 열거형

enum FillMode { "none", "forwards", "backwards", "both", "auto" };
none

채우기 없음.

forwards

순방향으로 채운다.

backwards

역방향으로 채운다.

both

역방향과 순방향으로 채운다.

auto

채우기 없음. 이 명세의 후속 레벨에서는 다른 유형의 애니메이션 효과에 대해 다른 동작을 생성할 수 있다.

6.5.3. PlaybackDirection 열거형

enum PlaybackDirection { "normal", "reverse", "alternate", "alternate-reverse" };
normal

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

reverse

모든 반복은 지정된 순서의 반대 방향으로 재생된다.

alternate

짝수 반복은 지정된 대로 재생되고, 홀수 반복은 지정된 순서의 반대 방향으로 재생된다.

alternate-reverse

짝수 반복은 지정된 순서의 반대 방향으로 재생되고, 홀수 반복은 지정된 대로 재생된다.

6.5.4. AnimationEffect의 타이밍 업데이트

EffectTiming 또는 OptionalEffectTiming 객체 input에서 effect애니메이션 효과의 타이밍 속성을 업데이트하려면 다음 단계를 수행한다:

  1. inputiterationStart 멤버가 존재하고 0보다 작으면 TypeError던지고 이 절차를 중단한다.

    참고: RangeError가 아니라 TypeError를 사용하는 이유는 향후 WebIDL의 [EnforceRange] 주석을 부동 소수점 값과 함께 사용할 수 있게 될 경우 그 동작을 따르기 위해서이다.

  2. inputiterations 멤버가 존재하고, 0보다 작거나 값이 NaN이면 TypeError던지고 이 절차를 중단한다.

  3. inputduration 멤버가 존재하고, 0보다 작거나 값이 NaN이면 TypeError던지고 이 절차를 중단한다.

  4. inputeasing 멤버가 존재하지만 <easing-function> 생성 규칙 [CSS-EASING-1]을 사용하여 구문 분석할 수 없으면 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

0 로컬 시간 이후의 밀리초로 표현된 애니메이션 효과종료 시간 (즉, 이 애니메이션 효과애니메이션과 연결되어 있으면 연결된 애니메이션시작 시간 이후). 이는 애니메이션 효과의 활성 구간 끝에 모든 종료 지연을 더한 값에 해당한다.

activeDuration, 유형은 unrestricted double

애니메이션 효과활성 지속 시간.

localTime, 유형은 double, null 허용

애니메이션 효과로컬 시간.

애니메이션 효과애니메이션과 연결되어 있지 않으면 null이다.

progress, 유형은 double, null 허용

애니메이션 효과의 현재 반복 진행률.

currentIteration, 유형은 unrestricted double, null 허용

첫 번째 반복을 0으로 시작하는 현재 반복 인덱스.

대부분의 경우 이는 (양의) 정수이다. 그러나 지속 시간이 0이고 무한히 반복되는 애니메이션의 경우 값은 양의 Infinity이다.

미해결 시간과 마찬가지로, 미해결 현재 반복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 설정자에 대해 정의된 오류 처리가 적용된다. 설정자가 예외를 던지도록 요구하는 경우 이 절차는 동일한 예외를 던지고 이후 모든 단계를 중단해야 한다.

    그렇지 않으면,

    대상 의사 선택자null로 설정한다.

  4. timing input을 아래에서 처음으로 일치하는 조건에 대응하는 결과로 둔다.

    optionsKeyframeEffectOptions 객체이면,

    timing inputoptions로 둔다.

    그렇지 않으면(optionsdouble이면),

    timing input을 모든 멤버가 기본값으로 설정되고 durationoptions로 설정된 새 EffectTiming 객체로 둔다.

  5. timing input에서 effect애니메이션 효과의 타이밍 속성을 업데이트하는 절차를 호출한다.

    그 절차에서 예외가 발생하면 예외를 전파하고 이 절차를 중단한다.

  6. optionsKeyframeEffectOptions 객체이면, effectcomposite 속성에 options의 대응하는 값을 할당한다.

    이 속성을 할당할 때 KeyframeEffect 인터페이스의 해당 설정자에 대해 정의된 오류 처리가 적용된다. 설정자가 options에 지정된 값에 대해 예외를 던지도록 요구하면, 이 절차는 동일한 예외를 던지고 이후 모든 단계를 중단해야 한다.

  7. keyframes를 입력으로 전달하여 setKeyframes()에 정의된 절차를 수행함으로써 키프레임 집합을 초기화한다.

Element? target

대상 요소. 특정 요소를 대상으로 하지 않는 애니메이션의 경우 null일 수 있다.

object? keyframes

사용할 키프레임 집합. 이 인수의 형식과 처리는 § 6.6.3 키프레임 인수 처리에 정의되어 있다.

optional KeyframeEffectOptions options

효과의 반복 지속 시간을 지정하는 숫자이거나, 효과의 타이밍과 동작을 지정하는 속성 모음.

이 생성자의 사용 예는 § 6.6.1 새 KeyframeEffect 객체 생성에 제시되어 있다.

KeyframeEffect (source)

다음 절차를 사용하여 source와 동일한 속성을 가진 새 KeyframeEffect 객체를 생성한다:

  1. KeyframeEffect 객체 effect를 생성한다.

  2. source의 대응하는 값을 사용하여 effect의 다음 속성을 설정한다:

    참고: KeyframeEffect(target, keyframes, options) 생성자와 달리, source에 지정된 타이밍 속성이 유효하다고 가정할 수 있으므로 예외를 다시 던질 필요가 없다.

KeyframeEffect source

키프레임 효과를 정의하는 속성을 복사해 올 키프레임 효과.

target, 유형은 Element, null 허용

이 객체가 애니메이션하는 대상 요소 (효과 대상Element이면 효과 대상 자체이고, 의사 요소이면 그 기원 요소). 오디오 API를 사용하여 소리를 생성하는 애니메이션처럼 특정 요소를 대상으로 하지 않는 애니메이션의 경우 null일 수 있다.

pseudoElement, 유형은 CSSOMString, null 허용

대상 의사 선택자. 이 효과에 효과 대상이 없거나, 효과 대상이 요소인 경우 (즉, 의사 요소가 아닌 경우) null이다. 효과 대상이 의사 요소인 경우, 이 값은 의사 요소 선택자(예: ::before)를 지정한다.

설정할 때는 다음 예외를 적용한 후 애니메이션 효과대상 의사 선택자를 제공된 값으로 설정한다:

  • 제공된 값이 null이 아니고 유효하지 않은 <pseudo-element-selector>이면, 사용자 에이전트는 오류 이름이 SyntaxErrorDOMException던지고, 이 애니메이션 효과대상 의사 선택자를 변경하지 않아야 한다.

    참고: 이 컨텍스트에서 유효하지 않음은 [SELECTORS-4]에 정의된 유효하지 않은 선택자의 정의를 따른다. 따라서 구문상 유효하지 않은 의사 요소뿐만 아니라 사용자 에이전트가 사용 가능한 수준으로 지원하지 않는 의사 요소도 모두 유효하지 않은 것으로 간주된다.

  • 레거시 Selectors Level 2의 단일 콜론 선택자 (':before', ':after', ':first-letter' 또는 ':first-line') 중 하나가 지정되면, 대상 의사 선택자는 이에 대응하는 이중 콜론 선택자(예: '::before')로 설정되어야 한다.

composite, 유형은 CompositeOperation

CompositeOperation 열거형 값 중 하나로 지정되는, 이 키프레임 효과효과 스택과 합성하는 데 사용되는 합성 연산.

설정할 때는 이 애니메이션 효과합성 연산 속성을 제공된 값으로 설정한다.

sequence<object> getKeyframes()

이 효과를 구성하는 키프레임을 그 계산된 키프레임 오프셋과 함께 반환한다.

이 절은 비규범적이다

이 메서드의 결과는 다음 형식의 객체 시퀀스이다:

dictionary ComputedKeyframe {
    // ... 속성-값 쌍 ...
    // 즉, 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. keyframes의 각 keyframe에 대해 다음 단계를 수행한다:

    1. 다음 정의를 사용하여 딕셔너리 객체 output keyframe을 초기화한다:

      dictionary BaseComputedKeyframe {
           double?                  offset = null;
           double                   computedOffset;
           DOMString                easing = "linear";
           CompositeOperationOrAuto composite = "auto";
      };
      
    2. output keyframeoffset, computedOffset, easing, 및 composite 멤버를 각각 keyframe키프레임 오프셋, 계산된 키프레임 오프셋, 키프레임별 타이밍 함수, 그리고 키프레임별 합성 연산 값으로 설정한다.

    3. keyframe의 각 애니메이션 속성-값 쌍 declaration에 대해 다음 단계를 수행한다:

      1. declaration의 속성 이름에 애니메이션 속성 이름을 IDL 속성 이름으로 변환하는 알고리즘을 적용한 결과를 property name으로 둔다.

      2. declarationCSS 값을 직렬화하는 알고리즘 [CSSOM]에 전달하여 declaration의 속성 값을 직렬화한 결과를 IDL value로 둔다.

      3. IDL value를 ECMAScript String 값으로 변환한 결과를 value로 둔다.

      4. output keyframe에서 속성 이름 property name, Property Descriptor { [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true, [[Value]]: value } 및 불리언 플래그 false[[DefineOwnProperty]] 내부 메서드를 호출한다.

    4. output keyframeresult에 추가한다.

  4. result를 반환한다.

void setKeyframes(object? keyframes)

이 효과를 구성하는 키프레임 집합을 대체한다.

object? keyframes

형식과 처리가 § 6.6.3 키프레임 인수 처리에 정의된 일련의 키프레임.

이 효과의 키프레임 집합은 키프레임 인수를 처리하는 절차를 수행한 결과로 대체된다. 해당 절차에서 예외가 발생하면 이 효과의 키프레임은 수정되지 않는다.

6.6.1. KeyframeEffect 객체 생성

이 절은 비규범적이다

KeyframeEffect 생성자는 새 KeyframeEffect 객체를 생성하는 여러 방법을 제공한다.

가장 단순한 형태로, elem의 "left" 속성을 3초에 걸쳐 100px로 변경하는 KeyframeEffect 객체는 다음과 같이 생성할 수 있다:

var effect = new KeyframeEffect(elem, { left: '100px' }, 3000);

키프레임 목록을 나타내는 두 번째 매개변수는 여러 속성을 지정할 수 있다. (§ 6.6.3 keyframes 인수 처리 참조.)

// 여러 속성을 한 번에 지정한다
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 });

지속 시간을 지정하지 않으면 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 이름

property에 대한 애니메이션 속성 이름을 IDL 속성 이름으로 변환하는 알고리즘은 다음과 같다:

  1. property<custom-property-name> 생성 규칙을 따르면, property를 반환한다.

  2. property가 CSS float 속성을 가리키면, 문자열 "cssFloat"를 반환한다.

  3. property가 CSS offset 속성을 가리키면, 문자열 "cssOffset"을 반환한다.

  4. 그렇지 않으면 propertyCSS 속성을 IDL 속성으로 변환하는 알고리즘 [CSSOM]을 적용한 결과를 반환한다.

attribute에 대한 IDL 속성 이름을 애니메이션 속성 이름으로 변환하는 알고리즘은 다음과 같다:

  1. attribute<custom-property-name> 생성 규칙을 따르면, attribute를 반환한다.

  2. attribute가 문자열 "cssFloat"이면, CSS float 속성을 나타내는 애니메이션 속성을 반환한다.

  3. attribute가 문자열 "cssOffset"이면, CSS offset 속성을 나타내는 애니메이션 속성을 반환한다.

  4. 그렇지 않으면 attributeIDL 속성을 CSS 속성으로 변환하는 알고리즘 [CSSOM]을 적용한 결과를 반환한다.

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 객체를 사용하여 지정되는 키프레임 효과의 전체 반복 지속 시간에 적용되는 타이밍 함수와는 독립적이다(Animatable 인터페이스 믹스인의 animate() 메서드를 사용할 때는 KeyframeAnimationOptions 객체).

다음 예에서 두 문은 서로 다른 결과를 생성한다.

// 여기서는 각 색상 값 사이에 'ease-in-out'이 적용된다.
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 {
    // ... 속성-값 쌍 ...
    // 즉, DOMString propertyName
    double?                   offset = null;
    DOMString                 easing = "linear";
    CompositeOperationOrAuto  composite = "auto";
};

dictionary PropertyIndexedKeyframes {
    // ... 속성-값 및 속성-값목록 쌍 ...
    // 즉, (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

이 키프레임에서 시퀀스의 다음 키프레임까지 시간의 진행을 변환하는 데 사용되는 타이밍 함수.

이 문자열을 구문 분석할 때의 구문과 오류 처리는 EffectTiming 인터페이스의 easing 속성에 정의된 것과 동일하다.

composite

이 키프레임에 지정된 값을 기저 값과 결합하는 데 사용되는 키프레임별 합성 연산.

auto이면, 키프레임 효과에 지정된 합성 연산이 사용된다.

이 유형은 WebIDL로 표현할 수 없으므로 그 처리는 다음 본문에서 정의한다.

keyframes 인수를 받는 각 메서드에 대해, 입력에 키프레임 인수를 처리하는 절차를 실행하고 그 절차의 결과를 유지한다.

먼저 두 가지 보조 정의를 정의한다.

ECMAScript 연산 호출에서 얻은 완료 레코드result완료 레코드를 확인하라는 지시는 다음 단계와 동등하다:

  1. result갑작스러운 완료이면, result의 [[value]] 필드에 포함된 예외를 던지고 절차를 중단한다.

    [[type]]이 break, continue 또는 return이면 어떻게 해야 하는가? 그런 경우가 가능한가?

  2. resultresult의 [[value]] 필드에 포함된 값으로 대체한다.

키프레임 유사 객체를 처리하는 절차는 두 인수를 받는다:

그리고 다음 절차를 사용하여 allow lists가 false이면 속성 이름에서 DOMString 값으로의 맵을, 그렇지 않으면 속성 이름에서 DOMString 값 시퀀스로의 맵을 반환한다:

  1. keyframe input을 ECMAScript 값으로 하여 ECMAScript 값을 딕셔너리 유형으로 변환하는 절차 [WEBIDL]를 실행하고, 딕셔너리 유형은 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를 구현이 애니메이션할 수 있는 속성 이름(애니메이션 가능한 장축 하위 속성을 가진 단축 속성 포함)의 목록으로 둔다.

    2. 애니메이션 속성 이름을 IDL 속성 이름으로 변환하는 알고리즘을 적용하여 animatable properties의 각 속성 이름을 대응하는 IDL 속성으로 변환한다.

  3. keyframe input을 객체로 하여 EnumerableOwnNames 연산을 호출한 결과를 input properties로 둔다.

  4. input propertiesanimatable properties모두 포함되거나, input properties에 포함되면서 <custom-property-name> 생성 규칙을 따르는 모든 속성으로 구성된 새 목록 animation properties를 만든다.

  5. 각 속성 이름을 정의하는 유니코드 코드 포인트를 기준으로 animation properties를 오름차순 정렬한다.

  6. animation properties의 각 property name에 대해,

    1. keyframe input에서 속성 키로 property name을, 수신자로 keyframe input을 사용하여 [[Get]] 내부 메서드를 호출한 결과를 raw value로 둔다.

    2. raw value완료 레코드를 확인한다.

    3. raw value를 다음과 같이 DOMString 또는 DOMString 시퀀스 property values로 변환한다:

      allow lists가 true이면,

      ECMAScript 값을 IDL 값으로 변환하기 위해 정의된 절차 [WEBIDL]를 사용하여 raw value를 IDL 유형 (DOMString or sequence<DOMString>)으로 변환한 결과를 property values로 둔다.

      property values가 단일 DOMString이면, property values를 원래 property values 값만을 유일한 항목으로 갖는 DOMString 시퀀스로 대체한다.

      그렇지 않으면,

      ECMAScript 값을 DOMString으로 변환하는 절차 [WEBIDL]를 사용하여 raw value를 DOMString으로 변환한 결과를 property values로 둔다.

    4. property nameIDL 속성 이름을 애니메이션 속성 이름으로 변환하는 알고리즘을 적용한 결과를 normalized property name으로 계산한다.

    5. normalized property name을 속성 이름으로 하고 property values를 속성 값으로 하는 속성을 keyframe output에 추가한다.

  7. keyframe output을 반환한다.

키프레임 인수를 처리하는 절차는 null 허용 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를 던지고 이 단계를 중단한다.

      7. nextItemkeyframe input으로 전달하고 allow lists 플래그를 false로 설정하여 키프레임 유사 객체를 처리하는 절차를 실행한 결과를 processed keyframes에 추가한다.

    그렇지 않으면,
    1. objectkeyframe input으로 전달하고 allow lists 플래그를 true로 설정하여 키프레임 유사 객체를 처리하는 절차를 실행한 결과를 property-indexed keyframe으로 둔다.

    2. property-indexed keyframe의 각 멤버 m에 대해 다음 단계를 수행한다:

      1. property namem의 키로 둔다.

      2. property name이 "composite", "easing" 또는 "offset"이면, 이 루프의 나머지 단계를 건너뛰고 property-indexed keyframe에서 m 다음 멤버부터 계속한다.

      3. property valuesm의 값으로 둔다.

      4. property keyframes를 빈 키프레임 시퀀스로 둔다.

      5. property values의 각 값 v에 대해 다음 단계를 수행한다:

        1. k를 null 키프레임 오프셋을 가진 새 키프레임으로 둔다.

        2. 속성-값 쌍 property namevk에 추가한다.

        3. kproperty keyframes에 추가한다.

      6. property keyframes누락된 키프레임 오프셋 계산 절차를 적용한다.

      7. property keyframes키프레임processed keyframes에 추가한다.

    3. processed keyframes를 각 키프레임계산된 키프레임 오프셋을 기준으로 오름차순 정렬한다.

    4. processed keyframes에서 인접한 키프레임계산된 키프레임 오프셋이 같으면 병합한다.

    5. offsetsproperty-indexed keyframe의 "offset" 멤버 유형에 따라 다음과 같이 할당된 null 허용 double 값의 시퀀스로 둔다:

      sequence<double?>,

      "offset"의 값을 그대로 사용한다.

      double?,

      "offset"의 값을 유일한 항목으로 갖는 길이 1의 시퀀스, 즉 « offset »,

    6. 두 시퀀스 중 하나의 끝에 도달할 때까지 offsets의 각 값을 processed keyframes에서 대응하는 위치의 키프레임키프레임 오프셋에 할당한다.

    7. easingsproperty-indexed keyframe의 "easing" 멤버 유형에 따라 다음과 같이 할당된 DOMString 값의 시퀀스로 둔다:

      sequence<DOMString>,

      "easing"의 값을 그대로 사용한다.

      DOMString,

      "easing"의 값을 유일한 항목으로 갖는 길이 1의 시퀀스, 즉 « easing »,

    8. easings가 빈 시퀀스이면, 단일 값 "linear"를 포함하는 길이 1의 시퀀스, 즉 « "linear" »로 둔다.

    9. easings의 항목 수가 processed keyframes보다 적으면, easingsprocessed keyframes와 같은 수의 항목을 가질 때까지 목록의 처음부터 easings의 요소를 차례로 반복한다.

      예를 들어 processed keyframes에 5개 항목이 있고 easings가 « "ease-in", "ease-out" » 시퀀스이면, easings는 « "ease-in", "ease-out", "ease-in", "ease-out", "ease-in" »이 되도록 반복된다.
    10. easings의 항목 수가 processed keyframes보다 많으면, 초과 항목을 unused easings로 저장한다.

    11. processed keyframes의 끝에 도달할 때까지 easings의 각 값을 processed keyframes에서 대응하는 위치의 키프레임에 있는 "easing"이라는 이름의 속성에 할당한다.

    12. property-indexed keyframe의 "composite" 멤버가 빈 시퀀스가 아니면:

      1. composite modesproperty-indexed keyframe의 "composite" 멤버에서 할당된 CompositeOperationOrAuto 값의 시퀀스로 둔다. 해당 멤버가 단일 CompositeOperationOrAuto 값 연산이면, composite modes를 "composite"의 값을 유일한 항목으로 갖는 길이 1의 시퀀스로 둔다.

      2. easings와 마찬가지로 composite modes의 항목 수가 processed keyframes보다 적으면, composite modesprocessed keyframes와 같은 수의 항목을 가질 때까지 목록의 처음부터 composite modes의 요소를 차례로 반복한다.

      3. processed keyframes의 끝에 도달할 때까지 composite modes에서 auto가 아닌 각 값을 processed keyframes에서 대응하는 위치의 키프레임키프레임별 합성 연산에 할당한다.

  6. processed keyframes오프셋을 기준으로 느슨하게 정렬되어 있지 않으면 TypeError던지고 이 단계를 중단한다.

  7. processed keyframes에 null이 아니며 0보다 작거나 1보다 큰 키프레임 오프셋을 가진 키프레임이 하나라도 존재하면 TypeError던지고 이 단계를 중단한다.

  8. processed keyframes의 각 frame에 대해 다음 단계를 수행한다:

    1. frame의 각 속성-값 쌍에 대해, 해당 속성에 지정된 구문을 사용하여 속성 값을 구문 분석한다.

      속성 값이 속성 구문에 따라 유효하지 않으면 해당 속성-값 쌍을 버린다. 콘텐츠의 오류 진단을 지원하는 사용자 에이전트는 유효하지 않은 속성 값을 강조하는 적절한 경고를 생성해야 한다.

    2. frame타이밍 함수EffectTiming 딕셔너리의 easing 멤버에 정의된 CSS 구문을 사용하여 frame의 "easing" 속성을 구문 분석한 결과로 둔다.

      "easing" 속성 구문 분석에 실패하면 TypeError던지고 이 절차를 중단한다.

      참고: 위 두 단계 모두에서 CSS 파서를 사용한다는 것은 CSS 주석과 이스케이프가 허용되지만 값이 성공적으로 구문 분석되면 유지되지 않음을 의미한다.

      참고: "easing" 속성의 구문 분석에 실패한 경우, object의 모든 속성을 읽은 후에 TypeError를 던지는 것이 중요하다. 그렇지 않으면 그 차이가 관찰 가능하며, 나중에 WebIDL에서 부분적으로 개방된 딕셔너리를 지원할 경우의 동작과 일치하지 않는다.

  9. EffectTiming 인터페이스의 easing 멤버에 정의된 CSS 구문을 사용하여 unused easings의 각 값을 구문 분석하고, 값 중 하나라도 구문 분석에 실패하면 TypeError던지고 이 절차를 중단한다.

    다음 모든 경우에 TypeError가 발생하도록 일관된 동작을 제공하기 위해 이 마지막 단계가 필요하다:

    elem.animate({ easing: 'invalid' });
    elem.animate({ easing: ['invalid'] });
    elem.animate([{ easing: 'invalid' }]);
    

6.6.4. KeyframeEffectOptions 딕셔너리

KeyframeEffectOptions 객체를 제공하여 KeyframeEffect(target, keyframes, options) 생성자에 추가 매개변수를 전달할 수 있다.

dictionary KeyframeEffectOptions : EffectTiming {
    CompositeOperation composite = "replace";
    CSSOMString?       pseudoElement = null;
};
composite, 유형은 CompositeOperation, 기본값은 "replace"

CompositeOperation 열거형 값 중 하나로 지정되는, 이 애니메이션을 효과 스택과 합성하는 데 사용되는 합성 연산. 이는 auto 키프레임별 합성 연산을 지정하는 모든 키프레임에 사용된다.

pseudoElement, 유형은 CSSOMString, null 허용, 기본값은 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. targettarget 인수로, 제공된 keyframesoptions 인수를 그대로 전달하여 KeyframeEffect(target, keyframes, options) 생성자와 동일한 절차를 사용해 target관련 Realm에 새 KeyframeEffect 객체 effect를 생성한다.

    위 절차에서 예외가 발생하면 예외를 전파하고 이 절차를 중단한다.

  3. optionsKeyframeAnimationOptions 객체이면, timelineoptionstimeline 멤버로 두거나, optionstimeline 멤버가 없으면 이 메서드가 호출된 요소의 노드 문서기본 문서 타임라인으로 둔다.

  4. 같은 이름의 인수로 effecttimeline을 전달하여 Animation() 생성자와 동일한 절차를 사용해 target관련 Realm에 새 Animation 객체 animation을 생성한다.

  5. optionsKeyframeAnimationOptions 객체이면, optionsid 멤버 값을 animationid 속성에 할당한다.

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

  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, null 허용

존재하는 경우 새로 생성된 애니메이션과 연결할 타임라인을 지정하는 선택적 값.

subtree, 유형은 boolean, 기본값은 false

true이면, getAnimations()이 호출된 객체의 자손대상 요소를 가진 애니메이션 효과와 연결된 애니메이션도 결과에 포함해야 함을 나타낸다.

6.9. Document 인터페이스 확장

[DOM]에 정의된 Document 인터페이스에 다음 확장이 적용된다.

partial interface Document {
    readonly attribute DocumentTimeline timeline;
};
timeline, 유형은 DocumentTimeline, 읽기 전용

기본 문서 타임라인을 나타내는 DocumentTimeline 객체.

6.10. DocumentOrShadowRoot 인터페이스 믹스인 확장

[DOM]에 정의된 DocumentOrShadowRoot 인터페이스 믹스인에 다음 확장이 적용된다.

partial interface mixin DocumentOrShadowRoot {
    sequence<Animation> getAnimations();
};
sequence<Animation> getAnimations()

이 메서드가 호출된 문서 또는 섀도 루트에 대한 하위 트리의 관련 애니메이션 집합을 반환한다.

반환된 목록은 § 5.4.2 효과 스택의 효과와 연결된 애니메이션에 대해 설명된 합성 순서를 사용하여 정렬된다.

이 메서드를 호출하면 문서에 대해 스타일 변경 이벤트가 트리거된다. 따라서 반환된 목록은 아직 처리되지 않은 애니메이션 관련 스타일 속성 변경과 같은 애니메이션의 대기 중인 스타일 변경을 모두 적용한 의 상태를 반영한다.

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, 읽기 전용, null 허용

이벤트가 큐에 들어간 순간 이벤트를 생성한 애니메이션현재 시간. 이벤트가 생성된 시점에 애니메이션유휴 상태였다면 null이다.

timelineTime, 유형은 double, 읽기 전용, null 허용

이벤트가 큐에 들어간 순간 이벤트를 생성한 애니메이션과 연결된 타임라인시간 값. 이벤트가 큐에 들어간 시점에 애니메이션활성 타임라인과 연결되어 있지 않았다면 null이다.

currentTime, 유형은 double, null 허용, 기본값은 null

currentTime 속성의 설명을 참조한다.

timelineTime, 유형은 double, null 허용, 기본값은 null

timelineTime 속성의 설명을 참조한다.

6.13. 모델 활성성

모델의 어느 부분이든 변경되면 전체 타이밍 모델과 이에 의존하는 모든 스타일이 업데이트된다.

달리 명시되지 않는 한, 이 명세의 프로그래밍 인터페이스 절에 정의된 인터페이스의 메서드나 생성자를 호출하거나 멤버를 가져오거나 설정해도 스타일 변경 이벤트발생하지 않는다.

참고: 이 명세를 확장하는 다른 명세는 이러한 이벤트가 실제로 트리거되는 상황을 도입하여 스타일 변경 이벤트에 대한 요구사항을 구체화할 것으로 예상된다. 예를 들어, 이 명세의 인터페이스가 CSS 마크업으로 정의된 애니메이션을 나타내는 경우, 지정된 스타일의 변경 사항을 반영하기 위해 많은 메서드가 스타일 변경 이벤트를 트리거해야 한다.

이 절은 비규범적이다

위 요구사항과 이 명세의 다른 곳에 있는 규범적 요구사항을 기반으로 다음 불변 조건을 관찰할 수 있다:

웹 애니메이션 모델에 대한 변경 사항은 즉시 적용된다

예를 들어 Animation과 연결된 KeyframeEffect가 프로그래밍 인터페이스를 통해 탐색되면 (§ 4.4.4 애니메이션의 현재 시간 설정 참조), 애니메이션의 startTime을 조회하여 반환되는 값은 모델의 업데이트된 상태를 즉시 반영한다.

// 처음에는 animation.effect.getComputedTiming().localTime이 3000이다
animation.currentTime += 2000;
alert(animation.effect.getComputedTiming().localTime); // "5000"을 표시한다
애니메이션의 영향을 받는 속성의 계산된 스타일을 조회하면 애니메이션의 완전히 최신 상태를 반환한다

예를 들어 요소에 새 Animation을 적용한 직후 해당 요소의 사용된 스타일을 조회하면, 새 애니메이션의 결과가 반환되는 값에 포함된다.

// 불투명도를 즉시 0으로 설정한다
elem.animate({ opacity: 0 }, { fill: 'forwards' });
alert(window.getComputedStyle(elem).opacity); // "0"을 표시한다
동일한 태스크 내에서 이루어진 변경 사항은 전체 변경 집합이 함께 렌더링되도록 동기화된다

모델 변경 사항이 즉시 적용되는 특성과 ECMAScript의 실행 완료 의미론이 결합되므로, 예를 들어 애니메이션을 적용하지 않은 채 지정된 스타일의 변경 사항 렌더링되는 상황은 발생해서는 안 된다.

// Element.animate를 지원하지 않는 브라우저를 위한 대체 동작과 함께
// 불투명도를 페이드한다
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-FRAGS]는 미디어 리소스의 시간 범위를 지정하는 수단을 정의한다. 미디어 프래그먼트의 적용은 지정된 리소스의 MIME 유형에 따라 달라진다. SVG MIME 유형 [SVG11]을 가진 리소스의 경우, 시간 매개변수의 적용은 애니메이션 요소 명세에 정의되어 있다.

참고: 미디어 프래그먼트는 MIME 유형을 기반으로 리소스에 작동하도록 정의된다. 따라서 웹 애니메이션 콘텐츠가 사용되는 모든 상황에서 시간 지정이 지원되는 것은 아닐 수 있다.

8. 페이지 표시와의 상호 작용

HTML은 사용자가 페이지 사이를 탐색할 때 스크롤 위치와 같은 상태를 포함하여 이전 페이지 상태를 복원할 수 있도록 사용자 에이전트가 세션 기록 항목과 함께 사용자 에이전트 정의 상태를 저장할 수 있도록 허용한다 [HTML].

참조 문서가 언로드되고 기록을 순회할 때 미디어 요소를 일시 중지하고 재개하는 사용자 에이전트는 웹 애니메이션 콘텐츠가 포함된 문서에도 일관된 처리를 적용하는 것이 권장된다. 제공되는 경우 이 동작은 벽시계 시간을 추적하는 모든 타임라인시간 값을 조정하여 구현해야 한다.

이것은 이러한 시간 값navigationStart에 상대적이라는 점 및 requestAnimationFramedocument.timeline.currentTime과 동일한 시간을 사용한다는 점과 충돌하는가? [이슈 #2083]

9. 구현 요구사항

9.1. 시간 값의 정밀도

시간 값의 내부 표현은 구현에 따라 달라지지만, 사용자 에이전트가 입력 시간 값을 마이크로초 정밀도로 표현할 수 있도록 하는 것이 권장된다. 이를 통해 명목상 밀리초를 나타내는 시간 값 0.001을 0.0과 구분할 수 있다.

9.2. 적합성 기준

이 명세는 애니메이션의 추상 모델을 정의하므로, 스크립팅을 지원하지 않는 사용자 에이전트에는 테스트 가능한 표면이 없기 때문에 적합성 기준이 없다.

그러나 스크립팅을 지원하지 않는 사용자 에이전트도 이 명세를 기준으로 정의된 추가 기술을 구현할 수 있으며, 이 경우 이 명세에 제공된 정의가 해당 추가 기술의 적합성 기준 일부를 구성한다.

적합한 스크립트형 웹 애니메이션 사용자 에이전트§ 6 프로그래밍 인터페이스에 정의된 API를 구현하는 사용자 에이전트이다.

10. 감사의 말

이 명세에 기여해 준 Steve Block, Michael Giuffrida, Ryan Seys 및 Eric Willigers에게 감사한다.

또한 제안된 부드러운 타이밍 함수의 방정식을 도와준 Michiel "Pomax" Kamermans에게도 감사한다. 다만 이 기능은 후속 명세로 연기되었다.

방송용 애니메이션 제작에 사용되는 과정과 기법을 편집자들에게 소개하는 데 친절한 관대함과 인내심을 보여준 Southern Star Animation에 깊은 감사를 표한다.

11. 마지막 게시 이후 변경 사항

2022년 9월 8일 작업 초안 이후 다음 변경 사항이 적용되었다:

변경 이력에서 더 자세한 이력을 확인할 수 있다.

부록 A: 기존 속성의 애니메이션 유형

일반적으로 속성의 애니메이션 유형은 그 정의와 함께 포함된다. 그러나 오래되었거나 매우 성숙한 명세에 정의된 일부 속성에는 애니메이션 유형 정보가 포함되어 있지 않다. 아래에 나열된 예외 중 하나가 아닌 한 이러한 모든 속성은 계산된 값에 따라 애니메이션 유형을 갖는 것으로 가정한다.

font-weight 애니메이션

레벨 4 이전의 font-weight 속성 값은 다음과 같이 결합된다:

참고: 이 정의는 font-weight 값이 100의 배수여야 한다는 요구사항이 제거된 [CSS-FONTS-4]에 의해 폐기되었다. 그 시점에서 font-weight애니메이션 유형은 단순히 계산된 값에 따라이다.

visibility 애니메이션

visibility 속성의 경우, visible보간되는 이산 단계이며, 0과 1 사이의 p 값은 visible에 매핑되고 다른 p 값은 더 가까운 끝점에 매핑된다. 어느 값도 visible이 아니면 이산 애니메이션이 사용된다.

box-shadowtext-shadow 애니메이션

box-shadow 또는 text-shadow 속성의 애니메이션은 다음과 같이 그림자 목록결합하는 절차를 따른다:

목록의 각 그림자는 (none을 길이 0의 목록으로 취급하여) 계산된 값에 따라 동작하는 것처럼 구성 요소별로 보간된다. 그러나 두 입력 그림자가 모두 inset이거나 두 입력 그림자가 모두 inset이 아닌 경우, 보간된 그림자도 그 점에서 입력 그림자와 일치해야 한다. 입력 그림자 쌍 중 하나가 inset이고 다른 하나가 inset이 아니면, 전체 그림자 목록은 이산 애니메이션을 사용한다. 그림자 목록의 길이가 서로 다르면, 더 짧은 목록의 끝에 색상이 transparent이고, 모든 길이가 0이며, inset 여부가 더 긴 목록과 일치하는 그림자를 추가하여 채운다.

그림자 목록 VaVb덧셈VresultVaVb확장한 것과 같도록 하는 목록 연결로 정의된다.

그림자 목록누적은 위의 보간 일치 규칙을 따르며, 각 구성 요소의 유형에 따라 덧셈을 수행하거나 inset 값이 일치하지 않으면 이산 애니메이션으로 대체한다.

적합성

문서 규칙

적합성 요구사항은 설명적 단언과 RFC 2119 용어를 조합하여 표현한다. 이 문서의 규범적 부분에서 “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, “OPTIONAL”이라는 키워드는 RFC 2119에 설명된 대로 해석해야 한다. 그러나 가독성을 위해 이 명세에서는 이러한 단어가 항상 모두 대문자로 표시되지는 않는다.

명시적으로 비규범적이라고 표시된 절, 예제 및 참고를 제외한 이 명세의 모든 텍스트는 규범적이다. [RFC2119]

이 명세의 예제는 “예를 들어”라는 말로 시작하거나 class="example"을 사용하여 규범적 텍스트와 구분되며, 다음과 같다:

정보 제공용 예제의 예이다.

정보 제공용 참고는 “참고”라는 말로 시작하며 class="note"을 사용하여 규범적 텍스트와 구분되며, 다음과 같다:

참고, 이것은 정보 제공용 참고이다.

권고 사항은 특별한 주의를 끌도록 스타일이 지정된 규범적 절이며 <strong class="advisement">을 사용하여 다른 규범적 텍스트와 구분된다. 다음과 같다: UA는 접근 가능한 대안을 반드시 제공해야 한다.

적합성 클래스

이 명세에 대한 적합성은 세 가지 적합성 클래스에 대해 정의된다:

스타일시트
CSS 스타일시트.
렌더러
스타일시트의 의미를 해석하고 이를 사용하는 문서를 렌더링하는 UA.
저작 도구
스타일시트를 작성하는 UA.

이 모듈에 정의된 구문을 사용하는 모든 문이 일반 CSS 문법과 이 모듈에 정의된 각 기능의 개별 문법에 따라 유효하면 스타일시트는 이 명세에 적합하다.

렌더러는 적절한 명세에 정의된 대로 스타일시트를 해석하는 것 외에도, 이 명세에 정의된 모든 기능을 올바르게 구문 분석하고 그에 따라 문서를 렌더링하여 지원하면 이 명세에 적합하다. 그러나 장치의 제한으로 인해 UA가 문서를 올바르게 렌더링할 수 없는 경우에도 UA가 부적합해지는 것은 아니다. (예를 들어 단색 모니터에서 UA가 색상을 렌더링할 필요는 없다.)

저작 도구는 일반 CSS 문법과 이 모듈에 정의된 각 기능의 개별 문법에 따라 구문적으로 올바른 스타일시트를 작성하고, 이 모듈에 설명된 스타일시트의 다른 모든 적합성 요구사항을 충족하면 이 명세에 적합하다.

부분 구현

작성자가 순방향 호환 구문 분석 규칙을 활용하여 대체 값을 할당할 수 있도록, CSS 렌더러는 사용 가능한 수준의 지원이 없는 모든 @ 규칙, 속성, 속성 값, 키워드 및 기타 구문 구조를 유효하지 않은 것으로 취급해야 하며 (그리고 적절히 무시해야 한다). 특히 사용자 에이전트는 단일 다중 값 속성 선언에서 지원되지 않는 구성 요소 값만 선택적으로 무시하고 지원되는 값을 적용해서는 안 된다. 어떤 값이든 유효하지 않은 것으로 간주되면 (지원되지 않는 값은 반드시 그렇게 간주되어야 함), CSS는 전체 선언을 무시하도록 요구한다.

불안정 기능 및 독점 기능의 구현

향후 안정적인 CSS 기능과의 충돌을 피하기 위해 CSSWG는 CSS의 불안정 기능과 독점 확장을 구현할 때 모범 사례를 따를 것을 권장한다.

비실험적 구현

명세가 후보 권고안 단계에 도달하면 비실험적 구현이 가능하며, 구현자는 명세에 따라 올바르게 구현되었음을 입증할 수 있는 모든 CR 수준 기능의 접두사 없는 구현을 공개하는 것이 좋다.

구현 간 CSS 상호운용성을 확립하고 유지하기 위해, CSS 작업 그룹은 비실험적 CSS 렌더러가 어떤 CSS 기능의 접두사 없는 구현을 공개하기 전에 구현 보고서 (필요한 경우 해당 구현 보고서에 사용된 테스트 사례도 포함)를 W3C에 제출할 것을 요청한다. W3C에 제출된 테스트 사례는 CSS 작업 그룹의 검토와 수정 대상이 된다.

테스트 사례와 구현 보고서 제출에 대한 자세한 정보는 CSS 작업 그룹 웹사이트의 https://www.w3.org/Style/CSS/Test/에서 확인할 수 있다. 질문은 public-css-testsuite@w3.org 메일링 리스트로 보내야 한다.

색인

이 명세에서 정의된 용어

참조로 정의된 용어

참고 문헌

규범적 참고 문헌

[CSS-ANIMATIONS-1]
David Baron; et al. CSS 애니메이션 레벨 1. 2023년 3월 2일. WD. URL: https://www.w3.org/TR/css-animations-1/
[CSS-ANIMATIONS-2]
David Baron; Brian Birtles. CSS 애니메이션 레벨 2. 2023년 3월 2일. WD. URL: https://www.w3.org/TR/css-animations-2/
[CSS-BACKGROUNDS-3]
Bert Bos; Elika Etemad; Brad Kemper. CSS 배경 및 테두리 모듈 레벨 3. 2023년 2월 14일. CR. URL: https://www.w3.org/TR/css-backgrounds-3/
[CSS-CASCADE-3]
Elika Etemad; Tab Atkins Jr.. CSS 캐스케이딩 및 상속 레벨 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 캐스케이딩 및 상속 레벨 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 색상 모듈 레벨 4. 2022년 11월 1일. CR. URL: https://www.w3.org/TR/css-color-4/
[CSS-DISPLAY-3]
Elika Etemad; Tab Atkins Jr.. CSS 디스플레이 모듈 레벨 3. 2023년 3월 30일. CR. URL: https://www.w3.org/TR/css-display-3/
[CSS-EASING-1]
Brian Birtles; Dean Jackson; Matt Rakow. CSS 이징 함수 레벨 1. 2023년 2월 13일. CR. URL: https://www.w3.org/TR/css-easing-1/
[CSS-FONTS-4]
John Daggett; Myles Maxfield; Chris Lilley. CSS 글꼴 모듈 레벨 4. 2021년 12월 21일. WD. URL: https://www.w3.org/TR/css-fonts-4/
[CSS-LOGICAL-1]
Rossen Atanassov; Elika Etemad. CSS 논리적 속성 및 값 레벨 1. 2018년 8월 27일. WD. URL: https://www.w3.org/TR/css-logical-1/
[CSS-PROPERTIES-VALUES-API-1]
Tab Atkins Jr.; et al. CSS 속성 및 값 API 레벨 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 섀도 파트. 2018년 11월 15일. WD. URL: https://www.w3.org/TR/css-shadow-parts-1/
[CSS-STYLE-ATTR]
Tantek Çelik; Elika Etemad. CSS 스타일 속성. 2013년 11월 7일. REC. URL: https://www.w3.org/TR/css-style-attr/
[CSS-TEXT-DECOR-4]
Elika Etemad; Koji Ishii. CSS 텍스트 장식 모듈 레벨 4. 2022년 5월 4일. WD. URL: https://www.w3.org/TR/css-text-decor-4/
[CSS-TRANSFORMS-1]
Simon Fraser; et al. CSS 변환 모듈 레벨 1. 2019년 2월 14일. CR. URL: https://www.w3.org/TR/css-transforms-1/
[CSS-TRANSITIONS-1]
David Baron; et al. CSS 전환. 2018년 10월 11일. WD. URL: https://www.w3.org/TR/css-transitions-1/
[CSS-TRANSITIONS-2]
CSS 전환 레벨 2 URL: https://drafts.csswg.org/css-transitions-2/
[CSS-VALUES-4]
Tab Atkins Jr.; Elika Etemad. CSS 값 및 단위 모듈 레벨 4. 2023년 4월 6일. WD. URL: https://www.w3.org/TR/css-values-4/
[CSS-VARIABLES-1]
Tab Atkins Jr.. 캐스케이딩 변수를 위한 CSS 사용자 지정 속성 모듈 레벨 1. 2022년 6월 16일. CR. URL: https://www.w3.org/TR/css-variables-1/
[CSS-WILL-CHANGE-1]
Tab Atkins Jr.. CSS Will Change 모듈 레벨 1. 2022년 5월 5일. CR. URL: https://www.w3.org/TR/css-will-change-1/
[CSS-WRITING-MODES-3]
Elika Etemad; Koji Ishii. CSS 쓰기 모드 레벨 3. 2019년 12월 10일. REC. URL: https://www.w3.org/TR/css-writing-modes-3/
[CSS-WRITING-MODES-4]
Elika Etemad; Koji Ishii. CSS 쓰기 모드 레벨 4. 2019년 7월 30일. CR. URL: https://www.w3.org/TR/css-writing-modes-4/
[CSS21]
Bert Bos; et al. 캐스케이딩 스타일시트 레벨 2 개정 1(CSS 2.1) 명세. 2011년 6월 7일. REC. URL: https://www.w3.org/TR/CSS21/
[CSS22]
Bert Bos. 캐스케이딩 스타일시트 레벨 2 개정 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. 고해상도 시간. 2023년 4월 25일. WD. URL: https://www.w3.org/TR/hr-time-3/
[HTML]
Anne van Kesteren; et al. 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; et al. 미디어 프래그먼트 URI 1.0 (기본). 2012년 9월 25일. REC. URL: https://www.w3.org/TR/media-frags/
[MOTION-1]
Dirk Schulze; et al. 모션 경로 모듈 레벨 1. 2018년 12월 18일. WD. URL: https://www.w3.org/TR/motion-1/
[RFC2119]
S. Bradner. 요구 수준을 나타내기 위해 RFC에서 사용하는 키워드. 1997년 3월. 현행 최선의 관행. URL: https://datatracker.ietf.org/doc/html/rfc2119
[SELECT]
Tantek Çelik; et al. 선택자 레벨 3. 2018년 11월 6일. REC. URL: https://www.w3.org/TR/selectors-3/
[SELECTORS-4]
Elika Etemad; Tab Atkins Jr.. 선택자 레벨 4. 2022년 11월 11일. WD. URL: https://www.w3.org/TR/selectors-4/
[SVG11]
Erik Dahlström; et al. 확장 가능한 벡터 그래픽(SVG) 1.1 (제2판). 2011년 8월 16일. REC. URL: https://www.w3.org/TR/SVG11/
[SVG2]
Amelia Bellamy-Royds; et al. 확장 가능한 벡터 그래픽(SVG) 2. 2018년 10월 4일. CR. URL: https://www.w3.org/TR/SVG2/
[WEB-ANIMATIONS-2]
Brian Birtles; Robert Flack. 웹 애니메이션 레벨 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 애니메이션. 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;
};

이슈 색인

"원점 시간"보다 더 나은 용어가 있어야 한다— "시간 원점"과 너무 유사하다. [이슈 #2079]
특정 타이밍 함수가 존재하는 경우 애니메이션 효과에 입력되는 반복 진행률은 [0, 1] 범위로 제한되지 않는다. 그러나 현재 키프레임 오프셋은 여전히 [0, 1] 범위로 제한되며, 이 범위를 벗어난 입력 반복 진행률 값에 대해서는 속성 값이 단순히 외삽된다.

반복 진행률 값이 [0, 1] 범위를 벗어난 곳에서 속성 값의 비선형 변화를 지정할 수 있는 것이 유용한 경우가 있으므로 이 제한을 제거하는 방안을 검토했다. 한 가지 예는 녹색에서 노란색으로 보간하지만 오버슈트 타이밍 함수 때문에 일시적으로 노란색을 "넘어" 빨간색까지 보간한 다음 다시 노란색으로 돌아오는 애니메이션이다.

키프레임과 타이밍 함수를 수정하여 이 효과를 구현할 수는 있지만, 이 접근 방식은 타이밍 관련 사항과 애니메이션 효과를 분리하는 모델의 구조를 깨는 것으로 보인다.

이 효과를 어떻게 구현해야 하는지는 명확하지 않지만, [0, 1] 밖의 키프레임 오프셋을 허용하면 필요에 따라 오프셋 0과 1의 키프레임을 합성하도록 현재 지정된 동작과 일관되지 않을 수 있다는 점에 유의한다.

2013년 도쿄 F2F 회의록 논의의 4절([0, 1] 밖의 키프레임 오프셋)을 참조한다.

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

렌더링 중 [HTML]의 정의는 display: contents와 관련하여 여전히 논의 중이다. 이 절차의 목적상, 다른 경우라면 연관된 레이아웃 박스를 가질 display: contents인 요소 (즉, 연결되어 있고 display: none 하위 트리의 일부가 아닌 요소)는 렌더링 중이라고 가정한다.

remove() 메서드는 효과를 그 부모 그룹이나 애니메이션에서 제거하는 데 사용할 수 있다. 이를 레벨 1에 유지하고 단순히 애니메이션 효과를 그 애니메이션에서 제거하는 것으로 정의해야 하는가? [이슈 #2082]
[[type]]이 break, continue 또는 return이면 어떻게 해야 하는가? 그런 경우가 가능한가?
이것은 이러한 시간 값navigationStart에 상대적이라는 점 및 requestAnimationFramedocument.timeline.currentTime과 동일한 시간을 사용한다는 점과 충돌하는가? [이슈 #2083]