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()); 또한, 애플리케이션은 대기하지 않고 애니메이션의 재생 상태를 조회할 수도 있습니다.
- 실행 중인 애니메이션 제어
-
때로는 애니메이션이 외부 입력에 반응할 수 있도록 재생 제어를 하는 것이 유용합니다. 예를 들어, 사용자 주의를 방해하지 않도록 모달 다이얼로그를 표시하기 전에 모든 애니메이션을 일시정지해야 할 수 있습니다.
- 스크립트로 애니메이션 생성
-
ECMAScript를 이용해
requestAnimationFrame
[HTML]으로 애니메이션을 수행하는 것도 가능하지만, 이러한 애니메이션은 CSS 캐스케이드에서의 표현 방식이나, 별도 스레드에서 애니메이션을 수행하는 등 성능 최적화 측면에서 선언적 애니메이션과 다르게 동작합니다. 웹 애니메이션 프로그래밍 인터페이스를 사용하면, 선언적 애니메이션과 동일한 동작 및 성능 특성을 가진 스크립트 기반 애니메이션을 생성할 수 있습니다. - 애니메이션 디버깅
-
복잡한 애플리케이션에서는 요소가 현재 상태에 도달한 경로를 파악하기 어려울 수 있습니다. 웹 애니메이션 프로그래밍 인터페이스를 사용하여 실행 중인 애니메이션을 검사하고, "왜 이 요소의 투명도가 변하고 있을까?"와 같은 질문에 답할 수 있습니다.
// elem에서 opacity 애니메이션의 id를 출력 for ( const animationof elem. getAnimations()) { if ( animation. effectinstanceof KeyframeEffect&& animation. effect. getKeyframes() . some( frame=> frame. hasOwnProperty( 'opacity' )) ) { console. log( animation. id); } } 또한 애니메이션을 미세 조정하려면 재생 속도를 낮추고 반복해서 재생해야 할 때가 많습니다.
// transform 애니메이션을 느리게 하고 재생 const transformAnimations= elem. getAnimations(). filter( animation=> animation. effectinstanceof KeyframeEffect&& animation. effect. getKeyframes(). some( frame=> frame. hasOwnProperty( 'transform' ) ) ); for ( const animationof transformAnimations) { animation. currentTime= 0 ; animation. updatePlaybackRate( 0.5 ); } - 애니메이션 테스트
-
애니메이션을 사용하는 애플리케이션을 테스트할 때, 애니메이션이 완전히 끝날 때까지 기다리는 것은 비효율적일 수 있습니다. 대신, 애니메이션을 특정 시간으로 이동시키는 것이 바람직합니다.
// 애니메이션 중간 지점으로 이동한 뒤 opacity가 50%인지 확인 for ( const animationof elem. getAnimations()) { const { delay, activeDuration} = animation. effect. getComputedTiming(); animation. currentTime= delay+ activeDuration/ 2 ; } assert. strictEqual( getComputedStyle( elem). opacity, '0.5' ); // 애니메이션이 끝난 후 로딩 화면이 숨겨지는지 확인 for ( const animationof elem. getAnimations()) { animation. finish(); } // 이벤트 핸들러가 실행될 수 있도록 한 프레임 대기 requestAnimationFrame(() => { assert. strictEqual( getComputedStyle( document. querySelector( '#loading' )). display, 'none' ); });
1.2. 다른 명세와의 관계
CSS 트랜지션 [CSS-TRANSITIONS-1], CSS 애니메이션 [CSS-ANIMATIONS-1], 그리고 SVG [SVG11] 모두 웹 페이지에서 애니메이션 콘텐츠를 생성하는 메커니즘을 제공합니다. 이 세 가지 명세는 많은 유사한 기능을 제공하지만, 각각 다른 용어로 설명되어 있습니다. 이 명세서는 세 가지 명세의 공통 기능을 포괄하는 추상적 애니메이션 모델을 제안합니다. 이 모델은 기존 명세의 동작과 호환되어 관찰 가능한 변화 없이 이 모델로 정의될 수 있습니다.
SVG 1.1의 애니메이션 기능은 SMIL 애니메이션 [SMIL-ANIMATION]을 기반으로 정의되어 있습니다. 웹 애니메이션 모델로 SVG의 애니메이션 기능을 정의하면, SVG와 SMIL 애니메이션 간의 의존성을 제거할 수 있습니다.
애니메이션 프레임 콜백(일반적으로 "requestAnimationFrame"이라 불리는) [HTML]과 마찬가지로, 이 명세서의 프로그래밍 인터페이스 구성요소는 스크립트로 애니메이션을 생성할 수 있게 해줍니다. 그러나 이 명세서에서 정의된 인터페이스를 사용해 생성된 애니메이션은 한 번 생성되면 전적으로 사용자 에이전트에 의해 실행되므로, 마크업에서 정의된 애니메이션과 동일한 성능 특성을 갖습니다. 이 인터페이스를 사용하면 스크립트로 더 간단하고 효율적으로 애니메이션을 만들 수 있습니다.
프로그래밍 인터페이스에서 사용되는 시간 값은 애니메이션 프레임 콜백 [HTML]에서 사용되는 값과 일치하며, 실행 순서는 두 인터페이스를 동시에 사용해도 충돌이 없도록 정의되어 있습니다.
이 명세서의 프로그래밍 인터페이스 구성요소는 HTML [HTML]에서 정의된 인터페이스에 일부 기능을 추가합니다.
1.3. 이 명세서 개요
이 명세서는 먼저 애니메이션을 위한 추상 모델을 정의합니다. 그 다음, 추상 모델을 바탕으로 정의된 프로그래밍 인터페이스를 설명합니다. 프로그래밍 인터페이스는 추상 모델을 기반으로 정의되며, 스크립팅을 지원하는 사용자 에이전트에만 관련이 있습니다.
2. 명세 규약
이 명세서는 애니메이션과 애니메이션 효과 등과 같은 추상 개념과, 그에 속한 재생 속도나 반복 지속 시간과 같은 속성들을 먼저 설명합니다. 이러한 속성 외에도, 재생 속도 설정이나 시작 시간 설정과 같이, 이러한 속성을 업데이트하는 구체적인 절차가 자주 존재합니다.
이 명세서가 특정 절차에 연결하지 않은 경우, 예를 들어 "make animation’s start time unresolved"과 같이 사용자 에이전트가 속성을 업데이트해야 하는 텍스트는 관련 절차를 호출하지 않고 직접적으로 해당 속성을 업데이트하는 것을 의미합니다.
이 명세에 국한되지 않는 추가적인 문서 규약은 문서 규약에서 설명합니다.
3. 웹 애니메이션 모델 개요
웹 애니메이션 모델은 크게 두 가지 독립적인 부분, 즉 타이밍 모델과 애니메이션 모델로 구성됩니다. 각 부분의 역할은 다음과 같습니다:
- 타이밍 모델
-
어떤 순간의 시간을 받아서, 반복 진행도라 불리는 애니메이션의 한 반복 내 비례적 거리를 계산합니다. 또한 반복 인덱스도 기록하는데, 이는 일부 애니메이션이 반복될 때마다 달라질 수 있기 때문입니다.
- 애니메이션 모델
-
타이밍 모델에서 생성된 반복 진행도 값과 반복 인덱스를 받아서, 대상 속성에 적용할 일련의 값들로 변환합니다.
이 흐름은 그래픽적으로 다음과 같이 표현할 수 있습니다:
현재 시간이 타이밍 모델에 입력되어 반복 진행도 값과 반복 인덱스를 생성합니다.
이 파라미터들은 애니메이션 모델에 입력되어 적용할 값을 생성하는 데 사용됩니다.
예를 들어, 다음과 같은 애니메이션을 생각해봅시다:
-
3초 후에 시작
-
두 번 반복
-
매번 2초 소요
-
사각형의 너비를 50픽셀에서 100픽셀로 변경
첫 세 항목은 타이밍 모델에 적용됩니다. 6초 시점에는 애니메이션이 두 번째 반복의 중간 지점임을 계산하고 결과값 0.5를 생성합니다. 애니메이션 모델은 이 정보를 사용하여 너비를 계산합니다.
이 명세서는 타이밍 모델부터 시작해 애니메이션 모델로 이어집니다.
4. 타이밍 모델
이 섹션에서는 웹 애니메이션 타이밍 모델의 동작을 설명하고 정의합니다.
4.1. 타이밍 모델 개요
이 섹션은 규범적이지 않습니다
웹 애니메이션 타이밍 모델의 특징은 무상태와 계층적이라는 두 가지입니다.
4.1.1. 무상태
웹 애니메이션 타이밍 모델은 입력된 시간을 받아서 반복 진행도를 출력합니다. 출력은 오직 입력 시간만을 기준으로 이전 입력과는 무관하게 결정되므로, 이 모델은 무상태로 설명할 수 있습니다. 이는 모델에 다음과 같은 특성을 부여합니다:
- 프레임 속도 독립적
-
출력이 이전 입력에 독립적이기 때문에, 모델의 업데이트 속도는 진행도에 영향을 미치지 않습니다. 입력 시간이 실제 시간의 진행에 비례한다면, 애니메이션은 실행되는 기기의 성능과 관계없이 동일한 속도로 진행됩니다.
- 방향 무관
-
입력의 순서가 중요하지 않기 때문에, 모델은 방향성이 없습니다. 즉, 모델을 임의의 시점으로 업데이트해도 별도의 처리가 필요하지 않습니다.
- 상수 시간 탐색
-
각 입력이 이전 입력과 독립적이므로, 탐색(seek) 연산을 수행하는 데 필요한 처리는 먼 미래라도 최소한 상수 시간으로 가능할 수 있습니다.
타이밍 모델의 무상태 동작에는 몇 가지 예외가 있습니다.
첫째, 모델의 프로그래밍 인터페이스에서 정의된 여러 메서드는 애니메이션 일시정지 등 재생 제어를 제공합니다. 이러한 메서드는 호출된 시점의 시간에 따라 동작하므로 상태성을 가집니다. 이 메서드들은 편의를 위해 제공되는 것이며 핵심 타이밍 모델의 일부가 아니라 그 위에 계층적으로 추가된 것입니다.
마찬가지로, 애니메이션의 완료 동작은 애니메이션의 미디어(연관 효과)의 종료 시간을 동적으로 변경할 경우, 변경 시점에 따라 결과가 달라질 수 있습니다. 이 동작은 다소 아쉽지만 직관적이고 HTML과 일관되기 때문에 채택되었습니다. 따라서 모델은 타이밍 속성에 동적 변경이 없을 때에만 무상태로 설명될 수 있습니다.
마지막으로, 모델이 업데이트될 때마다 일시적 상태가 형성된다고 볼 수 있습니다. 이 일시적 상태는 프로그래밍 인터페이스에서 반환되는 값에 영향을 주지만, 이후 업데이트에는 영향을 미치지 않으므로 앞서 설명한 무상태 특성과 충돌하지 않습니다.
4.1.2. 계층적
타이밍 모델의 또 다른 특징은 시간이 상속된다는 점입니다. 시간은 타임라인에서 시작하여 여러 단계에 걸쳐 각 애니메이션 효과로 전달됩니다. 각 단계에서 시간은 뒤로 또는 앞으로 이동, 스케일 조정, 반전, 일시정지, 반복될 수 있습니다.
이 명세서의 이 단계에서는 계층 구조가 얕습니다. 이후 단계에서 그룹 효과 개념이 도입되어 더 깊은 타이밍 계층 구조가 가능해집니다.
4.2. 시간 값
타이밍은 타이밍 노드 간의 시간 관계 계층 구조에 기반합니다. 부모 노드는 자식 노드에 시간 값의 형태로 타이밍 정보를 제공합니다.
시간 값은 일반적으로 어떤 시점부터 경과한 밀리초 수를 의미하는 실수입니다. 시간 값과 실제 벽시계 밀리초와의 연결은 시간 계층을 거치며 적용되는 다양한 변환에 의해 흐려질 수 있습니다.
앞으로 스크롤 위치나 UI 제스처를 기반으로 한 타임라인이 도입될 수 있으며, 이 경우 시간 값과 밀리초의 연결은 더욱 약해질 수 있습니다.
시간 값은 또한 미해결일 수도 있습니다. 예를 들어, 타이밍 노드가 시간 값을 생성할 수 없는 상태일 때 그렇습니다.
4.3. 타임라인
타임라인은 동기화 목적을 위한 시간 값의 소스를 제공합니다.
어느 한 순간에, 타임라인은 단일 현재 시간 값을 가지며, 이를 단순히 타임라인의 현재 시간이라고 합니다.
타임라인은 항상 의미 있는 시간 값을 반환할 수 있는 것은 아니며, 때로는 미해결 시간 값만 반환할 수 있습니다. 예를 들어, 아직 발생하지 않은 순간(예: 문서의 load 이벤트 발생 등)을 기준으로 정의될 수 있습니다. 타임라인은 비활성 타임라인으로 간주되며, 시간 값이 미해결일 때입니다.
타임라인은, 그 현재 시간이 항상 이전에 보고된 현재 시간과 같거나 클 때 단조 증가 타임라인입니다.
특정 종류의 타임라인은 타임라인 시간을 원점 기준 시간으로 변환하는 절차를 시간 값 time에 대해 정의할 수 있으며, 벽시계 기반 타임라인에서 생성된 시간 값을 비교할 수 있도록 합니다.
타임라인은 문서에 연결된 타임라인일 수 있습니다.
애니메이션을 업데이트하고
이벤트를 전송할 때,
Document
doc에서 timestamp now에 대해 아래 단계들을 실행합니다:
-
문서에 연결된 모든 타임라인의 현재 시간을 now를 timestamp로 전달하여 업데이트합니다.
타이밍 모델의 계층적 특성 때문에, 타임라인의 현재 시간을 업데이트하면 다음도 포함됩니다:
-
현재 시간이 업데이트된 애니메이션에 대해 애니메이션의 완료 상태를 업데이트 절차를 실행합니다.
-
해당 애니메이션에 대해 애니메이션 이벤트를 큐에 추가합니다.
-
교체된 애니메이션 제거를 doc에 대해 실행합니다.
-
마이크로태스크 체크포인트 실행를 합니다.
참고: 이는 이전 단계에서 타임라인 업데이트의 일부로 Promise 객체를 해결하거나 거부한 결과로 큐에 추가된 마이크로태스크가 애니메이션 이벤트 디스패치 이전에 콜백을 실행할 수 있도록 하는 것입니다.
-
events to dispatch를 doc의 대기 중인 애니메이션 이벤트 큐의 복사본으로 설정합니다.
-
doc의 대기 중인 애니메이션 이벤트 큐를 비웁니다.
-
events to dispatch 내의 애니메이션 이벤트를 다음 방식으로 안정적으로 정렬합니다:
-
이벤트의 예정 이벤트 시간 기준으로, 먼저 발생해야 하는 이벤트가 뒤에 발생하는 이벤트보다 앞에 오도록 정렬합니다. 그리고 예정 이벤트 시간이 미해결인 이벤트가 해결됨인 이벤트보다 앞에 오도록 정렬합니다.
-
예정 이벤트 시간이 동일한 이벤트 내에서는, 합성 순서로 정렬합니다.
참고: 이벤트 정렬 목적은, 기기별 프레임률이 달라도 이벤트가 일관된 순서로 디스패치되도록 최대한 보장하기 위함입니다.
참고: 정렬이 안정적이어야 하는 이유는, 동일한 예정 이벤트 시간으로 이벤트가 큐에 추가될 수 있기 때문입니다. 예를 들어, 0초짜리 CSS 애니메이션은
animationstart
와animationend
이벤트를 모두 디스패치할 수 있으며, 이 두 이벤트의 순서는 유지되어야 합니다. -
-
이벤트 디스패치를 events to dispatch의 각 이벤트에 대해 해당 타겟에서, 앞 단계에서 정해진 순서대로 실행합니다.
이 절차가 호출될 때마다 새로운 애니메이션 프레임이 생성된다고 설명하는 것이 편리할 때가 많습니다. 애니메이션이나 애니메이션 효과의 타이밍 속성 변경, 객체 추가 및 제거 등은 타이밍 또는 애니메이션 모델의 출력을 변경할 수 있지만, 이러한 작업 자체가 새로운 애니메이션 프레임을 생성하는 것은 아니며, 단지 현재 애니메이션 프레임을 업데이트할 뿐입니다.
4.3.1. 문서 타임라인
문서 타임라인은 타임라인의 한 종류로, 문서에 연결되어 있으며, 현재 시간은 애니메이션을 업데이트하고 이벤트를 전송 절차가 실행될 때마다 제공되는 now timestamp로부터 고정 오프셋을 계산하여 결정됩니다. 이 고정 오프셋을 문서 타임라인의 원점 시간이라고 합니다.
"origin time"보다 더 나은 용어가 필요합니다— "time origin"과 너무 유사합니다. [Issue #2079]
연결된 문서의 시간 원점이 설정되기 전에는, 문서 타임라인은 비활성 상태입니다.
문서 타임라인이 Document
에 연결되어 있고,
해당 문서가 활성 문서가 아니라면 비활성으로 간주됩니다.
타임라인 시간 timeline time을 원점 기준 시간으로 변환하려면, 문서 타임라인 timeline에서 timeline time과 timeline의 원점 시간을 합산하여 반환합니다. timeline이 비활성 상태라면, 미해결 시간 값을 반환합니다.
4.3.2. 문서 기본 타임라인
각 Document
는 문서 타임라인을 가지며, 이를
기본 문서 타임라인이라고 합니다.
기본 문서 타임라인은 각 문서에 대해 고유하며,
document.open() [HTML] 호출을 포함하여 문서의 생명주기 동안 유지됩니다.
기본 문서 타임라인의 원점 시간은 0입니다.
문서 타임라인에 제공되는 now timestamp 값에는 스케일링이 적용되지 않으므로, 해당 타임라인이 생성하는 시간 값은 벽시계 밀리초에 비례합니다.
또한, 기본 문서 타임라인의 시간 값은 시간 원점으로부터 오프셋이 0이므로,
document.timeline.currentTime
은 Performance.now()
[HR-TIME]와 대략적으로 일치합니다. 단,
document.timeline.currentTime
은 애니메이션을
업데이트하고 이벤트를 전송 절차를 호출하는 사이에는 변경되지 않습니다.
4.4. 애니메이션
타임라인의 자식들은 애니메이션이라고 불립니다. 애니메이션은 애니메이션 효과를 갖는데, 이는 특정 시간 동작의 정적 기술이며, 이를 타임라인에 연결하여 실행되도록 합니다. 애니메이션은 애니메이션 효과와 타임라인 간의 연결을 일시정지, 탐색, 속도 제어 등 런타임 제어도 할 수 있게 해줍니다. 애니메이션과 애니메이션 효과의 관계는 DVD 플레이어와 DVD의 관계와 유사합니다.
애니메이션은 하나의 애니메이션 효과(이를 연관 효과라 함)를 타임라인에 연결하고, 재생 제어를 제공합니다. 이 두 연결은 모두 선택적이며 구성 가능하므로, 애니메이션은 특정 시점에 연관 효과나 타임라인이 없을 수도 있습니다.
애니메이션의 타이밍용 문서는 Document
이며,
해당 타임라인이 문서에
연결되어 있을 때 해당됩니다.
애니메이션이 타임라인에 연결되어 있지 않거나, 타임라인이 문서와 연결되어 있지 않으면, 타이밍용 문서가 없습니다.
애니메이션의 시작 시간은 타임라인의 시간 값이며, 연관 효과가 재생 시작으로 예약될 때의 값입니다. 애니메이션의 시작 시간은 처음에는 미해결 상태입니다.
애니메이션은 또한 홀드 시간 시간 값도 유지하며, 일시정지 등 상황에서 애니메이션의 출력 시간 값(현재 시간이라 함)을 고정할 때 사용됩니다. 홀드 시간 역시 처음에는 미해결입니다.
상충하는 애니메이션들의 상대적 순서를 정하기 위해, 애니메이션들은 생성된 순서대로 글로벌 애니메이션 리스트에 추가됩니다. 하지만 특정 애니메이션 클래스에서는 다른 정렬 방식도 제공할 수 있습니다 (§ 5.4.1 애니메이션 클래스 참고).
4.4.1. 애니메이션의 타임라인 설정
애니메이션의 타임라인 설정 절차(애니메이션 animation을 new timeline으로, null일 수 있음)는 다음과 같습니다:
-
old timeline을 animation의 현재 타임라인(있다면)으로 설정합니다.
-
new timeline이 old timeline과 동일 객체라면, 절차를 중단합니다.
-
animation의 타임라인을 new timeline으로 설정합니다.
-
animation의 시작 시간이 해결됨이라면, animation의 홀드 시간을 미해결로 설정합니다.
참고: 이 단계는 animation의 완료 상태가 "고착"되지 않고, 갱신된 현재 시간 기준으로 재평가되도록 보장합니다.
-
animation에 대해 애니메이션 완료 상태 업데이트 절차를 실행합니다. did seek 플래그는 false, synchronously notify 플래그도 false로 설정합니다.
4.4.2. 애니메이션의 연관 효과 설정
애니메이션의 연관 효과 설정 절차(애니메이션 animation을 new effect로, null일 수 있음)는 다음과 같습니다:
-
old effect를 animation의 현재 연관 효과(있다면)로 설정합니다.
-
new effect가 old effect와 동일 객체라면, 절차를 중단합니다.
-
animation에 대기 중인 일시정지 작업이 있다면, animation이 준비됨 상태가 되자마자 해당 작업을 실행하도록 다시 예약합니다.
-
animation에 대기 중인 재생 작업이 있다면, animation이 준비됨 상태가 되고 new effect로 재생할 수 있을 때 실행하도록 다시 예약합니다.
-
new effect가
null
이 아니고, new effect가 다른 애니메이션(previous animation)의 연관 효과라면, previous animation에 대해 본 절차(애니메이션의 연관 효과 설정)를 null을 new effect로 넘겨 실행합니다. -
animation의 연관 효과를 new effect로 설정합니다.
-
animation에 대해 애니메이션 완료 상태 업데이트 절차를 실행합니다. did seek 플래그는 false, synchronously notify 플래그도 false로 설정합니다.
4.4.3. 애니메이션의 현재 시간
애니메이션은 연관 효과에 시간 값을 제공하며, 이를 현재 시간이라고 합니다.
현재 시간은 아래 조건들 중 처음으로 일치하는 조건에 따라 계산됩니다:
4.4.4. 애니메이션의 현재 시간 설정
애니메이션의 현재 시간은 새로운 값으로 설정되어 탐색할 수 있습니다. 현재 시간을 설정하는 절차는 두 부분으로 정의됩니다.
현재 시간 조용히 설정 절차(애니메이션 animation을 seek time으로)는 다음과 같습니다:
-
seek time이 미해결 시간 값이라면, 아래 단계를 실행합니다.
-
animation에 연관된 타임라인이 없거나, 해당 타임라인이 비활성이면, animation의 시작 시간을 미해결로 설정합니다.
이 불변식은 활성 타임라인이 없는 경우 시작 시간 또는 애니메이션의 현재 시간만 설정할 수 있음을 보장합니다.
현재 시간 설정 절차(애니메이션 animation을 seek time으로)는 다음과 같습니다:
-
animation의 현재 시간 조용히 설정 단계를 seek time으로 실행합니다.
-
animation에 대기 중인 일시정지 작업이 있다면, 동기적으로 일시정지 작업을 완료합니다. 아래 단계를 실행하세요:
-
animation의 홀드 시간을 seek time으로 설정합니다.
-
대기 중인 재생 속도 적용을 animation에 실행합니다.
-
대기 중인 일시정지 작업을 취소합니다.
-
resolve animation의 현재 ready promise를 animation으로 해결합니다.
-
-
animation에 대해 애니메이션 완료 상태 업데이트 절차를 실행합니다. did seek 플래그는 true, synchronously notify 플래그는 false로 설정합니다.
4.4.5. 애니메이션의 시작 시간 설정
시작 시간 설정 절차는 animation, animation을 new start time으로 설정할 때 다음과 같습니다:
-
timeline time을 animation이 연결된 타임라인의 현재 시간 값으로 설정합니다. animation에 연결된 타임라인이 없거나, 연결된 타임라인이 비활성 상태라면, timeline time을 미해결로 설정합니다.
-
timeline time이 미해결이고 new start time이 해결됨이라면, animation의 홀드 시간을 미해결로 설정합니다.
-
previous current time을 animation의 현재 시간으로 설정합니다.
참고: 이는 앞 단계의 변경이 적용된 이후의 현재 시간으로, 이로 인해 현재 시간이 미해결이 될 수 있습니다.
-
대기 중인 재생 속도 적용을 animation에 실행합니다.
-
animation의 시작 시간을 new start time으로 설정합니다.
-
다음 중 첫 번째로 일치하는 조건에 따라 animation의 홀드 시간을 업데이트합니다:
-
animation에 대기 중인 재생 작업 또는 대기 중인 일시정지 작업이 있다면, 해당 작업을 취소하고 resolve를 통해 animation의 현재 ready promise를 animation으로 해결합니다.
-
animation에 대해 애니메이션 완료 상태 업데이트 절차를 실행합니다. did seek 플래그는 true, synchronously notify 플래그는 false로 설정합니다.
4.4.6. 연관 효과 대기
이 섹션은 규범적이지 않습니다
애니메이션이 수행하는 일부 작업은 즉시 발생하지 않을 수 있습니다. 예를 들어, 일부 사용자 에이전트는 애니메이션의 재생을 별도의 프로세스나 특수 그래픽 하드웨어에 위임할 수 있으며, 이 과정에서 준비 시간이 발생할 수 있습니다.
이런 애니메이션이 트리거된 순간부터 타이밍이 시작된다면, 애니메이션의 첫 번째와 두 번째 프레임 사이에 준비 시간만큼의 큰 점프가 생길 수 있습니다.
이 문제를 방지하기 위해, 웹 애니메이션은 일반적으로 애니메이션의 첫 프레임이 완료되는 순간부터 타이밍을 시작합니다. 이는 애니메이션의 시작 시간이 미해결로 표시되다가, 애니메이션이 준비됨이 되면 해결됨으로 바뀌는 방식으로 나타납니다. 콘텐츠는 시작 시간을 해결됨 시간 값으로 설정해 이 동작을 비활성화할 수 있습니다.
애니메이션은 아래 두 조건이 모두 충족되는 최초의 순간에 준비됨 상태가 됩니다:
-
사용자 에이전트가 애니메이션의 연관 효과 재생을 시작하기 위한 모든 준비(키프레임 효과의 첫 프레임 렌더링 등)를 완료한 경우
4.4.7. 현재 ready promise
각 애니메이션은 현재 ready promise를 가집니다. 현재 ready promise는 초기에는 Promise 객체로, 애니메이션 자체를 값으로 하여 새로 해결된 Promise 생성 절차를 사용해 생성되며, 애니메이션의 관련 Realm에서 생성됩니다.
이 객체는 애니메이션이 대기 중인 재생 작업 또는 대기 중인 일시정지 작업을 새로 큐에 추가할 때마다, 또는 애니메이션이 취소될 때마다(§ 4.4.14 애니메이션 취소 참고) 새로운 Promise 객체로 대체됩니다.
동일 객체가 재생/일시정지 모두에 사용되므로, 개발자는 Promise 객체가 해결될 때 애니메이션의 상태를 확인하는 것을 권장합니다.
예를 들어, 아래 코드에서는 현재 ready promise가 해결될 때 애니메이션의 상태는 running입니다.
이는 play
작업이 대기 중인 재생 작업이 아직 큐에 있는 동안 발생하기 때문에 현재 ready promise가 재사용되기 때문입니다.
4.4.8. 애니메이션 재생
애니메이션 재생 절차는 animation에 대해 auto-rewind 플래그가 주어졌을 때 다음과 같습니다:
-
aborted pause를, animation에 대기 중 일시정지 작업이 있으면 true, 아니면 false인 불리언 플래그로 설정합니다.
-
has pending ready promise를 초기값 false인 불리언 플래그로 설정합니다.
-
auto-rewind 플래그가 true라면, 아래 조건 중 첫 번째에 해당하는 경우의 단계를 실행합니다:
-
seek time을 0으로 설정합니다.
-
- 연관 효과 종료가 양의 무한대인 경우,
-
throw "
InvalidStateError
"DOMException
예외를 발생시키고, 절차를 중단합니다. - 그 밖의 경우,
-
seek time을 animation의 연관 효과 종료로 설정합니다.
-
다음 세 조건이 모두 참이면:
seek time을 0으로 설정합니다.
참고: 위 단계는 auto-rewind 플래그 설정과 관계없이 이 절차가 유휴 애니메이션을 재생하도록 보장합니다.
-
has finite timeline을, animation이 타임라인에 연결되어 있고, 그 타임라인이 단조 증가가 아니면 true로 설정합니다.
-
seek time이 해결됨이라면,
- has finite timeline이 true인 경우,
-
-
animation의 시작 시간을 seek time으로 설정합니다.
-
대기 중 재생 속도 적용을 animation에 실행합니다.
-
- 그 밖의 경우,
-
animation의 홀드 시간을 seek time으로 설정합니다.
-
animation에 대기 중 재생 작업 또는 대기 중 일시정지 작업이 있다면,
-
해당 작업을 취소합니다.
-
has pending ready promise를 true로 설정합니다.
-
-
아래 네 조건이 모두 참이면:
-
seek time이 미해결이고
-
aborted pause가 false이고
-
animation에 대기 중 재생 속도가 없는 경우,
절차를 중단합니다.
-
has pending ready promise가 false라면, animation의 현재 ready promise를 새 promise로, 관련 Realm에서 설정합니다.
-
animation이 준비됨 상태가 되자마자 실행될 작업을 예약합니다. 해당 작업은 다음 단계를 실행합니다:
-
아래에서 첫 번째로 일치하는 조건의 단계를 실행합니다:
- animation의 홀드 시간이 해결됨인 경우,
- animation의 시작 시간 이 해결됨이고 animation에 대기 중 재생 속도가 있는 경우,
-
resolve animation의 현재 ready promise를 animation으로 해결합니다.
-
animation에 대해 애니메이션 완료 상태 업데이트 절차를 실행합니다. did seek 플래그는 false, synchronously notify 플래그도 false로 설정합니다.
위 두 단계의 순서가 중요합니다. 즉, 길이가 0인 연관 효과를 가진 애니메이션은 현재 ready promise가 현재 finished promise보다 먼저 resolve됩니다.
위 작업이 예약되어 아직 실행되지 않은 동안 animation은 대기 중 재생 작업을 갖는 것으로 간주합니다. 하지만 작업이 실행 중일 때는 animation에 대기 중 재생 작업이 없습니다.
만약 사용자 에이전트가 animation이 즉시 준비됨이라고 판단하면, 위 작업을 마이크로태스크로 예약해 다음 마이크로태스크 체크포인트에서 실행할 수 있습니다. 하지만 동기적으로 작업을 실행하면 안 됩니다.
위 요구사항에 따라 대기 중 재생 작업을 비동기로 실행해야 하므로 아래 코드가 구현 간에 일관되게 동작합니다:
animation
. play(); animation. ready. then( () => { console. log( '재생 시작' ); }, () => { console. log( '재생 취소됨' ); } ); // 어떤 조건으로 인해 재생이 취소되어야 한다면... animation. cancel(); // "재생 취소됨"이 콘솔에 출력됩니다. 위 코드에서 대기 중 재생 작업이 동기적으로 실행된다면 현재 ready promise가 reject되지 않을 수 있습니다.
-
animation에 대해 애니메이션 완료 상태 업데이트 절차를 실행합니다. did seek 플래그는 false, synchronously notify 플래그도 false로 설정합니다.
4.4.9. 애니메이션 일시정지
애니메이션에 미해결 시작 시간이 있을 때마다, 현재 시간이 일시적으로 중단됩니다.
애니메이션 재생과 마찬가지로, 일시정지는 즉시 발생하지 않을 수 있습니다(§ 4.4.6 연관 효과 대기 참고). 예를 들어, 애니메이션이 별도의 프로세스에서 수행되는 경우, 애니메이션 프로세스가 그린 상태를 반영하도록 현재 시간을 동기화해야 할 수도 있습니다.
애니메이션 일시정지 절차(animation)는 다음과 같습니다:
-
animation에 대기 중 일시정지 작업이 있으면 이 단계를 중단합니다.
-
has finite timeline을, animation에 연결된 타임라인이 단조 증가가 아니면 true로 설정합니다.
-
animation의 현재 시간이 미해결이면, 아래에서 첫 번째로 일치하는 조건의 단계를 수행합니다:
- animation의 재생 속도가 ≥ 0일 때,
-
seek time을 0으로 설정합니다.
- 그 밖의 경우,
-
- 연관 효과 종료가 양의 무한대인 경우,
-
throw "
InvalidStateError
"DOMException
예외를 발생시키고 이 단계를 중단합니다. - 그 밖의 경우,
-
seek time을 animation의 연관 효과 종료로 설정합니다.
-
seek time이 해결됨이면,
-
has pending ready promise를 초기값 false인 불리언 플래그로 설정합니다.
-
animation에 대기 중 재생 작업이 있으면, 해당 작업을 취소하고 has pending ready promise를 true로 설정합니다.
-
has pending ready promise가 false라면, animation의 현재 ready promise를 새 promise로 관련 Realm에 설정합니다.
-
아래 두 조건이 모두 충족되는 최초의 순간에 작업을 예약합니다:
해당 작업은 아래 단계를 수행합니다:
-
ready time을 animation이 연결된 타임라인의, 사용자 에이전트가 animation의 연관 효과 일시정지 처리를 완료한 순간의 시간 값으로 설정합니다.
-
animation의 시작 시간이 해결됨이고 홀드 시간이 해결되지 않았다면, animation의 홀드 시간을
(ready time - 시작 시간) × 재생 속도
결과로 설정합니다.참고: 홀드 시간은 애니메이션이 완료됨 상태이거나, 대기 중 재생 작업이 있을 때 이미 설정되어 있을 수 있습니다. 두 경우 모두 홀드 시간을 일시정지 상태로 진입할 때 유지해야 합니다.
-
대기 중 재생 속도 적용을 animation에 실행합니다.
-
animation의 시작 시간을 미해결로 만듭니다.
-
resolve animation의 현재 ready promise를 animation으로 해결합니다.
-
animation에 대해 애니메이션 완료 상태 업데이트 절차를 실행합니다. did seek 플래그는 false, synchronously notify 플래그도 false로 설정합니다.
위 작업이 예약되어 아직 실행되지 않은 동안 animation은 대기 중 일시정지 작업을 갖는 것으로 간주합니다. 하지만 작업이 실행 중일 때는 animation에 대기 중 일시정지 작업이 없습니다.
대기 중 재생 작업과 마찬가지로, 사용자 에이전트는 대기 중 일시정지 작업을 반드시 비동기로 실행해야 하며, 이는 다음 마이크로태스크 체크포인트에서 실행될 수 있습니다.
-
-
animation에 대해 애니메이션 완료 상태 업데이트 절차를 실행합니다. did seek 플래그는 false, synchronously notify 플래그도 false로 설정합니다.
4.4.10. 끝에 도달
이 섹션은 규범적이지 않습니다
DVD 플레이어나 카세트 플레이어는 일반적으로 미디어의 끝에 도달할 때까지 재생을 계속하다가 멈춥니다. 이러한 플레이어가 역재생이 가능하다면, 미디어의 시작점에 도달하면 재생이 멈춥니다. 이 동작을 모방하고, HTML의 미디어 요소 [HTML]와 일관성을 제공하기 위해, 웹 애니메이션의 애니메이션들은 연관 효과의 종료 시간을 넘어서 앞으로 재생되지 않고, 0초 이전으로 역재생되지 않습니다.
애니메이션이 재생 범위의 자연스러운 경계에 도달하면 완료됨 상태가 되었다고 합니다.
현재 시간을 제한하는 효과는 아래 그림과 같습니다.
하지만 애니메이션의 현재 시간을 연관 효과의 끝을 넘는 시간으로 탐색하는 것도 가능합니다. 이 경우 현재 시간은 진행되지 않고, 애니메이션은 탐색된 시간에 일시정지된 것처럼 동작합니다.
예를 들어, 연관 효과가 없는 애니메이션의 현재 시간을 5초로 탐색할 수 있습니다. 이후 연관 효과가 5초보다 늦게 종료되는 종료 시간과 함께 연결된다면, 재생은 5초 시점부터 시작됩니다.
위와 유사하게, 애니메이션의 연관 효과 길이가 변경될 때도 비슷한 동작이 발생할 수 있습니다.
4.4.11. 현재 finished promise
각 애니메이션은 현재 finished promise를 가집니다. 현재 finished promise는 초기에는 pending 상태의 Promise 객체입니다.
이 객체는 애니메이션이 완료됨 재생 상태를 벗어날 때마다 새로운 promise로 대체됩니다.
4.4.12. 완료 상태 업데이트
재생 속도가 양수인 애니메이션의 경우, 현재 시간은 연관 효과 종료까지 계속 증가합니다.
애니메이션의 연관 효과 종료는 해당 애니메이션의 연관 효과의 종료 시간과 같습니다. 애니메이션에 연관 효과가 없으면, 연관 효과 종료는 0입니다.
재생 속도가 음수인 애니메이션의 경우, 현재 시간은 0까지 계속 감소합니다.
실행 중인 애니메이션이 이 경계에 도달하거나 넘어서고, 시작 시간이 해결됨이면 완료됨 상태라고 합니다.
이 경계의 도달 여부는 애니메이션 객체가 수정될 때마다 아래 정의된 애니메이션 완료 상태 업데이트 절차를 통해 확인됩니다. 이 절차는 애니메이션 및 이벤트 업데이트 절차의 일부로도 실행됩니다. 두 경우 모두 아래 정의된 did seek 플래그는 false로 설정됩니다.
각 애니메이션에 대해 사용자 에이전트는 이전 현재 시간 시간 값을 관리하며, 이 값은 원래 미해결입니다.
일반 재생 중에는 애니메이션의 현재 시간이 위에서 설명한 경계로 제한되지만, 현재 시간 설정 절차를 사용하면 이 경계를 벗어난 시간으로 탐색할 수도 있습니다.
애니메이션 완료 상태 업데이트 절차(animation, did seek 플래그(현재 시간 설정 후 업데이트 여부), synchronously notify 플래그(즉시 이벤트 큐 및 promise 처리 기대 여부))는 다음과 같습니다:
-
unconstrained current time을 계산합니다. did seek이 false이면 홀드 시간 대신 미해결 시간 값을 사용해 현재 시간을 계산합니다. did seek이 true이면 unconstrained current time은 현재 시간과 같습니다.
참고: 이는 타임라인 방향 변경을 허용하기 위함입니다. 이 정의가 없다면, 한 번 완료된 애니메이션은 타임라인이 반대 방향으로 진행되어도 계속 완료 상태로 남습니다.
-
아래 세 조건이 모두 참이면,
-
unconstrained current time이 해결됨이고, 그리고
-
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이 활성 타임라인에 연결되어 있을 때,
-
아래 단계를 수행합니다:
-
-
current finished state를, animation의 재생 상태가 완료됨이면 true, 아니면 false로 설정합니다.
-
current finished state가 true이고 현재 finished promise가 아직 resolve되지 않았다면, 아래 단계를 수행합니다:
-
finish notification steps 절차는 다음과 같습니다:
-
resolve animation의 현재 finished promise 객체를 animation으로 resolve합니다.
-
Create
AnimationPlaybackEvent
객체 finishEvent를 생성합니다. -
finishEvent의
currentTime
속성을 animation의 현재 시간으로 설정합니다. -
finishEvent의
timelineTime
속성을 animation이 연결된 타임라인의 현재 시간으로 설정합니다. 타임라인이 없다면, 또는 타임라인이 비활성이면timelineTime
을null
로 설정합니다. -
animation에 타이밍용 문서가 있다면, finishEvent를 해당 타이밍용 문서의 대기 중 애니메이션 이벤트 큐에 타겟 animation과 함께 추가합니다. 예정 이벤트 시간은 변환한 animation의 연관 효과 종료를 원점 기준 시간으로 사용합니다.
그 외의 경우, 작업을 큐에 추가하여 finishEvent를 animation에서 디스패치합니다. 해당 작업의 소스는 DOM 조작 작업 소스입니다.
-
synchronously notify가 true이면, 이 animation의 finish notification steps 실행을 위한 모든 큐에 있는 마이크로태스크를 취소하고, finish notification steps를 즉시 실행합니다.
그 외에 synchronously notify가 false이면, 마이크로태스크를 큐에 추가하여 finish notification steps를 animation에 대해 실행합니다. 이미 해당 단계를 실행하기 위한 마이크로태스크가 큐에 있으면 추가하지 않습니다.
-
-
current finished state가 false이고, animation의 현재 finished promise가 이미 resolve된 경우, animation의 현재 finished promise를 새 promise로, 관련 Realm에서 설정합니다.
일반적으로 애니메이션의 완료 상태 알림은 비동기적으로 수행됩니다. 이렇게 하면 애니메이션이 잠시 완료됨 재생 상태에 들어가도 이벤트가 트리거되거나 promise가 resolve되지 않게 됩니다.
예를 들어, 아래 코드에서 animation
은 일시적으로 완료 상태가 됩니다. 만약 완료 상태 알림이 동기적으로 발생한다면, 이 코드는 finish event가 큐에 추가되고 현재
finished promise가 resolve됩니다. 하지만 두 문장의 순서를 바꿔 iterations
을 먼저 업데이트하면 이런 일이 발생하지
않습니다.
이런 예기치 않은 동작을 방지하기 위해, 애니메이션의 완료 상태 알림은 일반적으로 비동기적으로 수행됩니다.
var animation= elem. animate({ left: '100px' }, 2000 ); animation. playbackRate= 2 ; animation. currentTime= 1000 ; // animation은 이제 완료됨 animation. effect. updateTiming({ iterations: 2 }); // animation은 더 이상 완료 상태가 아님
이 비동기 동작의 한 가지 예외는 애니메이션 완료 절차(보통 finish()
메서드 호출)일 때입니다. 이 경우 작성자가 명확하게 애니메이션을 완료시키려는 의도가 있으므로, 완료 상태 알림이 아래와 같이 동기적으로 발생합니다.
var animation= elem. animate({ left: '100px' }, 1000 ); animation. finish(); // finish 이벤트가 즉시 큐에 추가되고 finished promise가 // resolve됨. 아래 문장 때문에 animation이 완료 상태를 벗어나도 animation. currentTime= 0 ;
애니메이션 완료 절차와 마찬가지로, 애니메이션 취소 절차도 cancel 이벤트를 큐에 추가하고 현재 finished promise 및 현재 ready promise를 동기적으로 reject합니다.
4.4.13. 애니메이션 완료
애니메이션은 아래 정의된 애니메이션 완료 절차를 통해 현재 재생 방향의 자연스러운 끝으로 진행할 수 있습니다(animation에 대해):
-
animation의 실효 재생 속도가 0이거나, 또는 animation의 실효 재생 속도 > 0이고 연관 효과 종료가 무한대라면, throw "
InvalidStateError
"DOMException
예외를 발생시키고 이 단계를 중단합니다. -
대기 중인 재생 속도 적용을 animation에 실행합니다.
-
limit을 다음과 같이 설정합니다:
-
현재 시간 조용히 설정 절차를 limit으로 실행합니다.
-
animation의 시작 시간이 미해결이고 animation이 활성 타임라인과 연결되어 있다면, 시작 시간을 다음과 같이 평가한 결과로 설정합니다:
timeline time - (limit / 재생 속도)
여기서 timeline time은 연결된 타임라인의 현재 시간 값입니다. -
대기 중 일시정지 작업이 있고 시작 시간이 해결됨이면,
-
대기 중 일시정지 작업을 취소합니다.
-
resolve animation의 현재 ready promise를 animation으로 resolve합니다.
-
대기 중 재생 작업이 있고 시작 시간이 해결됨이면, 해당 작업을 취소하고 resolve animation의 현재 ready promise를 animation으로 resolve합니다.
-
animation에 대해 애니메이션 완료 상태 업데이트 절차를 실행합니다. did seek 플래그는 true, synchronously notify 플래그는 true로 설정합니다.
4.4.14. 애니메이션 취소
애니메이션은 취소될 수 있으며, 이로 인해 현재 시간이 미해결이 되어 연관 효과로 인한 모든 효과가 제거됩니다.
애니메이션 취소 절차(animation에 대해)는 다음과 같습니다:
-
animation의 재생 상태가 유휴가 아니라면, 아래 단계를 실행합니다:
-
애니메이션의 대기 작업 재설정 절차를 animation에 대해 실행합니다.
-
reject animation의 현재 finished promise를 "AbortError"라는 이름의 DOMException으로 reject합니다.
-
현재 finished promise의 [[PromiseIsHandled]] 내부 슬롯을 true로 설정합니다.
-
현재 finished promise를 새 promise로, 관련 Realm에서 설정합니다.
-
Create
AnimationPlaybackEvent
객체 cancelEvent를 생성합니다. -
cancelEvent의
currentTime
속성을null
로 설정합니다. -
timeline time을 animation이 연결된 타임라인의 현재 시간으로 설정합니다. animation이 활성 타임라인과 연결되어 있지 않으면, timeline time을 미해결 시간 값으로 설정합니다.
-
cancelEvent의
timelineTime
속성을 timeline time으로 설정합니다. timeline time이 미해결이면null
로 설정합니다. -
animation에 타이밍용 문서가 있다면, cancelEvent를 해당 타이밍용 문서의 대기 중 애니메이션 이벤트 큐에 타겟 animation과 함께 추가합니다. animation이 활성 타임라인과 연결되어 있고, 타임라인 시간이 원점 기준 시간으로 변환하는 절차를 정의한다면, 예정 이벤트 시간을 해당 절차의 결과로 timeline time에 대해 설정합니다. 그렇지 않으면 예정 이벤트 시간은 미해결 시간 값입니다.
그 외의 경우, 작업을 큐에 추가하여 cancelEvent를 animation에서 디스패치합니다. 해당 작업의 소스는 DOM 조작 작업 소스입니다.
-
애니메이션의 대기 작업 재설정 절차(animation에 대해)는 다음과 같습니다:
-
animation에 대기 중 재생 작업이나 대기 중 일시정지 작업이 없다면, 이 절차를 중단합니다.
-
animation에 대기 중 재생 작업이 있다면, 해당 작업을 취소합니다.
-
animation에 대기 중 일시정지 작업이 있다면, 해당 작업을 취소합니다.
-
대기 중 재생 속도 적용을 animation에 실행합니다.
-
reject animation의 현재 ready promise를 "AbortError"라는 이름의 DOMException으로 reject합니다.
-
animation의 현재 ready promise의 [[PromiseIsHandled]] 내부 슬롯을 true로 설정합니다.
-
animation의 현재 ready promise를 새로 resolve된 Promise 객체로, 값은 animation이며 관련 Realm에서 생성합니다.
4.4.15. 속도 제어
애니메이션의 재생 속도는 재생 속도를 설정하여 제어할 수 있습니다. 예를 들어, 재생 속도를 2로 설정하면 애니메이션의 현재 시간이 타임라인의 속도의 두 배로 증가합니다. 마찬가지로, 재생 속도가 -1이면 애니메이션의 현재 시간이 타임라인의 시간 값이 증가하는 속도만큼 감소합니다.
애니메이션은 재생 속도를 가지며, 이는 연결된 타임라인의 시간 값 변화 속도를 애니메이션의 현재 시간 변화로 변환하는 스케일 계수를 제공합니다. 재생 속도는 기본적으로 1입니다.
애니메이션의 재생 속도를 0으로 설정하면 사실상 애니메이션이 일시정지됩니다(단, 재생 상태가 반드시 일시정지됨이 되는 것은 아닙니다).
4.4.15.1. 애니메이션의 재생 속도 설정
재생 속도 설정 절차는 애니메이션 animation을 new playback rate로 설정할 때 다음과 같습니다:
-
animation의 대기 중 재생 속도를 모두 초기화합니다.
-
previous playback rate를 animation의 현재 실효 재생 속도로 설정합니다.
-
재생 속도를 new playback rate로 설정합니다.
-
아래에서 첫 번째로 일치하는 조건의 단계를 실행합니다:
- animation이 단조 증가 타임라인에 연결되어 있고, previous time이 해결됨인 경우,
-
animation의 현재 시간 설정 절차를 previous time으로 실행합니다.
-
animation이 null이 아닌 타임라인에 연결되어 있고, 해당 타임라인이 단조 증가가 아니며, 시작 시간이 해결됨이고, 연관 효과 종료가 무한대가 아니며, 다음 중 하나라도 참일 때:
-
previous playback rate < 0이고 new playback rate ≥ 0, 또는
-
previous playback rate ≥ 0이고 new playback rate < 0,
-
-
animation의 시작 시간을
연관 효과 종료 - 시작 시간
결과로 설정합니다.참고: 이는 단조 증가하지 않는 타임라인에서 시작/종료 시점을 뒤집어, 다른 방향에서도 시작 시간의 상대적 오프셋을 유지합니다.
4.4.15.2. 애니메이션의 재생 속도 원활하게 업데이트
다른 프로세스나 쓰레드에서 실행 중인 애니메이션의 경우, 재생 속도 설정 절차가 동기화되지 않은 상태에서 실행되면 애니메이션이 튀는 현상이 발생할 수 있습니다.
애니메이션의 재생 속도를 원활하게 변경하기 위해, 애니메이션은 대기 중 재생 속도를 가질 수 있으며, 이는 동기화가 필요할 때(다른 쓰레드/프로세스에서 실행 중인 애니메이션 등) 적용될 재생 속도를 의미합니다.
초기에는 애니메이션의 대기 중 재생 속도는 설정되지 않은 상태입니다.
animation의 실효 재생 속도는 대기 중 재생 속도가 있으면 그 값이고, 없으면 재생 속도입니다.
애니메이션 animation에 대해 대기 중 재생 속도 적용을 실행할 때는 아래 단계를 따릅니다:
-
animation에 대기 중 재생 속도가 없다면, 이 단계를 중단합니다.
-
animation의 재생 속도를 대기 중 재생 속도로 설정합니다.
-
animation의 대기 중 재생 속도를 초기화합니다.
애니메이션 animation에 대해 재생 속도 원활하게 업데이트 절차(new playback rate로, 현재 시간을 유지함)는 다음과 같습니다:
-
previous play state를 animation의 재생 상태로 설정합니다.
참고: animation의 실효 재생 속도를 업데이트하기 전에 재생 상태를 기록해야 합니다. 아래 로직에서는 animation이 현재 완료됨이면, 이후 대기 중 재생 속도 적용 후 완료 상태가 아니더라도 바로 적용해야 합니다.
-
animation의 대기 중 재생 속도를 new playback rate로 설정합니다.
-
아래에서 첫 번째로 일치하는 조건의 단계를 실행합니다:
- animation에 대기 중 재생 작업이나 대기 중 일시정지 작업이 있으면,
-
이 단계를 중단합니다.
참고: 서로 다른 종류의 대기 작업은 실행 시 대기 중 재생 속도를 적용하므로, 추가 작업이 필요하지 않습니다.
-
previous play state가 유휴 또는 일시정지됨이거나, animation의 현재 시간이 미해결인 경우,
-
대기 중 재생 속도 적용을 animation에 실행합니다.
참고: 두 번째 조건은, 실행 중인 애니메이션에 대해, 현재 시간이 미해결이고 대기 중 재생 작업이 없으면 아래에서 재생을 시도하지 않도록 하기 위함입니다.
-
previous play state가 완료됨인 경우,
-
-
unconstrained current time을 현재 시간 계산 결과로, 홀드 시간을 미해결 시간 값으로 대체합니다.
-
animation의 시작 시간을 아래 식의 결과로 설정합니다:
timeline time - (unconstrained current time / 대기 중 재생 속도)
여기서 timeline time은 animation이 연결된 타임라인의 현재 시간 값입니다.
대기 중 재생 속도가 0이면, animation의 시작 시간을 timeline time으로 설정합니다.
-
대기 중 재생 속도 적용을 animation에 실행합니다.
-
animation에 대해 애니메이션 완료 상태 업데이트 절차를 실행합니다. did seek 플래그는 false, synchronously notify 플래그는 false로 설정합니다.
-
-
그 밖의 경우,
-
animation에 대해 애니메이션 재생 절차를 auto-rewind 플래그를 false로 설정하여 실행합니다.
4.4.16. 애니메이션 역재생
애니메이션 animation에 대해 역재생 절차는 다음과 같습니다:
-
animation에 연결된 타임라인이 없거나, 연결된 타임라인이 비활성이면, throw "
InvalidStateError
"DOMException
예외를 발생시키고 이 단계를 중단합니다. -
original pending playback rate를 animation의 대기 중 재생 속도로 설정합니다.
-
animation의 대기 중 재생 속도를 실효 재생 속도의 덧셈 역수(즉,
-실효 재생 속도
)로 설정합니다. -
animation에 대해 애니메이션 재생 절차를 auto-rewind 플래그를 true로 설정하여 실행합니다.
만약 애니메이션 재생 절차에서 예외가 발생하면, animation의 대기 중 재생 속도를 original pending playback rate로 되돌리고, 예외를 전파합니다.
4.4.17. 재생 상태
애니메이션은 아래 재생 상태 중 하나로 설명될 수 있습니다. 각 상태에 대해 비규범적인 설명도 함께 제공합니다:
애니메이션 animation의 재생 상태는 아래 조건들 중 첫 번째에 해당하는 상태입니다:
-
모두 다음 조건이 참일 때:
-
animation에 대기 중 재생 작업이나 대기 중 일시정지 작업이 없음
-
→ idle
-
다음 중 하나라도 참일 때:
-
animation에 대기 중 일시정지 작업이 있는 경우, 또는
-
둘 다 animation의 시작 시간이 미해결이고 그리고 대기 중 재생 작업이 없는 경우,
-
-
→ paused
-
→ finished
- 그 밖의 경우,
-
→ running
재생 상태 판정에서 paused play state가 finished play state보다 우선합니다.
단, 애니메이션이 자연스러운 재생 범위를 벗어난 상태에서 일시정지된 경우 start time을 아래와 같이 설정하면 paused에서 finished로 변환할 수 있습니다(재시작 없이):
animation. effect. updateTiming({ duration: 5000 }); animation. currentTime= 4000 ; animation. pause(); animation. ready. then( function () { animation. effect. updateTiming({ duration: 3000 }); alert( animation. playState); // 'paused' 출력 animation. startTime= document. timeline. currentTime- animation. currentTime* animation. playbackRate; alert( animation. playState); // 'finished' 출력 });
4.4.18. 애니메이션 이벤트
애니메이션 이벤트에는 이 명세에서 정의된 애니메이션 재생 이벤트와 CSS 트랜지션의 이벤트 [CSS-TRANSITIONS-1], 그리고 CSS 애니메이션의 이벤트 [CSS-ANIMATIONS-1]가 포함됩니다. 추후 명세에서 더 다양한 애니메이션 이벤트가 추가될 수 있습니다.
각 Document
는
대기 중 애니메이션 이벤트
큐를 유지하며, 애니메이션
이벤트와 해당 이벤트 타겟,
그리고 예정 이벤트 시간을
저장합니다.
예정 이벤트 시간은 시간 값으로,
시간 원점 기준으로 이벤트가 이상적으로 디스패치되었을 때의 시점을 나타냅니다.
이는 애니메이션 및 이벤트 업데이트 절차에서 큐에 있는 애니메이션 이벤트를 시간 순으로 정렬하는 데 사용됩니다.
이 값은 예를 들어 애니메이션의 타임라인이 시간 원점과 관계없는 값을 생성하는 경우(예: 스크롤 위치
기반 타임라인)나 타임라인이 비활성일 때 미해결이 될 수 있습니다.
4.4.18.1. 애니메이션 이벤트 정렬
아래 정의들은 큐에 있는 이벤트를 정렬하는 데 참고용으로 제공됩니다.
애니메이션 시간 값을 타임라인 시간으로 변환은 애니메이션 animation의 시작 시간 기준 상대 시간 값 time을 타임라인 시간으로 변환하는 절차입니다:
-
time이 미해결이면 time을 반환합니다.
-
아래 식을 계산한 결과를 반환합니다:
time × (1 / playback rate) + start time
(playback rate와 start time은 각각 재생 속도와 시작 시간입니다.)
타임라인 시간 값을 원점 기준 시간으로 변환은 타임라인 timeline과 동일 스케일의 시간 값 time을 원점 기준 시간으로 변환하는 절차입니다:
-
timeline time을 애니메이션 시간 값을 타임라인 시간으로 변환한 결과로 설정합니다.
-
timeline time이 미해결이면 time을 반환합니다.
-
animation이 연결된 타임라인에 타임라인 시간 값을 원점 기준 시간으로 변환하는 절차가 없다면, 미해결 시간 값을 반환합니다.
-
해당 절차로 timeline time을 원점 기준 시간으로 변환한 결과를 반환합니다(animation과 연결된 타임라인에 정의된 절차 사용).
4.4.18.2. 애니메이션 재생 이벤트
애니메이션이 재생될 때, 애니메이션 재생 이벤트를 통해 상태 변화를 보고합니다.
애니메이션 재생 이벤트는 타이밍 모델의 속성입니다. 따라서 애니메이션의 연관 효과가 없거나 가시적 결과가 없어도 이벤트는 디스패치됩니다.
4.4.18.3. 애니메이션 재생 이벤트 타입
- finish
-
애니메이션이 finished play state에 진입할 때마다 큐에 추가됩니다.
- cancel
-
애니메이션이 다른 상태에서 idle play state로 진입할 때마다 큐에 추가됩니다. 새로 생성된 애니메이션이 처음부터 idle이면 cancel event가 생성되지 않습니다.
- remove
-
애니메이션이 자동으로 제거될 때마다 큐에 추가됩니다. § 5.5 애니메이션 대체 참고.
4.5. 애니메이션 효과
애니메이션 효과는 타이밍 계층에서 항목을 추상적으로 지칭하는 용어입니다.
4.5.1. 애니메이션 효과와 애니메이션 간의 관계
애니메이션의 연관 효과가 설정되어 있으면, 이는 애니메이션 효과의 한 종류입니다. 연관 효과가 애니메이션에 연결됨 상태라고 합니다. 한 시점에 애니메이션 효과는 최대 하나의 애니메이션에 연결될 수 있습니다.
애니메이션 효과 effect는, 타임라인에 연결됨 timeline 상태일 수 있는데, 이는 effect가 애니메이션에 연결되어 있고, 그 애니메이션이 timeline에 연결되어 있을 때입니다.
4.5.2. 애니메이션 효과의 종류
이 명세에서는 애니메이션 효과의 한 종류로 키프레임 효과만을 정의합니다. 이후 명세 단계에서는 더 다양한 애니메이션 효과가 정의될 예정입니다.
모든 애니메이션 효과 종류는 다음 절에서 설명하는 여러 공통 속성을 정의합니다.
4.5.3. 활성 구간
애니메이션 효과가 실행되도록 예약된 기간을 활성 구간이라고 합니다. 각 애니메이션 효과는 오직 하나의 활성 구간만을 가집니다.
활성 구간의 하한은 보통 이 애니메이션 효과에 연결된 애니메이션의 시작 시간과 일치하지만, 애니메이션 효과의 시작 지연에 의해 이동될 수 있습니다.
구간의 상한은 활성 지속 시간에 의해 결정됩니다.
시작 시간, 시작 지연, 활성 지속 시간의 관계는 아래 그림에서 설명합니다.
(a) 지연이 없는 애니메이션 효과; 시작 시간과 활성 구간 시작이 일치.
(b) 양수 지연이 있는 경우; 활성 구간 시작이 지연만큼 늦춰짐.
(c) 음수 지연이 있는 경우; 활성 구간 시작이 지연만큼 앞당겨짐.
종료 지연도 지정할 수 있지만, 주로 애니메이션을 순차적으로 실행할 때에만 사용됩니다.
애니메이션 효과는 활성 구간을 정의하며, 이 구간 내에서 효과가 동작하도록 예약됩니다. 단, fill mode는 활성 구간 외에도 적용될 수 있습니다.
활성 구간의 하한은 start delay로 정의됩니다.
시작 지연은 애니메이션 효과가 연결된 애니메이션의 시작 시간으로부터의 부호 있는 오프셋입니다.
활성 구간의 길이를 활성 지속 시간이라고 하며, 계산 방법은 § 4.8.2 활성 지속 시간 계산에서 정의합니다.
시작 지연과 마찬가지로,
애니메이션 효과는
종료 지연도 가지며,
이는 주로 다른 애니메이션 효과의 종료 시간 기준으로 애니메이션을 순차적으로 실행할 때 사용됩니다.
보통 시퀀스 효과와 결합하여 사용할 때 유용하나, SVG의 min
속성을 표현하기 위해서도 포함됩니다([SVG11], 19장).
애니메이션 효과의 종료 시간은
max(start delay + 활성 지속 시간 + 종료 지연, 0)
의
결과입니다.
4.5.4. 로컬 시간
로컬 시간은 애니메이션 효과의 특정 시점에서 다음 조건 중 첫 번째로 일치하는 값입니다:
4.5.5. 애니메이션 효과의 페이즈와 상태
특정 시점에서 애니메이션 효과는 세 가지 페이즈 중 하나일 수 있습니다. 애니메이션 효과의 로컬 시간이 미해결이면 아무 페이즈에도 속하지 않습니다.
페이즈별 차이는 아래 그림에서 설명합니다.
페이즈는 다음과 같습니다:
- before phase
-
애니메이션 효과의 로컬 시간이 효과의 활성 구간 및 종료 시간보다 이전이거나, 음수 시작 지연이 적용된 구간에 해당하는 경우입니다.
- active phase
-
애니메이션 효과의 로컬 시간이 효과의 활성 구간 내에 있고, 음수 시작 지연이나 음수 종료 지연 구간이 아닌 경우입니다.
- after phase
-
애니메이션 효과의 로컬 시간이 효과의 활성 구간 또는 종료 시간(음수 종료 지연으로 인해 먼저 올 수도 있음) 이후이지만, 음수 시작 지연 구간에는 해당하지 않는 경우입니다.
이들 페이즈 외에도 애니메이션 효과는 여러 겹치는 상태로도 설명될 수 있습니다. 이 상태들은 오직 하나의 애니메이션 프레임 동안만 정의되며, 주로 모델의 상태적 부분 묘사에 편의를 위해 사용됩니다.
각 상태와 모델 내에서의 용도 요약:
- 재생 중(in play)
- current
-
재생 중이거나, 재생 중이 될 수 있는 애니메이션의 재생 속도에 따라 결정되는 애니메이션 효과에 해당합니다.
- 효과 중(in effect)
-
해결된 활성 시간이 있는 애니메이션 효과에 해당합니다. 이는 애니메이션 효과가 active phase에 있거나, active phase 외에 fill mode(§ 4.6 Fill behavior 참고)에 의해 활성 시간이 해결된 경우입니다. 효과 중 애니메이션 효과만이 타겟에 값을 적용합니다.
각 상태의 규범적 정의는 다음에 이어집니다.
애니메이션 효과 페이즈를 결정하려면 다음 정의가 필요합니다:
- 애니메이션 방향
-
효과가 애니메이션에 연결되어 있고, 연결된 애니메이션의 재생 속도가 0보다 작으면 "backwards"이고, 그 외에는 애니메이션 방향은 "forwards"입니다.
- before-active boundary time
-
max(min(start delay, end time), 0)
- active-after boundary time
-
max(min(start delay + active duration, end time), 0)
애니메이션 효과는 before phase 상태이며, 해당 효과의 로컬 시간이 미해결이 아니고, 아래 조건 중 하나라도 만족하면 before phase에 해당합니다:
-
로컬 시간이 before-active boundary time보다 작거나,
-
애니메이션 방향이 "backwards"이고 로컬 시간이 before-active boundary time과 같은 경우.
애니메이션 효과는 after phase 상태이며, 해당 효과의 로컬 시간이 미해결이 아니고, 아래 조건 중 하나라도 만족하면 after phase에 해당합니다:
-
로컬 시간이 active-after boundary time보다 크거나,
-
애니메이션 방향이 "forwards"이고 로컬 시간이 active-after boundary time과 같은 경우.
애니메이션 효과는 active phase 상태이며, 해당 효과의 로컬 시간이 미해결이 아니고, before phase나 after phase가 아닌 경우입니다.
그리고 위의 어느 페이즈에도 속하지 않는 경우를 편의상 idle phase라고 부르기도 합니다.
애니메이션 효과는 재생 중(in play) 상태이며, 아래 모든 조건을 만족하면 그렇습니다:
-
애니메이션 효과가 active phase에 있고,
애니메이션 효과는 current 상태이며, 아래 조건 중 하나라도 참이면 그렇습니다:
-
애니메이션 효과가 애니메이션에 연결되어 있고, 해당 애니메이션의 재생 속도가 0보다 크며, 애니메이션 효과가 before phase에 있을 때,
-
애니메이션 효과가 애니메이션에 연결되어 있고, 해당 애니메이션의 재생 속도가 0보다 작으며, 애니메이션 효과가 after phase에 있을 때,
-
애니메이션 효과가 애니메이션에 연결되어 있고, 해당 애니메이션이 idle 재생 상태가 아니며, null이 아닌 타임라인과 연결되어 있고, 해당 타임라인이 단조 증가가 아닐 때.
애니메이션 효과는 효과 중(in effect) 상태이며, 활성 시간이 미해결이 아닐 때입니다(§ 4.8.3.1 활성 시간 계산 참고).
4.5.6. 관련 애니메이션
애니메이션은 연관된 애니메이션 효과 연결 여부를 기준으로 관련 있음으로 정의할 수 있습니다.
애니메이션은 다음 조건을 모두 만족하면 관련 있음(relevant)입니다:
-
replace state가 removed가 아닌 경우.
관련 애니메이션(element 또는 pseudo-element target)은, effect target이 target인 애니메이션 효과를 최소 하나 이상 포함하는 모든 애니메이션의 집합입니다.
서브트리의 관련 애니메이션(element, pseudo-element, document 또는 shadow root target)은, effect target이 target의 포함 자손(또는 target이 document나 shadow root인 경우 자손)이거나, 해당 자손의 pseudo-element인 애니메이션 효과를 최소 하나 이상 포함하는 모든 애니메이션의 집합입니다.
4.6. 채움 동작
애니메이션 효과가 재생 중이 아닐 때의 효과는 해당 채움 모드에 의해 결정됩니다.
가능한 채움 모드는 다음과 같습니다:
-
none,
-
forwards,
-
backwards,
-
both.
이 모드들의 규범적 정의는 § 4.8.3.1 활성 시간 계산에서 활성 시간 계산에 포함되어 있습니다.
작성자들은 채움 모드를 사용하여 효과가 무기한 적용되는 애니메이션을 만드는 것을 지양해야 합니다. 채움 모드는 CSS 애니메이션 animation-fill-mode 속성을 표현하기 위해 도입되었습니다 ([CSS-ANIMATIONS-1]). 하지만 이들은 애니메이션 상태가 무한히 누적되는 상황을 만들 수 있어, § 5.5 애니메이션 대체에서 자동 애니메이션 제거가 필요해집니다. 또한 무기한 채움 애니메이션은 모든 애니메이션이 완료된 후에도 지정된 스타일 변경이 오랫동안 효과를 내지 못하게 할 수 있는데, 이는 CSS 계단식에서 애니메이션 스타일이 우선하기 때문입니다([css-cascade-3]).
가능하면, 작성자는 애니메이션의 최종 상태를 지정된 스타일로 직접 설정하는 것을 선호해야 합니다. 이는 애니메이션이 완료될 때까지 기다렸다가 스타일을 업데이트하는 방식으로 아래와 같이 구현할 수 있습니다:
// 아래 애니메이션이 완료된 후 첫 프레임에서, finished promise의 콜백이 먼저 실행되고 스타일이 업데이트되어 깜빡임이 발생하지 않습니다. elem. animate({ transform: 'translateY(100px)' }, 200 ). finished. then(() => { elem. style. transform= 'translateY(100px)' ; });
또는, 작성자가 애니메이션 시작 시 지정된 스타일을 먼저 설정하고, 원래 값에서 애니메이션하는 방식도 사용할 수 있습니다:
여러 애니메이션을 겹쳐놓은 복잡한 효과에서는, 애니메이션을 취소하기 전에 최종 값을 기록하기 위해 임시로 forwards 채움 모드를 사용할 수 있습니다. 예시:
elem. addEventListener( 'click' , async evt=> { const animation= elem. animate( { transform: `translate( ${ evt. clientX} px, ${ evt. clientY} px)` }, { duration: 800 , fill: 'forwards' } ); await animation. finished; // commitStyles는 animation까지의 스타일을 기록하고 elem의 지정 스타일을 갱신합니다. animation. commitStyles(); animation. cancel(); });
4.6.1. 채움 모드
각 채움 모드의 효과는 다음과 같습니다:
- none
-
애니메이션 효과가 재생 중이 아닐 때 아무 효과도 없습니다.
- forwards
-
애니메이션 효과가 after phase에 있을 때, 마지막으로 재생 중이었던 순간과 동일한 반복 진행도 값을 생성합니다.
그 외의 모든 재생 중이 아닌 시간에는 아무 효과가 없습니다.
- backwards
-
애니메이션 효과가 before phase에 있을 때, 가장 처음 재생 중이었던 순간과 동일한 반복 진행도 값을 생성합니다.
그 외의 모든 재생 중이 아닌 시간에는 아무 효과가 없습니다.
- both
-
애니메이션 효과가 before phase에 있으면 backwards 채움 동작이 적용됩니다.
애니메이션 효과가 after phase에 있으면 forwards 채움 동작이 적용됩니다.
아래에 다양한 채움 모드와 그로 인한 상태 예시가 나와 있습니다.
(a) 채움 모드 "none". 애니메이션 효과는 활성 phase 외에는 아무 효과도 없습니다.
(b) 채움 모드 "forwards". 활성 phase가 끝난 후에도 반복 진행도 값이 채움 값으로 유지됩니다.
(c) 채움 모드 "backwards". 활성 phase 시작 전까지 채움 값이 적용됩니다.
(d) 채움 모드 "both". 활성 phase 전후 모두 채움 값이 적용됩니다.
참고: 채움 모드를 설정해도 활성 구간의 끝점이나 phase 경계에는 영향이 없습니다. 그러나 채움 모드는 타이밍 모델의 여러 속성에 영향을 주는데, 활성 시간은 애니메이션 효과가 active phase 내에 있거나 채움이 적용될 때만 정의됩니다(미해결이 아님).
4.7. 반복
4.7.1. 반복 구간
애니메이션 효과가 정해진 횟수 또는 무한히 반복되도록 지정할 수 있습니다. 이 반복은 활성 구간 내에서 발생합니다. 한 번 반복이 실행되는 시간 범위를 반복 구간이라고 합니다.
활성 구간과 달리, 애니메이션 효과는 여러 반복 구간을 가질 수 있지만, 일반적으로 현재 반복에 해당하는 구간만 사용됩니다.
한 번 반복되는 길이를 반복 지속 시간이라고 하며, 애니메이션 효과의 초기 반복 지속 시간은 0입니다.
반복 지속 시간과 활성 지속 시간을 비교하면 다음과 같습니다:
- 반복 지속 시간
-
애니메이션 효과의 한 번 반복이 완료되는 데 걸리는 시간.
- 활성 지속 시간
-
전체 애니메이션 효과가 완료되는 데 걸리는 시간(반복 포함). 이 값은 반복 지속 시간보다 길거나 짧을 수 있습니다.
반복 지속 시간과 활성 지속 시간의 관계는 아래 그림에서 설명합니다.
4.7.2. 반복 제어
애니메이션 효과가 반복되는 횟수를 반복 횟수라고 합니다. 반복 횟수는 0 이상의 실수입니다. 반복 횟수는 양의 무한대가 될 수 있으며, 이는 애니메이션 효과가 무한히 반복됨을 의미합니다.
반복 횟수 외에도, 애니메이션 효과는 반복 시작 속성을 가지며, 이는 애니메이션 효과가 반복 시리즈 중 어느 위치에서 시작할지 지정합니다. 반복 시작은 0 이상의 유한 실수입니다.
이 파라미터들의 동작은 § 4.8 핵심 애니메이션 효과 계산에서 정의됩니다.
반복 횟수와 반복 시작 파라미터의 효과는 아래 그림에서 설명합니다.
첫 번째 예에서는 반복 횟수가 2.5로, 세 번째 반복이 반복 구간의 중간에서 잘립니다.
두 번째 예시는 반복 시작이 0.5인 경우로, 애니메이션 효과가 첫 번째 반복의 중간에서 시작하게 됩니다.
반복 횟수 파라미터와 달리, 반복 시작 파라미터는 활성 지속 시간의 길이에 영향을 주지 않습니다.
반복 시작이 1 이상인 값은, iteration composite operation이 accumulate로 설정된 애니메이션 효과와 조합할 때만 일반적으로 유용합니다.
4.7.3. 반복 시간 공간
Web Animations에서는 모든 시간이 어떤 기준점에 상대적입니다. 이러한 기준점의 차이로 서로 다른 시간 공간이 생깁니다.
이는 컴퓨터 그래픽에서 사용하는 좌표 공간과 비교할 수 있습니다. 시간 공간의 0초는 좌표 공간의 원점에 해당합니다.
반복되는 애니메이션은 애니메이션이 반복될 때마다 새로운 시간 공간, 즉 반복 시간 공간을 형성한다고 설명할 수 있습니다.
반복 시간 공간은 애니메이션 효과의 현재 반복이 시작되는 시점을 0초로 하는 시간 공간입니다.
Web Animations 모델 내에서는 활성 시간도 사용하는데, 이는 활성 구간의 시작점에 상대적인 시간입니다. 이 시간 공간은 모델 내부에서만 사용되며, 프로그래밍 인터페이스나 마크업에서는 노출되지 않습니다.
이러한 시간 공간들은 아래 그림에서 설명합니다.
참고: 시간 공간 자체에는 경계가 없지만, Web Animations에서는 활성 시간과 반복 진행도를 다이어그램처럼 특정 범위로 제한(clamp)합니다. 예를 들어, 활성 시간 공간에서 -1초도 유효한 시간이지만, § 4.8.3.1 활성 시간 계산 절차에서는 음수 값이 반환되지 않습니다.
이들 시간 공간 외에도 문서 시간 공간이라고 부르는 것이 있는데, 이는 기본 문서
타임라인의 시간 값이 속한 Document
의
현재 글로벌 객체의 시간 공간을 의미합니다.
4.7.4. 구간 타이밍
애니메이션 효과가 반복될 때 반복 경계에서의 동작을 정의해야 합니다.
이를 포함한 모든 구간 타이밍에 대해 Web Animations는 endpoint-exclusive 모델을 사용합니다.
즉, 구간의 시작 시간은 포함되지만, 끝 시간은 포함되지 않습니다.
구간 표기법으로는 [begin, end)
입니다.
이 모델은 구간이 반복·순차적으로 실행될 때 구간 간의 겹침이 없도록 합리적 동작을 제공합니다.
아래 예시에서 반복 효과의 경우, 로컬 시간 1초에 반복 시간은 0입니다. 순차 애니메이션의 경우, 타임라인 시간 1초에는 애니메이션 B의 연관 효과만 재생 중이 되며, 겹침이 없습니다.
이 동작의 예외는 채움을 수행할 때, 채움이 구간 끝점에서 시작된다면 그 끝점이 사용된다는 점입니다. 이 동작은 § 4.8.3.3 간단 반복 진행도 계산의 알고리듬에서 유도되며, 아래 그림에서 설명합니다.
4.8. 핵심 애니메이션 효과 계산
4.8.1. 개요
Web Animations 타이밍 모델의 핵심은 로컬 시간 값을 받아 반복 진행도로 변환하는 과정입니다.
이 과정의 첫 단계는 활성 구간의 경계를 계산하는데, 이는 활성 지속 시간에 의해 결정됩니다.
이 과정은 아래 그림에서 설명합니다.
활성 지속 시간 계산 과정은 § 4.8.2 활성 지속 시간 계산에 규범적으로 정의되어 있습니다.
활성 지속 시간이 결정되면, 애니메이션 효과의 로컬 시간을 변환 진행도(반복 진행도)로 변환하는 과정은 아래 그림에서 설명합니다.
(1) 로컬 시간은 연결된 애니메이션에서 결정됨.
(2) 로컬 시간은 활성 시간으로 변환되며, 시작 지연을 반영함.
(3) 활성 시간은 반복 지속 시간으로 나누고 반복 시작 속성도 반영하여 전체 진행도를 산출.
(4) 전체 진행도는 반복 내 오프셋인 간단 반복 진행도로 변환됨.
(5) 간단 반복 진행도는 방향 진행도로 변환되며, 재생 방향도 반영함.
(6) 마지막으로 타이밍 함수가 방향 진행도에 적용되어 변환 진행도가 산출됨.
첫 단계인 로컬 시간 계산은 § 4.5.4 로컬 시간에서 설명합니다. 다이어그램의 2~4단계는 다음 절에 설명되어 있습니다. 5, 6단계는 § 4.9.1 방향 진행도 계산 및 § 4.10.1 변환 진행도 계산에 설명되어 있습니다.
4.8.2. 활성 지속 시간 계산
활성 지속 시간은 아래와 같이 계산됩니다:
활성 지속 시간 =반복 지속 시간 × 반복 횟수
반복 지속 시간 또는 반복 횟수가 0이면 활성 지속 시간도 0입니다.
이 명확화는 IEEE 754-2008에 따라 무한대 × 0의 결과가 정의되지 않기 때문에 필요합니다.
4.8.3. 로컬 시간 변환
4.8.3.1. 활성 시간 계산
활성 시간은 로컬 시간과 시작 지연에 기반합니다. 하지만, 활성 시간은 애니메이션 효과가 실제로 출력을 생성해야 할 때만 정의되며, 아래와 같이 채움 모드와 페이즈에 따라 달라집니다,
- 애니메이션 효과가 before phase에 있을 때,
-
결과는 아래에서 첫 번째로 일치하는 조건에 따라 결정됩니다,
- 애니메이션 효과가 active phase에 있을 때,
- 애니메이션 효과가 after phase에 있을 때,
-
결과는 아래에서 첫 번째로 일치하는 조건에 따라 결정됩니다,
- 그 밖의 경우(로컬 시간이 미해결일 때),
4.8.3.2. 전체 진행도 계산
전체 진행도는 지금까지 완료된 반복 횟수(부분 반복 포함)를 나타내며, 아래와 같이 정의됩니다:
-
아래에서 첫 번째로 일치하는 조건에 따라 overall progress의 초기값을 계산합니다:
- 반복 지속 시간이 0인 경우,
-
애니메이션 효과가 before phase에 있으면 overall progress는 0, 그 외에는 반복 횟수와 같습니다.
- 그 밖의 경우,
-
overall progress + 반복 시작
결과를 반환합니다.
4.8.3.3. 간단 반복 진행도 계산
간단 반복 진행도는 현재 반복 내의 진행도를 나타내는 분수 값으로, 재생 방향이나 타이밍 함수 등 시간 변형을 무시하고 아래와 같이 계산합니다:
-
전체 진행도가 무한대면 simple iteration progress는
반복 시작 % 1.0
이고, 그 외에는 simple iteration progress는전체 진행도 % 1.0
입니다. -
아래 모든 조건이 참이면,
-
위에서 계산한 simple iteration progress가 0이고, 그리고
-
애니메이션 효과가 active phase 혹은 after phase에 있고, 그리고
-
반복 횟수가 0이 아님.
simple iteration progress를 1.0으로 합니다.
위 단계는 애니메이션의 활성 구간이 반복 끝점에 정확히 맞춰 끝나면, 다음 반복의 시작점이 아니라 마지막 반복의 끝점에서 채움이 유지되는 동작을 구현합니다.
마지막 조건은 반복 횟수가 처음부터 0이어서 반복이 전혀 실행되지 않은 경우에는 적용되지 않게 합니다.
-
-
simple iteration progress를 반환합니다.
4.8.4. 현재 반복 계산
현재 반복은 아래의 단계로 계산할 수 있습니다:
-
애니메이션 효과가 after phase에 있고 반복 횟수가 무한대라면, 무한대를 반환합니다.
-
그 밖의 경우,
floor(전체 진행도)
를 반환합니다.
4.9. 방향 제어
애니메이션 효과는 반복의 방향을 제어할 수도 있습니다. 이를 위해 애니메이션 효과는 재생 방향 파라미터를 가지며, 아래 값 중 하나를 가집니다:
-
normal,
-
reverse,
-
alternate,
-
alternate-reverse.
이 값들의 의미는 아래 방향 진행도 계산에 포함되어 있습니다.
이 값들의 비규범적 정의는 다음과 같습니다:
- normal
-
모든 반복은 지정된 대로 재생됩니다.
- reverse
-
모든 반복은 지정과 반대 방향으로 재생됩니다.
- alternate
-
짝수 반복은 지정된 방향대로, 홀수 반복은 반대 방향으로 재생됩니다.
- alternate-reverse
-
짝수 반복은 반대 방향으로, 홀수 반복은 지정된 대로 재생됩니다.
4.9.1. 방향 진행도 계산
방향 진행도는 간단 반복 진행도에서 아래 단계로 계산합니다:
-
아래에서 첫 번째로 일치하는 조건에 따라 current direction을 결정합니다:
-
current direction이 forwards이면 간단 반복 진행도를 반환합니다.
그 밖의 경우,
1.0 - 간단 반복 진행도
를 반환합니다.
4.10. 시간 변환
애니메이션 효과의 진행 속도를 제어하는 것이 바람직한 경우가 많습니다. 예를 들어, 애니메이션의 속도를 부드럽게(이징) 조절하면 모멘텀을 느끼게 하거나 보다 자연스러운 효과를 줄 수 있습니다. CSS 이징 함수 모듈 [CSS-EASING-1]에서는 이를 위한 타이밍 함수를 정의합니다.
애니메이션 효과는 하나의 타이밍 함수를 가집니다. 기본 타이밍 함수는 선형 타이밍 함수입니다.
4.10.1. 변환 진행도 계산
변환 진행도는 방향 진행도에서 다음 단계로 계산합니다:
-
before flag의 값을 아래와 같이 계산합니다:
-
§ 4.9.1 방향 진행도 계산에서 정의된 절차로 current direction을 결정합니다.
-
current direction이 forwards이면, going forwards를 true로, 아니면 false로 설정합니다.
-
애니메이션 효과가 before phase에 있고 going forwards가 true이면, 또는 애니메이션 효과가 after phase에 있고 going forwards가 false이면, before flag를 설정합니다.
-
-
애니메이션 효과의 타이밍 함수를, 방향 진행도를 input progress value로, before flag를 before flag로 넘겨 계산한 결과를 반환합니다.
4.11. 반복 진행도
5. 애니메이션 모델
일부 애니메이션 효과에 대해, Web Animations 애니메이션 모델은 타이밍 모델이 산출한 반복 진행도와 현재 반복 값을 받아 이에 상응하는 출력을 계산합니다.
이러한 애니메이션 효과 각각의 출력은 효과 스택에서 다른 효과의 출력과 합쳐진 다음, 대상 속성에 적용됩니다(§ 5.4 효과 결합 참고).
5.1. 소개
애니메이션 효과는 타이밍 출력 변화에 따라 영향을 받는 0개 이상의 속성을 가집니다. 이 속성들을 효과의 대상 속성이라고 합니다.
반복 진행도, 현재 반복, 기저 값이 주어지면, 애니메이션 효과는 각 애니메이션 가능한 대상 속성에 대해 해당 속성에 맞는 애니메이션 타입의 절차를 적용해 효과 값을 산출합니다.
5.2. 속성 애니메이션
별도 명시가 없는 한, 모든 CSS 속성은 애니메이션 가능입니다. 속성 값이 어떻게 결합되는지는 각 속성 정의 표의 애니메이션 타입 행에 정의되어 있습니다:
- 애니메이션 불가
-
해당 속성은 애니메이션 불가입니다.
애니메이션 키프레임에 명시되어도 처리되지 않으며,
트랜지션에도 영향을 받지 않습니다.
참고: 일부 속성은 애니메이션 처리 시 과도한 복잡성이 생기므로 애니메이션에서 제외됩니다. 예를 들어, 애니메이션 파라미터를 정의하는 속성은 애니메이션 불가인데, 이들을 애니메이션하면 복잡한 재귀 동작이 나타날 수 있습니다.
참고: 애니메이션 효과가 애니메이션 불가 속성만 대상으로 할 경우에도, 이벤트 발생, 애니메이션의 현재 finished promise의 이행 지연 등 통상적인 애니메이션 효과의 동작은 그대로 나타납니다.
- 이산(discrete)
-
해당 속성 값은 의미 있게 결합될 수 없으므로,
가산 불가능 및 보간이
Va에서 Vb로 50%(p=0.5)에서 전환됩니다.
즉,
- 계산값 기준(by computed value)
- 계산값의 개별 컴포넌트를 (보간, 덧셈, 누적 등) 해당 값 타입에 맞는 절차로 결합합니다 (CSS Values 4 § 3 값 결합: 보간, 덧셈, 누적 참고). 컴포넌트 수나 타입이 맞지 않거나, 어떤 컴포넌트 값이 이산(discrete) 애니메이션이고 두 값이 다르다면, 속성 값은 이산(discrete)으로 결합됩니다.
- 반복 가능한 리스트(repeatable list)
-
계산값 기준과 동일하지만, 두
리스트의 아이템 수가 다르면 먼저 최소공배수 길이까지 반복합니다.
각 아이템은 계산값 기준으로 결합합니다.
결합 불가한 쌍이나 어떤 컴포넌트 값이 이산(discrete)
애니메이션이면,
속성 값은 이산(discrete)으로 결합합니다.
참고: 반복 가능한 리스트 개념은, 리스트가 특정 길이까지 개념적으로 반복될 때(background-origin이 background-image 리스트 길이에 맞게 반복됨) 또는 무한 반복될 때, 어떤 값 사이든 부드럽게 전환되고, 계산값이 결과를 올바르게 표현하며(상속도 가능), 리스트가 올바른 길이로 처리될 수 있도록 합니다.
- (See prose)
- 일부 속성은 위의 경우에 해당하지 않는 특정 보간 동작을 가지며, 이 경우 해당 속성에 대해 애니메이션 동작이 별도로 명시됩니다.
아직 애니메이션 타입 행이 속성 정의에 포함되지 않은 속성의 애니메이션 타입은 부록 A: 기존 속성의 애니메이션 타입에서 정의됩니다.
5.2.1. 사용자 정의 속성
사용자 정의 속성이
registerProperty()
메서드를 통해 현재 글로벌 오브젝트에 등록된 경우,
해당 애니메이션 타입은 계산값 기준이며,
속성의 문법 정의에 사용된 타입에서 유도됩니다.
속성의 지정 문법에 해당하는 계산값 타입이 없거나
(예: 문법이 범용 문법 정의일 때)
혹은 사용자 정의 속성이 등록되지 않은 경우에는,
애니메이션 타입이 이산(discrete)입니다.
5.3. 키프레임 효과
키프레임 효과는 애니메이션 효과의 한 종류로,
타이밍 모델의 출력을 이용해 요소 또는 의사 요소(예: ::before
나 ::after
[select])의 CSS 속성을 갱신합니다.
이를 효과 타겟이라고 합니다.
효과
타겟은
Element
타입의 타겟 요소와, 의사 요소 선택자인
타겟 의사 선택자로 구성됩니다.
효과 타겟이 Element
이면,
타겟
요소는 해당 요소이고,
타겟 의사 선택자는 null
입니다.
효과 타겟이 의사
요소이면,
타겟 요소는 그 기원
요소이고, 타겟 의사 선택자는 해당 의사 요소를 지정하는
선택자입니다.
이 방법으로 지정된 모든 효과 타겟(예: ::part() 의사 요소나 미지원 의사 요소 등)이 반드시 계산된 속성 값을 갖는 것은 아닙니다.
5.3.1. 키프레임
키프레임 효과의 효과 값은, 분수 오프셋에 위치한 여러 속성 값 사이를 보간(interpolate)하여 계산됩니다. 오프셋별로 인덱싱된 각 속성 값 집합을 키프레임이라고 합니다.
키프레임 오프셋은 [0, 1] 범위의 값 또는 특별한 값 null입니다. 키프레임 목록은 키프레임 효과에 대해 오프셋 기준 느슨한 정렬이어야 하며, 이는 목록의 각 키프레임이 null이 아닌 키프레임 오프셋을 갖는 경우, 해당 오프셋 값이 목록에서 바로 이전의 null이 아닌 키프레임의 키프레임 오프셋 이상이어야 한다는 뜻입니다.
키프레임이 겹치거나 값이 미지원일 때의 동작은 § 5.3.4 키프레임 효과의 효과 값에서 정의됩니다.
각 키프레임에는 타이밍 함수가 연결되어 있으며, 해당 함수는 지정된 키프레임과 다음 키프레임 사이 구간에 적용됩니다. 목록의 마지막 키프레임에 지정된 타이밍 함수는 적용되지 않습니다.
각 키프레임에는 키프레임별 합성 연산(composite operation)이 있을 수 있으며, 지정된 경우 해당 키프레임의 모든 값에 적용됩니다. 가능한 연산과 의미는 § 5.4.4 효과 합성에서 전체 키프레임 효과에 지정된 합성 연산과 동일합니다. 키프레임별 합성 연산이 지정되지 않은 키프레임의 값에는 해당 키프레임 효과 전체에 대해 지정된 합성 연산이 사용됩니다.
5.3.2. 속성 값 계산
Element
element가 주어졌을 때,
property의 정의표에서 "Computed Value" 행을 따라 value를 resolve하고,
계산값 컨텍스트로 element의 계산값을 사용한 후,
그 결과를 반환합니다.
참고: 계산값은 해당 알고리즘에 의해 element에서 변경되지 않습니다.
이 알고리즘은, 키프레임에 지정된 속성 값이 순서 종속성을 만들 수 있음을 의미합니다. 속성 값 계산 시, value가 의존하는 값의 계산값은 먼저 계산되어야 합니다.
var animation= elem. animate([{ fontSize: '10px' , width: '10em' }, { fontSize: '20px' , width: '20em' }], 1000 ); animation. currentTime= 500 ; console. log( getComputedStyle( elem). fontSize); // 15px이어야 함 console. log( getComputedStyle( elem). width); // 225px이어야 함
이 예시에서 10em
의 속성 값을 계산하려면, font-size의 계산값을
타겟 요소에서 알아야 하며,
이는 다시 효과 값으로 결정되고,
font-size의 속성 값을 계산해야 합니다.
따라서 속성 값 계산에는 순서 제약이 따릅니다.
5.3.3. 계산된 키프레임 계산
키프레임 효과의 효과 값을 계산하기 전에, 그 키프레임의 속성 값을 계산하고, null 키프레임 오프셋에 사용할 오프셋도 계산합니다. 이 값들의 결과가 계산된 키프레임입니다.
null이 아닌 값을 포함한 키프레임 집합의 키프레임 오프셋을 계산한 결과를 계산된 키프레임 오프셋이라고 합니다.
계산된 키프레임 오프셋을 산출하기 위해, 키프레임 시퀀스 keyframes에 대해 키프레임 오프셋 누락 계산 절차를 정의하며, 다음 단계로 진행합니다:
-
keyframes의 각 키프레임에 대해, 키프레임의 계산된 키프레임 오프셋을 해당 키프레임 오프셋 값으로 설정합니다.
-
keyframes에 키프레임이 2개 이상 있고, 첫 번째 키프레임의 계산된 키프레임 오프셋이 null이면, 첫 번째 계산된 키프레임 오프셋을 0으로 설정합니다.
-
마지막 키프레임의 계산된 키프레임 오프셋이 null이면, 해당 계산된 키프레임 오프셋을 1로 설정합니다.
-
아래 조건을 모두 만족하는 키프레임 A, B 쌍에 대하여:
-
A가 B보다 keyframes 내에서 먼저 나오며,
-
A, B 모두 계산된 키프레임 오프셋이 null이 아니며,
-
A와 B 사이의 모든 키프레임이 null 계산된 키프레임 오프셋을 갖는 경우,
A와 B 사이에 있는 각 키프레임의 계산된 키프레임 오프셋은 아래와 같이 계산합니다:
-
offsetk을 계산된 키프레임 오프셋으로 합니다.
-
n을 A, B 포함해 사이에 있는 키프레임 수에서 1을 뺀 값으로 합니다.
-
index를 A와 B 사이 키프레임 중에서, A 바로 다음 키프레임이 1인 위치로 합니다.
-
keyframe의 계산된 키프레임 오프셋을 offsetA + (offsetB − offsetA) × index / n으로 설정합니다.
-
계산된 키프레임은 다음 절차로 산출합니다. 이 절차는 반드시 계산된 속성 값을 산출할 수 있는 키프레임 효과에 대해 수행합니다.
-
computed keyframes를 빈 키프레임 리스트로 초기화합니다.
-
해당 키프레임 효과에 지정된 키프레임 리스트의 각 keyframe에 대해, 아래 단계를 수행합니다:
-
새 빈 키프레임 computed keyframe을 computed keyframes에 추가합니다.
-
keyframe에 지정된 각 속성에 대해:
-
속성 값 계산 알고리즘으로, keyframe에 지정된 값을 value로, 타겟 요소를 element로 사용해 계산하고, 그 속성과 결과값을 computed keyframe에 추가합니다.
-
축약(shorthand) 속성은 동등한 긴(longhand) 속성으로 추가합니다.
-
논리(logical) 속성 [CSS-LOGICAL-1]은 동등한 물리(physical) 속성 [CSS-WRITING-MODES-4]으로 추가하며, writing-mode 및 direction의 계산값을 효과 타겟에 대해 사용합니다.
예를 들어, keyframe이 border-width에 "12pt" 값을 지정하면, 사용자 에이전트는 각 longhand 속성에 대해 "16px"로 속성 값 계산을 할 수 있습니다: border-bottom-width, border-left-width, border-right-width, border-top-width 등. 결과적으로 computed keyframe에는 border-width 속성 값은 없고, 각 longhand 속성에 "16px" 값이 포함됩니다.
축약 속성 확장이나 논리 속성의 물리 속성 대체 과정에서 충돌이 발생하면, 아래 규칙을 순서대로 적용해 해결합니다:
-
longhand 속성이 shorthand 속성보다 우선합니다(예: border-top-color가 border-top보다 우선).
-
longhand 구성 요소가 더 적은 shorthand 속성이 더 많은 shorthand 구성 요소를 포함한 속성보다 우선합니다(예: border-top이 border-color보다 우선).
-
물리 속성이 논리 속성보다 우선합니다.
-
동일한 longhand 구성 수를 가지는 shorthand 속성의 경우, 각 속성의 IDL 이름(CSS property to IDL attribute 알고리즘 [CSSOM] 참고)이 유니코드 코드포인트 오름차순 정렬에서 더 앞서는 속성이 뒤에 오는 속성보다 우선합니다.
-
-
-
키프레임 오프셋 누락 계산 절차를 computed keyframes에 적용합니다.
-
computed keyframes를 반환합니다.
5.3.4. 키프레임 효과의 효과 값
키프레임 효과가 참조하는 단일 속성의 효과 값은 그 대상 속성 중 하나로, 주어진 iteration progress, current iteration, underlying value에 대해 아래와 같이 계산됩니다.
-
iteration progress가 미해결이면 이 절차를 중단합니다.
-
target property를 효과 값을 계산할 longhand 속성으로 설정합니다.
-
target property의 애니메이션 타입이 애니메이션 불가이면 효과를 적용할 수 없으므로 이 절차를 중단합니다.
-
키프레임 효과에 효과 타겟이 없거나, 효과 타겟에서 계산된 속성 값을 산출할 수 없으면 이 절차를 중단합니다.
-
합성 중립값을, add 합성 연산으로 기저 값과 결합할 때 기저 값이 그대로 나오게 하는 값으로 정의합니다.
-
property-specific keyframes를 이 키프레임 효과의 계산된 키프레임 집합으로 설정합니다.
-
property-specific keyframes에서 target property 값이 없는 키프레임을 모두 제거합니다.
-
property-specific keyframes가 비어 있으면 underlying value를 반환합니다.
-
만약 property-specific keyframes 내에 계산된 키프레임 오프셋이 0인 키프레임이 없다면, 키프레임을 새로 만들어, 계산된 키프레임 오프셋을 0으로, 속성 값을 합성 중립값으로, 합성 연산을 add로 지정하여 property-specific keyframes 맨 앞에 추가합니다.
-
마찬가지로, property-specific keyframes 내에 계산된 키프레임 오프셋이 1인 키프레임이 없다면, 키프레임을 새로 만들어, 계산된 키프레임 오프셋을 1로, 속성 값을 합성 중립값으로, 합성 연산을 add로 지정하여 property-specific keyframes 맨 끝에 추가합니다.
-
interval endpoints를 빈 키프레임 시퀀스로 초기화합니다.
-
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에 추가합니다.
- 그 밖의 경우,
-
-
property-specific keyframes에서 계산된 키프레임 오프셋이 iteration progress 이하이고 1 미만인 마지막 키프레임을 interval endpoints에 추가합니다. 없으면(예: iteration progress가 음수인 경우) 키프레임 중 계산된 키프레임 오프셋이 0인 마지막 키프레임을 추가합니다.
-
이전 단계에서 추가한 키프레임 바로 다음 키프레임을 interval endpoints에 추가합니다.
-
-
interval endpoints의 각 keyframe에 대해:
-
interval endpoints에 키프레임이 하나만 있으면, 그 키프레임의 target property 속성 값을 반환합니다.
-
start offset을 interval endpoints의 첫 번째 키프레임의 계산된 키프레임 오프셋으로 설정합니다.
-
end offset을 interval endpoints의 마지막 키프레임의 계산된 키프레임 오프셋으로 설정합니다.
-
interval distance를
(iteration progress - start offset) / (end offset - start offset)
로 계산합니다. -
transformed distance를 interval endpoints의 첫 번째 키프레임에 연결된 타이밍 함수에 interval distance를 입력값으로 넘겨 계산한 결과로 설정합니다.
-
interval endpoints의 두 키프레임에 지정된 target property 값을 애니메이션 타입의 보간(interpolation) 절차에 따라, 첫 번째 값을 Vstart, 두 번째 값을 Vend로 사용하고, transformed distance를 보간 파라미터 p로 사용해서 결과를 반환합니다.
이 절차는 효과에 지정된 키프레임 목록에 대해 아래와 같은 조건을 가정합니다:
-
각 키프레임은 [0, 1] 범위의 계산된 키프레임 오프셋을 갖습니다.
-
키프레임 목록은 계산된 키프레임 오프셋 기준 오름차순으로 정렬되어 있습니다.
-
특정 속성에 대해, 각 키프레임에 지정된 속성 값은 최대 하나입니다.
모델 사용자(예: 선언적 마크업 또는 프로그래밍 인터페이스)가 이 조건을 충족시켜야 합니다.
예를 들어, 본 명세에서 정의된 프로그래밍 인터페이스에선, 이 조건은 계산된 키프레임을 산출하는 절차에서 충족되어, 본 절차의 입력이 됩니다.
참고: 이 절차는 키프레임이 겹치는(overlap) 경우도 허용합니다. 겹치는 오프셋에서 출력 값은 해당 오프셋에 마지막으로 정의된 키프레임 값으로 점프합니다. 0 또는 1에서 겹치는 키프레임의 경우, iteration progress 값이 0 미만 또는 1 이상일 때 출력 값은 키프레임 목록의 첫 번째 또는 마지막 값이 됩니다.
예를 들어 font-size 속성에 대해 10px
에서 20px
로 트랜지션 중일
때,
키프레임에 1em
값이 지정되면, 키프레임 계산 과정에서 계산값은
font-size의 트랜지션으로 생성된 [10px
,
20px
] 범위 내에서 resolve됩니다.
이 제한을 제거하는 방안도 고려 중인데, 범위 밖의 iteration progress에서 속성 값이 비선형적으로 변하는 경우가 실무적으로 존재하기 때문입니다. 예를 들어, 애니메이션이 초록에서 노랑으로 보간하지만 오버슈트 타이밍 함수 덕분에 잠시 노랑을 넘어 빨간색으로 이동한 뒤 다시 노랑으로 복귀하는 경우가 있습니다.
이 효과는 키프레임과 타이밍 함수를 조정해 만들 수도 있지만, 이 방식은 모델의 타이밍과 애니메이션 효과 분리를 깨뜨리는 것으로 보입니다.
이 효과를 어떻게 구현할지는 아직 불명확하지만, 키프레임 오프셋을 [0, 1] 밖으로 허용하면 0과 1에서 키프레임을 합성하는 기존 동작과 일관성이 깨질 수 있습니다.
5.4. 효과 결합
키프레임 효과의 효과 값을 계산한 뒤, 해당 값들은 애니메이션 효과의 대상 속성에 적용됩니다.
여러 효과 중 키프레임 효과가 동일 속성을 타겟팅할 수 있으므로, 여러 키프레임 효과의 결과를 결합해야 할 필요가 있습니다. 이 과정을 합성(compositing)이라고 하며, 각 속성별로 효과 스택을 구축해 진행합니다(효과 중 애니메이션 효과 기준).
여러 키프레임 효과의 결과를 합성한 뒤, 그 합성 결과는 해당 대상 속성에 지정된 다른 값들과 결합됩니다.
아래 그림은 전체 구조를 설명합니다:
동일 속성을 타겟팅하는 키프레임 효과의 결과는 효과 스택을 사용해 합성됩니다.
이 합성 결과는 적절한 위치에서 CSS 계단식에 삽입되어 적용됩니다.
이 과정의 첫 단계(동일 속성에 대해 효과 값을 결합하는 과정)에서는, 여러 키프레임 효과를 어떻게 결합할지(how), 그리고 적용 순서(order, 즉 상대 합성 순서(composite order))를 정해야 합니다.
5.4.1. 애니메이션 클래스
이 명세는, 본 모델 위에 마크업이나 프로그래밍 인터페이스를 정의하는 다른 명세에서 사용할 수 있도록 공통 애니메이션 모델을 제공합니다. 특정 마크업/프로그래밍 인터페이스가 생성한 애니메이션은 그 애니메이션 클래스를 정의합니다.
후속 명세에서는 서로 다른 애니메이션 클래스 간 또는 클래스 내부에서 합성 순서에 대한 특수 동작을 정의할 수 있습니다.
예를 들어, 클래스가 "CSS animation"인 애니메이션은 "CSS transition" 클래스보다 높은 합성 순서, 기타 클래스 없는 애니메이션보다 낮은 합성 순서를 갖도록 정의됩니다.
"CSS animation" 객체 집합 내에서는, animation-name 속성 등 여러 요소에 따라 특수 합성 순서가 정의됩니다.
5.4.2. 효과 스택
효과 스택은, 하나 이상의 키프레임 효과가 타겟팅하는 각 속성마다 연결됩니다. 효과 스택은 키프레임 효과들 간의 상대 합성 순서를 결정합니다.
효과 스택 내 두 키프레임 효과 A, B의 상대 합성 순서는 아래 속성 비교로 결정됩니다:
-
A와 B를 아래 조건을 순서대로 적용해 비교해 결정합니다:
-
A, B의 연결된 애니메이션이 클래스가 다르면, 각 클래스에 정의된 inter-class 합성 순서로 결정합니다.
-
아직 비교가 끝나지 않았으면, 두 A, B의 공통 클래스에 정의된 class-specific 합성 순서로 비교합니다.
-
아직도 결정이 안 되면, 전역 애니메이션 리스트에서 A, B의 연결된 애니메이션 위치로 비교합니다.
-
애니메이션 효과가 먼저 정렬되면 더 낮은 합성 순서를 갖습니다.
5.4.3. 효과 스택 결과 계산
효과 스택의 최종 값을 계산하려면, 스택에 포함된 각 키프레임 효과의 효과 값을 합성 순서대로 결합합니다.
효과 스택 평가 과정의 각 단계는 입력값으로 기저 값을 받습니다.
스택의 각 키프레임 효과에 대해, 해당 키프레임 효과의 적절한 효과 값을 기저 값과 결합하여 새 값을 생성합니다. 이렇게 생성된 값은 다음 키프레임 효과와 결합할 때의 새로운 기저 값이 됩니다.
스택의 최종 효과 스택 값은 합성 값이라 하며, 스택에서 마지막(합성 순서가 가장 높은) 키프레임 효과의 효과 값과 해당 시점의 기저 값을 결합한 결과입니다.
5.4.4. 효과 합성
효과 값을 기저 값과 결합할 때 사용하는 구체적인 연산은 키프레임 효과의 합성 연산(composite operation)에 따라 결정됩니다.
이 명세에서는 아래 세 가지 합성 연산을 정의합니다:
- replace
- add
-
효과 값을 덧셈(addition) 연산으로 기저 값에 더합니다. 애니메이션 타입에 따라 덧셈 연산이 교환법칙이 성립하지 않는 경우, 피연산자 순서는
기저 값 + 효과 값
입니다. - accumulate
-
효과 값을 누적(accumulation) 연산으로 기저 값에 누적합니다. 애니메이션 타입에 따라 누적 연산이 교환법칙이 성립하지 않는 경우, 피연산자 순서는 기저 값 다음에 효과 값입니다.
5.4.5. 합성 결과 적용
합성 값을 대상 속성에 적용하려면, 지정값을 CSS 계단식에 추가하면 됩니다.
지정값이 CSS 계단식의 어느 단계에 추가되는지는, 효과 스택 내에서 가장 높은 합성 순서를 갖는 효과가 연결된 클래스에 따라 결정됩니다. 기본적으로 지정값은 CSS 계단식의 "Animation declarations" 단계에 추가됩니다([css-cascade-3]).
예를 들어, 가장 높은 합성 순서의 효과가 "CSS transition" 클래스 애니메이션에 연결된 경우, 합성 값은 "Transition declarations" 단계에 추가됩니다.
CSS 대상 속성에 계산된 합성 값은 아래 절차로 적용됩니다.
-
해당 속성에 대해 애니메이션이 없을 때 계산값을 구해, 그 값을 base value로 설정합니다.
-
해당 속성의 효과 스택을 구축합니다(§ 5.4.2 효과 스택 참고).
-
base value를 초기 기저 값으로 하여, 효과 스택의 합성 값을 계산합니다(§ 5.4.3 효과 스택 결과 계산 참고).
-
효과 스택의 맨 위에 있는 효과가 연결된 애니메이션의 클래스에 정의된 단계에, 합성 값을 CSS 계단식에 삽입합니다.
5.5. 애니메이션 대체
이 명세에서 정의된 프로그래밍 인터페이스를 사용하면, 요소의 애니메이션 스타일에 기여하는 새 애니메이션을 무한 반복적으로 트리거할 수 있습니다.
예를 들어, 아래 코드를 보세요:
elem. addEventListener( 'mousemove' , evt=> { circle. animate( { transform: `translate( ${ evt. clientX} px, ${ evt. clientY} px)` }, { duration: 500 , fill: 'forwards' } ); });
이 코드는 마우스가 움직일 때마다 새로운 forwards-fill 애니메이션을 생성하며, 빠르게 수백, 수천 개의 forwards-fill 애니메이션이 쌓입니다.
만약 사용자 에이전트가 모든 이런 애니메이션을 유지해야 한다면, 애니메이션 리스트가 끝없이 커져 결국 메모리 누수가 발생할 수 있습니다.
이 섹션에서는 오버라이드된 애니메이션이 명시적으로 보존되지 않는 한 자동으로 제거되는 메커니즘을 정의합니다.
5.5.1. 대체 상태
애니메이션은 아래 값 중 하나를 가질 수 있는 대체 상태(replace state)를 유지합니다:
-
active
-
removed
-
persisted
애니메이션의 대체 상태의 초기 값은 active입니다.
replace state가 removed인 애니메이션의 애니메이션 효과는 그 대상 속성의 효과 스택에 포함되지 않습니다.
5.5.2. 대체된 애니메이션 제거
애니메이션은 아래 모든 조건을 만족하면 대체 가능(replaceable)입니다:
-
애니메이션의 존재가 마크업에 의해 규정되지 않습니다. 즉, CSS 애니메이션(소유 요소가 있음)이나 CSS 트랜지션(소유 요소가 있음)이 아닙니다.
Document
doc에 대해 대체된 애니메이션 제거를 요청받으면,
아래 조건을 모두 만족하는 각 애니메이션 animation에 대해 다음을 수행합니다:
-
연결된 애니메이션 효과의 효과 타겟이 doc의 자손(descendant)인 경우,
-
대체 가능이고,
-
replace state가 active이고,
-
각 대상 속성에 대해, animation에 연결된 모든 애니메이션 효과에 대해, 해당 대상 속성을 포함하는, 더 높은 합성 순서의 대체 가능 애니메이션에 연결된 애니메이션 효과가 존재하는 경우
다음 단계를 수행합니다:
-
animation의 replace state를 removed로 설정합니다.
-
Create an
AnimationPlaybackEvent
, removeEvent. -
removeEvent의
currentTime
속성을 animation의 현재 시간으로 설정합니다. -
removeEvent의
timelineTime
속성을 animation이 연결된 타임라인 현재 시간으로 설정합니다. -
animation에 document for timing이 있으면, removeEvent를 그 document for timing의 대기 중 애니메이션 이벤트 큐에, 타겟 animation과 함께 추가합니다. 예정 이벤트 시간은 타임라인 시간을 원점 기준 시간으로 변환 절차를 animation이 연결된 타임라인 현재 시간에 적용한 결과로 사용합니다.
그 밖의 경우, 태스크(queue a task)를 디스패치(dispatch)하는데, removeEvent를 animation에 디스패치합니다. 이 태스크의 소스는 DOM 조작 태스크 소스입니다.
5.6. 애니메이션의 부수 효과
최소 하나의 애니메이션 효과에 의해 타겟팅되고, current 또는 효과 중인 모든 속성에 대해, 그리고 그 효과가 애니메이션에 연결되어 있고, 해당 애니메이션의 replace state가 removed가 아닌 경우, 사용자 에이전트는 will-change 속성이 effect target에 해당 속성을 포함하는 것처럼 동작해야 합니다.
위 요구사항의 결과로, 예를 들어 애니메이션이 요소의 transform 속성을 타겟팅하면, 스태킹 컨텍스트가 effect target에 대해 생성됩니다. 단, 애니메이션이 before phase 또는 active phase에 있거나, "forwards" 혹은 "both" fill mode이고 after phase에 있는 경우에만 해당합니다.
6. 프로그래밍 인터페이스
위에서 설명한 추상 모델 외에도, Web Animations는 모델에 대한 프로그래밍 인터페이스도 정의합니다. 이 인터페이스는 선언적 방식으로 생성된 애니메이션을 검사 및 확장하거나, 절차적 접근이 더 적합한 경우 직접 애니메이션을 생성하는 데 사용할 수 있습니다.
6.1. 프로그래밍 인터페이스의 시간 값
시간 값은 프로그래밍 인터페이스에서
double
타입으로 표현됩니다. 미해결 시간 값은 null
로 표현됩니다.
6.2.
AnimationTimeline
인터페이스
타임라인은 Web Animations API에서 AnimationTimeline
인터페이스로 표현됩니다.
[Exposed =Window ]interface {
AnimationTimeline readonly attribute double ?currentTime ; };
6.3.
DocumentTimeline
인터페이스
문서 타임라인 및 기본 문서 타임라인은 Web Animations API에서 DocumentTimeline
인터페이스로 표현됩니다.
dictionary {
DocumentTimelineOptions DOMHighResTimeStamp originTime = 0; }; [Exposed =Window ]interface :
DocumentTimeline AnimationTimeline {constructor (optional DocumentTimelineOptions options = {}); };
originTime
, 타입 DOMHighResTimeStamp, 기본값0
-
타임라인의 origin time을 밀리초 단위 실수로 지정하며, 시간 원점 기준 상대값입니다.
DocumentTimeline (options)
-
새
DocumentTimeline
를 생성합니다. 타임라인이 연결되는Document
는Document
와 연결된Window
의 현재 글로벌 오브젝트가 됩니다.options
-
새로 생성된 타임라인의 설정 파라미터. 이 명세에서는
originTime
만 정의하지만, 다른 명세에서 더 많은 파라미터를 확장할 수 있습니다.
6.4. Animation
인터페이스
애니메이션은
Web Animations API에서 Animation
인터페이스로 표현됩니다.
[Exposed =Window ]interface :
Animation EventTarget {constructor (optional AnimationEffect ?effect =null ,optional AnimationTimeline ?timeline );attribute DOMString id ;attribute AnimationEffect ?effect ;attribute AnimationTimeline ?timeline ;attribute double ?startTime ;attribute double ?currentTime ;attribute double playbackRate ;readonly attribute AnimationPlayState playState ;readonly attribute AnimationReplaceState replaceState ;readonly attribute boolean pending ;readonly attribute Promise <Animation >ready ;readonly attribute Promise <Animation >finished ;attribute EventHandler onfinish ;attribute EventHandler oncancel ;attribute EventHandler onremove ;undefined cancel ();undefined finish ();undefined play ();undefined pause ();undefined updatePlaybackRate (double playbackRate );undefined reverse ();undefined persist (); [CEReactions ]undefined commitStyles (); };
Animation (effect, timeline)
-
아래 절차에 따라 새로운
Animation
객체를 생성합니다.-
animation을 새로운
Animation
객체로 생성합니다. -
animation에 대해 timeline을 new timeline으로 넘기거나, timeline 인자가 없으면
기본 문서 타임라인
을Document
와 연결된Window
의 현재 글로벌 오브젝트로 넘겨 애니메이션의 타임라인 설정 절차를 실행합니다. -
animation에 대해 source를 new effect로 넘겨 애니메이션의 연관 효과 설정 절차를 실행합니다.
effect
timeline
-
존재하면, 새로 생성된 애니메이션과 연결할 타임라인을 지정합니다. 없으면,
기본 문서 타임라인
이Document
와 연결된Window
의 현재 글로벌 오브젝트로 사용됩니다.
-
id
, 타입 DOMString-
애니메이션을 식별하는 문자열입니다.
effect
, 타입 AnimationEffect, nullable-
이 애니메이션의 연관 효과입니다. 해당 속성을 설정하면 연관 효과가 애니메이션의 연관 효과 설정 절차에 따라 갱신됩니다.
timeline
, 타입 AnimationTimeline, nullable-
이 애니메이션에 연결된 타임라인입니다. 해당 속성을 설정하면 애니메이션의 타임라인이 애니메이션 타임라인 설정 절차에 따라 갱신됩니다.
startTime
, 타입 double, nullable-
이 애니메이션의 시작 시간을 반환합니다. 해당 속성을 설정하면 새로운 값으로 시작 시간이 시작 시간 설정 절차에 따라 갱신됩니다.
currentTime
, 타입 double, nullable-
이 애니메이션의 현재 시간입니다. 해당 속성을 설정하면 새로운 값으로 애니메이션 현재 시간 설정 절차를 수행합니다.
playbackRate
, 타입 double-
이 애니메이션의 재생 속도입니다. 해당 속성을 설정하면 새로운 값으로 재생 속도 설정 절차를 수행합니다.
이 속성을 설정하면 재생 속도가 동기적으로 갱신되며, 별도의 프로세스나 스레드에서 실행 중인 애니메이션과 재생 상태를 동기화하지 않습니다. 결과적으로, 비행 중인(실행 중인) 애니메이션의
playbackRate
를 설정하면 애니메이션이 점프할 수 있습니다.비행 중인 애니메이션의 재생 속도를 부드럽게 갱신하려면, 비동기
updatePlaybackRate()
메서드를 사용하세요. playState
, 타입 AnimationPlayState, 읽기 전용-
이 애니메이션의 재생 상태입니다.
replaceState
, 타입 AnimationReplaceState, 읽기 전용-
이 애니메이션의 대체 상태입니다.
pending
, 타입 boolean, 읽기 전용-
이 애니메이션에 대기 중 재생 태스크나 대기 중 일시정지 태스크가 있으면 true를 반환합니다.
ready
, 타입 Promise<Animation>, 읽기 전용-
이 객체의 현재 ready promise를 반환합니다.
finished
, 타입 Promise<Animation>, 읽기 전용-
이 객체의 현재 finished promise를 반환합니다.
onfinish
, 타입 EventHandler-
finish 이벤트의 이벤트 핸들러입니다.
oncancel
, 타입 EventHandler-
cancel 이벤트의 이벤트 핸들러입니다.
onremove
, 타입 EventHandler-
remove 이벤트의 이벤트 핸들러입니다.
void cancel()
-
이 애니메이션으로 인한 모든 효과를 모두 제거하고 재생을 중단합니다. 이 객체에 대해 애니메이션 취소 절차를 실행합니다.
void finish()
-
현재 방향에서 애니메이션을 연관 효과 끝까지 진행합니다. 이 객체에 대해 애니메이션 완료 절차를 실행합니다.
- DOMException of type
InvalidStateError
- DOMException of type
void play()
-
애니메이션 재생 또는 다시 재생을 시작합니다. play an animation 절차를 auto-rewind 플래그에 true를 넘겨 실행합니다.
void pause()
-
이 애니메이션의 재생을 일시정지합니다. 이 객체에 대해 애니메이션 일시정지 절차를 실행합니다.
void updatePlaybackRate(playbackRate)
-
이 애니메이션의 재생 속도를 비동기적으로 갱신합니다. 재생 속도 원활 갱신 절차를 실행하며,
playbackRate
를 new playback rate로 넘깁니다.playbackRate
-
갱신할 재생 속도를 지정하는 유한 실수입니다.
void reverse()
-
이 애니메이션의 재생 속도를 반전시키고 애니메이션 반전 절차로 재생합니다. play()와 마찬가지로, 이 메서드는 애니메이션을 일시정지 해제하며, 이미 역방향으로 완료된 애니메이션은 연관 효과의 시작으로 이동합니다.
void persist()
void commitStyles()
-
이 애니메이션의 애니메이션 효과가 생성한 효과 값을 해당 효과 타겟의 인라인 스타일에 계산된 스타일 커밋 절차로 기록합니다.
이 인터페이스의 대부분 다른 메서드와 달리, 이 메서드는 스타일 변경 이벤트(§ 6.13 모델 생명력 참고)를 트리거합니다.
계산된 스타일 커밋 절차에는 효과 값도 포함되므로, 애니메이션이 removed 상태여도 이 메서드는 애니메이션의 효과를 유지하는 데 유용합니다(§ 5.5.2 대체된 애니메이션 제거 참고). 단, 실제 애니메이션을 유지하지 않아도 됩니다.
커밋되는 값은 계산된 값이며, 애니메이션 효과가 메서드 호출 시점에 생성한 값입니다. 계산값이므로, CSS 변수 변화나 em 단위의 font-size 변화 등 컨텍스트 변화에 따라는 실시간으로 반영되지 않습니다.
채움 애니메이션의 결과를 완전히 유지하려면(§ 5.5 애니메이션 대체 참고),
persist()
메서드를 사용할 수 있습니다. 단, 이렇게 하면 애니메이션이 계속 리소스를 소비합니다.
계산된 스타일 커밋을 애니메이션 animation에 대해 수행하려면:
-
각 target에 대해:
-
target이 style 속성을 가질 수 있는 요소가 아니면([CSS-STYLE-ATTR], 예를 들어 pseudo-element나 style 속성이 정의되지 않은 문서 포맷의 요소 등) throw "
NoModificationAllowedError
"DOMException
하고, 절차를 중단합니다. -
대기 중인 스타일 변경 적용 후, target이 렌더링 중이 아니면 throw "
InvalidStateError
"DOMException
하고, 절차를 중단합니다.렌더링 중의 정의는 display: contents와 관련해 논의 중입니다. 본 절차에서는, display: contents 상태이고 레이아웃 박스를 가질 수 있는 요소(즉, connected이고 display: none 서브트리에 포함되지 않은 경우) 렌더링 중으로 간주합니다.
-
inline style을 target의 CSS 선언 블록에서 가져옵니다. target이 style 속성을 가지고 있지 않으면, inline style을 새로운 빈 CSS 선언 블록으로 하고, owner node를 target으로 설정합니다.
-
targeted properties를, target에 대해 애니메이션 효과가 animation과 연결되어 있고 해당 효과 타겟이 target인 경우에, 물리적 longhand 대상 속성의 집합으로 설정합니다.
-
각 targeted properties의 property에 대해:
-
partialEffectStack을 target의 효과 스택의 복사본으로 설정합니다.
-
animation의 대체 상태가 removed이면, animation과 연결되고 target을 효과 타겟으로 가지며 property를 대상 속성으로 포함하는 모든 애니메이션 효과를 partialEffectStack에 추가합니다.
-
partialEffectStack에서 animation보다 합성 순서가 더 높은 애니메이션에 연결된 애니메이션 효과를 모두 제거합니다.
-
effect value를 property와 target의 계산된 스타일을 이용해 partialEffectStack의 결과로 계산합니다(§ 5.4.3 효과 스택 결과 계산 참고).
-
CSS 선언 설정으로 inline style에 property와 effect value를 기록합니다.
-
-
inline style의 style 속성 갱신을 수행합니다.
-
6.4.1. AnimationPlayState
열거형
enum {
AnimationPlayState ,
"idle" ,
"running" ,
"paused" };
"finished"
idle
-
idle play state에 해당합니다.
running
-
running play state에 해당합니다.
paused
-
paused play state에 해당합니다.
finished
-
finished play state에 해당합니다.
6.4.2. AnimationReplaceState
열거형
enum {
AnimationReplaceState ,
"active" ,
"removed" };
"persisted"
active
-
active replace state에 해당합니다.
removed
-
removed replace state에 해당합니다.
persisted
-
persisted replace state에 해당합니다.
6.5.
AnimationEffect
인터페이스
애니메이션 효과는
Web Animations API에서 추상 AnimationEffect
인터페이스로 표현됩니다.
[Exposed =Window ]interface {
AnimationEffect EffectTiming getTiming ();ComputedEffectTiming getComputedTiming ();undefined updateTiming (optional OptionalEffectTiming timing = {}); };
any onupdate (double? progress,
double currentIteration, Animatable? target, any
underlyingValue)
를 노출하여 애니메이션 효과를 타이밍 모델과 분리해 동작할 수 있도록 할 수도 있습니다. getTiming()
-
이 애니메이션 효과의 지정된 타이밍 속성들을 반환합니다.
반환되는
EffectTiming
객체의 멤버와 타이밍 모델의 속성 간의 대응 관계는EffectTiming
인터페이스를 참조하세요. getComputedTiming()
-
이 애니메이션 효과의 계산된 타이밍 속성들을 반환합니다.
getTiming()
과getComputedTiming()
이 반환하는 객체의 일부 속성은 동일하지만, 다음과 같이 값이 다를 수 있습니다:-
duration
–getTiming()
은 문자열auto
를 반환할 수 있지만,getComputedTiming()
은 반복 지속 시간의 계산값에 해당하는 숫자를 반환해야 하며, 이는duration
멤버 설명에 따라 결정됩니다.이 명세 레벨에서는
auto
값이 0으로 대체됨을 의미합니다. -
fill
– 마찬가지로getTiming()
은auto
를 반환할 수 있지만,getComputedTiming()
은 FillMode의 실제 값을 반환해야 하며, 이는fill
멤버 설명에 따라 결정됩니다.이 명세 레벨에서는
auto
값이none
FillMode 값으로 대체됨을 의미합니다.
참고: 향후에는 다른 타이밍 멤버도
auto
와 유사한 값을 확장할 수 있습니다. 타이밍 계산 시, 허용값의 범위나 타입이 변경될 수 있으므로getComputedTiming()
을 사용하는 것이 호환성에 유리합니다.반환값 차이 외에도,
getTiming()
과 비교했을 때,getComputedTiming()
은ComputedEffectTiming
딕셔너리에서 정의한 추가 타이밍 정보를 반환합니다. -
updateTiming(timing)
-
이 애니메이션 효과의 지정된 타이밍 속성을 갱신합니다. 애니메이션 효과의 타이밍 속성 갱신 절차를 실행하며,
timing
파라미터를 input으로 넘깁니다.optional
OptionalEffectTiming
timing-
갱신할 타이밍 속성입니다.
timing
에 없는 멤버에 해당하는 타이밍 속성은 수정되지 않습니다.
remove()
메서드는
효과를 부모 그룹이나 애니메이션에서 제거하는 데 사용할 수 있습니다. 1단계에서 남겨두고 애니메이션에서 효과를 제거하는 것으로만 정의할까요? [Issue #2082]
6.5.1.
EffectTiming
및 OptionalEffectTiming
딕셔너리
EffectTiming
딕셔너리는 AnimationEffect
의
타이밍 속성을 나타냅니다.
OptionalEffectTiming
딕셔너리는 EffectTiming
딕셔너리의 변형으로, 일부 멤버가 존재하지 않아도 됩니다.
이는 updateTiming()
메서드에서 타이밍 속성의 델타 업데이트를 수행할 때 사용됩니다.
AnimationEffect
인터페이스의 애니메이션 효과의 타이밍
속성에 적용됩니다.
dictionary {
EffectTiming double delay = 0;double endDelay = 0;FillMode fill = "auto";double iterationStart = 0.0;unrestricted double iterations = 1.0; (unrestricted double or DOMString )duration = "auto";PlaybackDirection direction = "normal";DOMString easing = "linear"; };dictionary {
OptionalEffectTiming double delay ;double endDelay ;FillMode fill ;double iterationStart ;unrestricted double iterations ; (unrestricted double or DOMString )duration ;PlaybackDirection direction ;DOMString easing ; };
delay
, 타입 double, 기본값0
endDelay
, 타입 double, 기본값0
fill
, 타입 FillMode, 기본값"auto"
-
채움 모드로, 애니메이션 효과가 활성 구간 외부에서 어떻게 동작할지 정의합니다.
타이밍 계산 시, 특수 문자열 값
auto
는 타이밍 모델에서 인식하는 채움 모드 중 하나로 확장됩니다:§ 4.6 채움 동작에서 설명한 것처럼, 무기한 채움 애니메이션 사용은 지양해야 합니다. iterationStart
, 타입 double, 기본값0.0
-
애니메이션 효과의 반복 시작 속성으로, 0 이상의 유한 실수이며 애니메이션 효과가 시작되는 반복 인덱스 및 그 반복 내 진행도를 의미합니다.
예를 들어, 값이 0.5이면 애니메이션 효과가 첫 반복의 중간에서 시작됨을, 1.2이면 두 번째 반복의 20% 지점에서 시작됨을 의미합니다.
iterations
값은iterationStart
에 더해진다고 볼 수 있습니다. 예를 들어,iterationStart
가 "0.5"이고iterations
가 "2"이면 반복은 두 번이지만, 시작과 끝이 반복 구간의 중간에서 이루어집니다.iterationStart
값이 1 이상이면, iteration composite operation이 accumulate일 때나, 현재 반복 인덱스가 의미 있을 때 유용합니다. iterations
, 타입 unrestricted double, 기본값1.0
-
애니메이션 효과의 반복 횟수 속성으로, 0 이상의 실수(양의 무한대 포함)이며 애니메이션 효과를 반복할 횟수입니다.
+Infinity
로 지정하면 효과가 무한 반복됩니다(단, 효과의 duration이 0이면 즉시 종료됨). duration
, 타입(unrestricted double or DOMString)
, 기본값"auto"
-
반복 지속 시간으로, 0 이상의 실수(양의 무한대 포함)이며 애니메이션 효과의 한 번 반복에 소요되는 시간입니다.
이 명세 레벨에서는 문자열 값
auto
를 타이밍 모델 계산 및duration
멤버 반환값에서 0으로 처리합니다. 단, 작성자가auto
를 지정하면duration
멤버를getTiming()
에서 반환할 때auto
를 반환해야 합니다.향후 명세 레벨에서는 그룹 효과 등에서
auto
값이 자식 효과의 duration을 포함하도록 확장될 수 있습니다. direction
, 타입 PlaybackDirection, 기본값"normal"
easing
, 타입 DOMString, 기본값"linear"
-
타이밍 함수로, 시간 값을 스케일링하여 이징 효과를 생성합니다.
문자열의 문법은 <easing-function> 프로덕션에 정의되어 있습니다([CSS-EASING-1]).
6.5.2.
FillMode
열거형
enum {
FillMode ,
"none" ,
"forwards" ,
"backwards" ,
"both" };
"auto"
none
-
채움 없음.
forwards
-
forwards 채움.
backwards
-
backwards 채움.
both
-
backwards 및 forwards 모두 채움.
auto
-
채움 없음. 이후 명세 레벨에서는 다른 종류의 애니메이션 효과에 대해 다른 동작을 할 수 있습니다.
6.5.3.
PlaybackDirection
열거형
enum {
PlaybackDirection ,
"normal" ,
"reverse" ,
"alternate" };
"alternate-reverse"
normal
-
모든 반복이 지정된 대로 재생됩니다.
reverse
-
모든 반복이 지정된 순서의 반대 방향으로 재생됩니다.
alternate
-
짝수 반복은 지정된 대로, 홀수 반복은 반대 방향으로 재생됩니다.
alternate-reverse
-
짝수 반복은 반대 방향으로, 홀수 반복은 지정된 대로 재생됩니다.
6.5.4.
AnimationEffect
의 타이밍 업데이트
애니메이션 효과의 타이밍 속성 업데이트를 effect에
대해,
EffectTiming
또는 OptionalEffectTiming
객체 input을 사용해 다음 절차를 수행합니다:
-
input의
iterationStart
멤버가 존재하고 0 미만이면, TypeError를 발생시키고 절차를 중단합니다.참고: TypeError를 사용하는 이유는 RangeError가 아닌 WebIDL의 [EnforceRange] 어노테이션의 동작을 반영하기 위함이며, 향후 부동소수점 값에도 적용될 수 있습니다.
-
input의
iterations
멤버가 존재하며, 0 미만이거나NaN
이면 TypeError를 발생시키고 절차를 중단합니다. -
input의
duration
멤버가 존재하며, 0 미만이거나NaN
이면 TypeError를 발생시키고 절차를 중단합니다. -
input의
easing
멤버가 존재하지만 <easing-function> 프로덕션으로 파싱할 수 없으면, TypeError를 발생시키고 절차를 중단합니다. -
input에서 존재하는 각 멤버를 아래와 같이 effect의 해당 타이밍 속성에 할당합니다:
6.5.5. ComputedEffectTiming
딕셔너리
타이밍 모델에서 계산된 타이밍 속성은 ComputedEffectTiming
딕셔너리 객체로 노출됩니다.
dictionary :
ComputedEffectTiming EffectTiming {unrestricted double endTime ;unrestricted double activeDuration ;double ?localTime ;double ?progress ;unrestricted double ?currentIteration ; };
endTime
, 타입 unrestricted double-
애니메이션 효과의 종료 시간(end time)은 0 로컬 시간(local time)(즉, 해당 애니메이션이 애니메이션과 연관되어 있다면 시작 시간(start time) 이후)부터 밀리초 단위로 표현됩니다. 이는 애니메이션 효과의 활성 구간(active interval) 마지막과 종료 지연(end delay)을 더한 값에 해당합니다.
activeDuration
, 타입 unrestricted doublelocalTime
, 타입 double, nullable-
이 애니메이션 효과가 애니메이션과 연관되어 있지 않으면
null
이 됩니다. progress
, 타입 double, nullable-
이 애니메이션 효과의 현재 반복 진행도(iteration progress)입니다.
currentIteration
, 타입 unrestricted double, nullable-
첫 번째 반복은 0부터 시작하는 현재 반복(current iteration) 인덱스입니다.
대부분의 경우 이 값은 양의 정수입니다. 하지만, 0 지속시간 애니메이션이 무한 반복될 경우 값은 양의 Infinity가 됩니다.
미해결(unresolved) 시간과 마찬가지로, 현재 반복(current iteration)이 미해결 상태라면 null 값으로 표현됩니다.
6.6.
KeyframeEffect
인터페이스
키프레임 효과는 KeyframeEffect
인터페이스로 표현됩니다.
[Exposed =Window ]interface :
KeyframeEffect AnimationEffect {constructor (Element ?target ,object ?keyframes ,optional (unrestricted double or KeyframeEffectOptions )options = {});constructor (KeyframeEffect source );attribute Element ?target ;attribute CSSOMString ?pseudoElement ;attribute CompositeOperation composite ;sequence <object >getKeyframes ();undefined setKeyframes (object ?); };
keyframes
KeyframeEffect (target, keyframes, options)
-
아래 절차에 따라 새로운
KeyframeEffect
객체를 생성합니다:-
새로운
KeyframeEffect
객체 effect를 생성합니다. -
effect의 타겟 요소를 target으로 설정합니다.
-
타겟 의사 선택자를 아래 조건 중 처음 일치하는 결과로 설정합니다.
- 만약 options가
KeyframeEffectOptions
객체이고pseudoElement
속성을 가진 경우, -
타겟 의사 선택자를
pseudoElement
속성 값으로 설정합니다.이 속성을 설정할 때, 인터페이스의
pseudoElement
setter에 정의된 예외 처리가 적용됩니다. 만약 setter에서 예외를 발생시켜야 한다면, 이 절차도 동일한 예외를 발생시키고 이후 모든 단계를 중단해야 합니다. - 그 밖의 경우,
-
타겟 의사 선택자를
null
로 설정합니다.
- 만약 options가
-
timing input을 아래 조건 중 처음 일치하는 결과로 설정합니다.
- 만약 options가
KeyframeEffectOptions
객체인 경우, -
timing input을 options로 설정합니다.
- 그 밖의 경우(options가
double
인 경우), -
timing input을 모든 멤버가 기본값이고
duration
값만 options으로 설정된 새로운EffectTiming
객체로 설정합니다.
- 만약 options가
-
effect에 대해 timing input을 사용하여 애니메이션 효과의 타이밍 속성 업데이트 절차를 호출합니다.
만약 해당 절차에서 예외가 발생하면, 예외를 전파하고 이 절차를 중단합니다.
-
만약 options가
KeyframeEffectOptions
객체라면, effect의composite
속성을 options의 해당 값으로 할당합니다.이 속성을 할당할 때,
KeyframeEffect
인터페이스의 setter에 정의된 예외 처리가 적용됩니다. 만약 setter가 options의 값에 대해 예외를 발생시켜야 한다면, 동일한 예외를 발생시키고 절차를 중단해야 합니다. -
키프레임 집합을
setKeyframes()
절차를 keyframes 인자로 호출하여 초기화합니다.
Element
? target-
타겟 요소. 특정 요소를 타겟하지 않는 애니메이션에서는
null
일 수 있습니다. object? keyframes
-
사용할 키프레임 집합. 이 인자의 형식과 처리 방법은 § 6.6.3 키프레임 인자 처리에서 정의됩니다.
optional
KeyframeEffectOptions
options-
효과의 반복 지속 시간을 지정하는 숫자 또는 효과의 타이밍 및 동작을 지정하는 속성 집합입니다.
이 생성자의 사용 예시는 § 6.6.1 새로운 KeyframeEffect 객체 생성에서 확인할 수 있습니다.
-
KeyframeEffect (source)
-
아래 절차에 따라
KeyframeEffect
객체를 새로 생성하며,source
와 동일한 속성을 갖습니다:-
새
KeyframeEffect
객체 effect를 생성합니다. -
effect의 다음 속성을 source의 해당 값으로 설정합니다:
참고:
KeyframeEffect(target, keyframes, options)
생성자와 달리, source에 지정된 타이밍 속성은 유효하다고 간주할 수 있으므로 예외를 다시 발생시킬 필요가 없습니다.
KeyframeEffect
source-
새 키프레임 효과를 정의할 속성을 복사할 키프레임 효과.
-
target
, 타입 Element, nullable-
이 객체가 애니메이션하는 타겟 요소입니다 (만약 효과 타겟이
Element
인 경우 또는 의사 요소라면 기원 요소). 오디오 API 등 특정 요소가 없는 애니메이션에서는null
일 수 있습니다. pseudoElement
, 타입 CSSOMString, nullable-
타겟 의사 선택자. 효과 타겟이 없거나 효과 타겟이 요소(즉, 의사 요소가 아닌 경우)라면
null
입니다. 효과 타겟이 의사 요소라면, 해당 의사 요소 선택자(예:::before
)를 지정합니다.설정 시, 애니메이션 효과의 타겟 의사 선택자를 제공된 값으로 설정하며, 다음 예외를 적용합니다:
-
값이
null
이 아니고 <pseudo-element-selector>로서 올바르지 않으면, 사용자 에이전트는 DOMException (에러 이름SyntaxError
) 을 발생시키고 애니메이션 효과의 타겟 의사 선택자는 변경하지 않습니다.참고, 이 컨텍스트에서 invalid는 invalid selector 정의를 따릅니다. 즉, 문법적으로 잘못된 의사 요소와 사용자 에이전트가 지원하지 않는 의사 요소 모두 invalid로 간주됩니다.
-
레거시 Selectors Level 2 단일 콜론 선택자(':before', ':after', ':first-letter', ':first-line')가 지정된 경우, 타겟 의사 선택자는 동등한 2콜론 선택자(e.g. '::before')로 설정해야 합니다.
-
composite
, 타입 CompositeOperation-
이 키프레임 효과를 효과 스택과 합성하는 데 사용하는 합성 연산입니다. CompositeOperation 열거형 값 중 하나로 지정합니다.
sequence<object> getKeyframes()
-
이 효과를 구성하는 키프레임들과 각 키프레임의 계산된 키프레임 오프셋을 반환합니다.
이 섹션은 규범적이지 않습니다이 메서드의 결과는 아래 형식의 객체 시퀀스입니다:
dictionary ComputedKeyframe { // ... property-value pairs ... // i.e. DOMString propertyNamedouble ?offset =null ;double computedOffset ;DOMString easing = "linear";CompositeOperationOrAuto composite = "auto"; };각 멤버의 의미와 값은 아래와 같습니다:
offset
-
키프레임 오프셋 값으로, 0.0~1.0 사이의 숫자 또는
null
입니다.해당 키프레임이 인접 키프레임 간 자동 간격 지정일 경우
null
이 됩니다. computedOffset
-
이 키프레임의 계산된 키프레임 오프셋으로, 키프레임 오프셋 누락 계산 절차에서 산출됩니다.
offset
과 달리computedOffset
은 절대 null이 아닙니다. easing
-
이 키프레임부터 다음 키프레임까지 시간 진행을 변환하는 데 사용하는 타이밍 함수입니다.
composite
-
이 키프레임의 값과 기저 값을 결합하는 데 사용하는 키프레임별 합성 연산입니다.
키프레임은 현재 WebIDL로 완전히 표현할 수 없는 부분적으로 열린 딕셔너리 타입이므로, 이 메서드 결과 준비 절차는 아래와 같이 서술됩니다:
-
result를 빈 객체 시퀀스로 초기화합니다.
-
keyframes를 아래 중 하나로 설정합니다:
-
이 키프레임 효과가
CSSAnimation
과 연결되어 있고, 키프레임이setKeyframes()
성공 호출로 대체되지 않은 경우; 해당 키프레임 효과의 계산된 키프레임. -
그 외에는, 이 키프레임 효과의 키프레임에 대해 키프레임 오프셋 누락 계산 절차를 적용한 결과.
참고: CSS 애니메이션의 경우, 모든 CSS 지정 키프레임이 딕셔너리로 표현될 수는 없으므로 계산된 키프레임을 반환합니다.
-
-
각 keyframe에 대해 다음 단계를 수행합니다:
-
아래 정의에 따라 딕셔너리 객체 output keyframe을 초기화합니다:
dictionary
{BaseComputedKeyframe double ?
=offset null ;double
;computedOffset DOMString
= "linear";easing CompositeOperationOrAuto
= "auto"; };composite -
output keyframe의
offset
,computedOffset
,easing
,composite
멤버를 각각 키프레임 오프셋, 계산된 키프레임 오프셋, 키프레임별 타이밍 함수, 키프레임별 합성 연산 값으로 설정합니다. -
keyframe의 각 애니메이션 속성-값 쌍 declaration에 대해:
-
property name을 declaration의 속성명에 애니메이션 속성명 → IDL 속성명 알고리즘을 적용한 결과로 합니다.
-
IDL value를 declaration을 CSS 값 직렬화 알고리즘에 넘겨서 직렬화한 결과로 합니다.
-
value를 DOMString → ECMAScript String 변환에 IDL value를 넘긴 결과로 합니다.
-
output keyframe에 property name 이름으로 value를 [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true, [[Value]]: value 설정하여 [[DefineOwnProperty]] 내부 메서드를 Boolean flag false와 함께 호출합니다.
-
-
output keyframe을 result에 추가합니다.
-
-
result를 반환합니다.
void setKeyframes(object? keyframes)
-
이 효과를 구성하는 키프레임 집합을 대체합니다.
object? keyframes
-
키프레임 시퀀스. 형식과 처리 방법은 § 6.6.3 키프레임 인자 처리에서 정의됩니다.
이 효과의 키프레임 집합은 키프레임 인자 처리 절차를 수행한 결과로 대체됩니다. 만약 해당 절차에서 예외가 발생하면, 이 효과의 키프레임은 변경되지 않습니다.
6.6.1. KeyframeEffect
객체 생성하기
KeyframeEffect
생성자는 새로운 KeyframeEffect
객체를 만드는 여러 방식을 제공합니다.
가장 단순하게, KeyframeEffect
객체로 elem
의 "left" 속성을 3초 동안 100px로 변경하려면 다음과 같이 작성할 수 있습니다:
두 번째 파라미터(키프레임 목록)는 여러 속성을 지정할 수 있습니다. (§ 6.6.3 키프레임 인자 처리 참고)
// 여러 속성을 한 번에 지정 var effectA= new KeyframeEffect( elem, { left: '100px' , top: '300px' }, 3000 ); // 여러 키프레임 지정 var effectB= new KeyframeEffect( elem, [ { left: '100px' }, { left: '300px' } ], 3000 );
세 번째 파라미터(애니메이션 타이밍)는 위처럼 밀리초 단위의 반복 지속 시간 숫자일 수도 있고, 시작 지연 등 추가 타이밍 속성을 지정하려면 다음처럼 EffectTiming
객체를 사용할 수도 있습니다:
duration을 지정하지 않으면 0이 사용됩니다. 보간 없이 속성만 설정하는 애니메이션도 아래처럼 만들 수 있습니다:
§ 4.6 채움 동작에서 설명한 것처럼, 이런 식의 무한 채움 애니메이션 사용은 권장하지 않습니다.
KeyframeEffect
객체를 생성했다면,
Animation
에 추가한 뒤 재생할 수 있습니다.
간단한 효과에는 Element.animate
단축 메서드가 더
편리합니다. 이 메서드는 위 과정을 자동으로 수행합니다. 예를 들면,
6.6.2. 속성 이름과 IDL 이름
애니메이션 속성명 → IDL 속성명 알고리즘은 property에 대해 아래와 같습니다:
-
property가 <custom-property-name> 프로덕션을 따를 경우, property를 반환합니다.
-
property가 CSS float 속성인 경우, "cssFloat" 문자열을 반환합니다.
-
property가 CSS offset 속성인 경우, "cssOffset" 문자열을 반환합니다.
-
그 밖의 경우, CSS 속성 → IDL 속성 알고리즘([CSSOM])을 property에 적용한 결과를 반환합니다.
IDL 속성명 → 애니메이션 속성명 알고리즘은 attribute에 대해 아래와 같습니다:
-
attribute가 <custom-property-name> 프로덕션을 따를 경우, attribute를 반환합니다.
-
attribute가 "cssFloat" 문자열이면, CSS float 속성을 나타내는 애니메이션 속성을 반환합니다.
-
attribute가 "cssOffset" 문자열이면, CSS offset 속성을 나타내는 애니메이션 속성을 반환합니다.
-
그 밖의 경우, IDL 속성 → CSS 속성 알고리즘([CSSOM])을 attribute에 적용한 결과를 반환합니다.
6.6.3.
keyframes
인자 처리
아래 메서드는 모두 키프레임 집합을 인자로 받습니다:
-
setKeyframes()
메서드(KeyframeEffect
인터페이스), -
animate()
메서드(Animatable
인터페이스 믹스인).
이 인자는 아래 두 가지 형식 중 하나로 지정할 수 있습니다:
// 아래 두 표현식은 동일 결과를 만듭니다: elem. animate([ { color: 'blue' }, { color: 'green' }, { color: 'red' }, { color: 'yellow' } ], 2000 ); elem. animate({ color: [ 'blue' , 'green' , 'red' , 'yellow' ] }, 2000 ); // 여러 속성 애니메이션의 경우 아래 두 표현도 동등합니다: elem. animate([ { color: 'blue' , left: '0px' }, { color: 'green' , left: '-20px' }, { color: 'red' , left: '100px' }, { color: 'yellow' , left: '50px' } ], 2000 ); elem. animate({ color: [ 'blue' , 'green' , 'red' , 'yellow' ], left: [ '0px' , '-20px' , '100px' , '50px' ] }, 2000 ); // 참고로 아래 세 표현식도 모두 동일합니다: elem. animate([ { color: 'red' } ], 1000 ); elem. animate({ color: [ 'red' ] }, 1000 ); elem. animate({ color: 'red' }, 1000 );
첫 번째 형식(배열형)은 각 키프레임이 애니메이션 속성당 최대 하나의 값을 지정하는 키프레임 배열입니다. 두 번째 형식(객체형)은 각 애니메이션 속성이 단일 값 또는 값 배열을 지정하는 객체입니다.
첫 번째 배열형이 표준 형식이며, getKeyframes()
메서드가 반환하는 형식입니다.
키프레임 오프셋도 아래와 같이 두 형식 중 하나로 지정할 수 있습니다:
// 오프셋 없는 키프레임은 자동으로 오프셋이 할당됨 // 첫 키프레임은 0, 중간은 0.65, 마지막은 1로 계산됨. elem. animate([ { color: 'blue' }, { color: 'green' , offset: 0.5 }, { color: 'red' }, { color: 'yellow' , offset: 0.8 }, { color: 'pink' } ], 2000 ); // 아래도 동일한 결과. 마지막 값은 명시할 필요 없이 자동으로 'null'로 처리됨. elem. animate({ color: [ 'blue' , 'green' , 'red' , 'yellow' , 'pink' ], offset: [ null , 0.5 , null , 0.8 ] }, 2000 );
마찬가지로 타이밍 함수나 키프레임별 합성 연산도 두 형식 중 하나로 지정할 수 있습니다. 배열형은 각 키프레임마다 다른 값을 지정할 수 있고, 객체형은 값 리스트가 반복되어 모든 키프레임에 값이 할당될 때까지 이어집니다.
// 타이밍 함수는 _키프레임 사이_에 적용되므로 마지막 키프레임에 지정해도 무시됨. elem. animate([ { color: 'blue' , easing: 'ease-in' }, { color: 'green' , easing: 'ease-out' }, { color: 'yellow' } ], 2000 ); // 아래도 동일 결과. elem. animate({ color: [ 'blue' , 'green' , 'yellow' ], easing: [ 'ease-in' , 'ease-out' ] }, 2000 ); // 반복 동작 덕분에 모든 키프레임에 동일 값 할당도 간단: elem. animate({ color: [ 'blue' , 'green' , 'yellow' ], easing: 'ease-in-out' }, 2000 );
두 형식 모두의 easing
속성은 키프레임별 타이밍 함수를 설정한다는 점에 유의하세요.
이는 KeyframeEffectOptions
오브젝트(또는 KeyframeAnimationOptions
오브젝트, animate()
메서드 사용시 Animatable
믹스인 인터페이스에서)로 지정하는 전체 타이밍 함수와는 별개의 것입니다.
반복 지속 시간에 적용되는
함수와는 다릅니다.
아래 예시에서 두 문장은 서로 다른 결과를 산출합니다.
// 이 경우, 'ease-in-out'이 각 color 값 사이에 적용됨. elem. animate({ color: [ 'blue' , 'green' , 'yellow' ], easing: 'ease-in-out' }, 2000 ); // 반면, 이 경우는 'ease-in-out'이 애니메이션 전체(즉 'blue'~'yellow')에 적용됨. elem. animate({ color: [ 'blue' , 'green' , 'yellow' ] }, { duration: 2000 , easing: 'ease-in-out' });
keyframes
인자의 타입은 부분적으로 열린 딕셔너리 타입에 의존하므로 WebIDL로 표현할 수 없습니다.
개념적으로, 이 인자의 타입은 아래 WebIDL 유사 정의와 동일합니다:
dictionary Keyframe { // ... property-value pairs ... // i.e. DOMString propertyNamedouble ?offset =null ;DOMString easing = "linear";CompositeOperationOrAuto composite = "auto"; };dictionary PropertyIndexedKeyframes { // ... property-value and property-valuelist pairs ... // i.e. (DOMString or sequence<DOMString>) propertyName (double ?or sequence <double ?>)offset = []; (DOMString or sequence <DOMString >)easing = []; (CompositeOperationOrAuto or sequence <CompositeOperationOrAuto >)composite = []; };typedef (sequence <Keyframe >or PropertyIndexedKeyframes )KeyframeArgument ;
각 인자의 의미와 허용 값은 다음과 같습니다:
- offset
-
키프레임 오프셋 값으로, 키프레임의 0.0~1.0 사이 숫자 또는
null
입니다.null
값은 키프레임이 인접 키프레임 사이에 자동 간격으로 배치됨을 의미합니다.오프셋이 [0.0, 1.0] 범위 밖이면 TypeError가 발생합니다.
오프셋을 지정한 키프레임은 오프셋이 증가하는 순서로 제공해야 합니다. 인접하고 동일한 오프셋은 허용됩니다.
- easing
-
타이밍 함수로, 해당 키프레임에서 다음 키프레임까지 시간 진행 변환에 사용됩니다.
문자열 파싱 구문 및 오류 처리는
easing
attribute,EffectTiming
인터페이스와 동일합니다. - composite
-
키프레임별 합성 연산으로, 해당 키프레임 값과 기저 값을 결합합니다.
이 타입은 WebIDL로 표현할 수 없으므로 처리 절차는 다음 서술로 정의됩니다.
keyframes
인자를 받는 각 메서드는 입력값에 대해 키프레임 인자 처리 절차를 실행하고, 그 결과를 저장합니다.
우선 두 가지 보조 정의를 제시합니다.
명령 완료 레코드 확인은 result가 ECMAScript 연산 호출의 완료 레코드일 때, 다음 단계와 같습니다:
-
result가 갑작스런 완료라면, result의 [[value]] 필드의 예외를 throw하고 절차를 중단합니다.
[[type]]이 break, continue, return일 때 어떻게 해야 할까요? 해당 경우가 있을까요?
-
result를 그 [[value]] 필드 값으로 대체합니다.
키프레임 유사 객체 처리 절차는 두 인자를 받습니다:
-
ECMAScript 객체 keyframe input
-
불리언 플래그 allow lists
그리고 아래 절차를 사용하여 false일 때는 속성명을 DOMString 값으로, true일 때는 속성명을 DOMString 값 시퀀스로 매핑하는 맵을 반환합니다:
-
ECMAScript 값을 딕셔너리 타입으로 변환 절차를 keyframe input에 대해 실행합니다. allow lists 값에 따라 딕셔너리 타입은 아래와 같습니다:
- 만약 allow lists가 true라면,
-
딕셔너리 타입은 아래와 같습니다:
dictionary
{ (BasePropertyIndexedKeyframe double ?or sequence <double ?>)
= []; (offset DOMString or sequence <DOMString >)
= []; (easing CompositeOperationOrAuto or sequence <CompositeOperationOrAuto >)
= []; };composite - 그 밖의 경우,
-
아래 딕셔너리 타입 사용:
dictionary
{BaseKeyframe double ?
=offset null ;DOMString
= "linear";easing CompositeOperationOrAuto
= "auto"; };composite
이 절차 결과를 keyframe output으로 저장합니다.
-
아래와 같이 animatable properties 리스트를 만듭니다:
-
animatable properties를 구현체에서 애니메이션 가능한 속성(애니메이션 가능한 longhand 하위 속성이 있는 shorthand 포함) 이름 리스트로 만듭니다.
-
각 속성명을 애니메이션 속성명 → IDL 속성명 알고리즘으로 변환합니다.
-
-
input properties를 EnumerableOwnNames 연산에 keyframe input을 넘겨 얻습니다.
-
animation properties 리스트는 input properties와 animatable properties 모두에 포함된 속성, 또는 input properties에 포함되어 있고 <custom-property-name> 프로덕션을 만족하는 속성으로 구성합니다.
-
animation properties를 각 속성명의 Unicode 코드포인트 오름차순으로 정렬합니다.
-
각 property name에 대해,
-
raw value를 [[Get]] 내부 메서드에 keyframe input과 property name을 넘겨 얻습니다.
-
raw value에 대해 완료 레코드 확인을 수행합니다.
-
raw value를 DOMString 또는 DOMString 시퀀스 property values로 변환합니다:
- 만약 allow lists가 true라면,
-
property values를 ECMAScript 값 → IDL 값 변환 절차로
(DOMString or sequence<DOMString>)
타입으로 변환합니다.단일 DOMString이면, 그 값만 포함하는 DOMString 시퀀스로 대체합니다.
- 그 밖의 경우,
-
raw value를 ECMAScript 값 → DOMString 변환 절차로 변환합니다.
-
normalized property name을 IDL 속성명 → 애니메이션 속성명 알고리즘을 property name에 적용한 결과로 합니다.
-
keyframe output에 normalized property name 이름으로 property values를 속성값으로 추가합니다.
-
-
keyframe output을 반환합니다.
키프레임 인자 처리 절차는 nullable ECMAScript 객체 object를 받아 아래 절차로 키프레임 시퀀스를 반환합니다:
-
object가 null이면 빈 키프레임 시퀀스를 반환합니다.
-
processed keyframes를 빈 키프레임 시퀀스로 초기화합니다.
-
method를 GetMethod(object, @@iterator) 결과로 설정합니다.
-
method에 대해 완료 레코드 확인을 수행합니다.
-
아래 조건 중 처음 일치하는 것에 대해 단계 수행:
- method가 undefined가 아니라면,
-
-
iter를 GetIterator(object, method)로 설정합니다.
-
iter에 대해 완료 레코드 확인을 수행합니다.
-
반복:
-
next를 IteratorStep(iter)로 설정합니다.
-
next에 대해 완료 레코드 확인을 수행합니다.
-
next가 false이면 반복 종료.
-
nextItem을 IteratorValue(next)로 설정합니다.
-
nextItem에 대해 완료 레코드 확인을 수행합니다.
-
Type(nextItem) 값이 Undefined, Null, Object가 아니면 TypeError를 throw하고 단계 중단.
-
processed keyframes에 키프레임 유사 객체 처리 절차(nextItem, allow lists=false) 결과를 추가합니다.
-
-
- 그 밖의 경우,
-
-
property-indexed keyframe을 키프레임 유사 객체 처리 절차(object, allow lists=true) 결과로 설정합니다.
-
property-indexed keyframe의 각 멤버 m에 대해:
-
property name을 m의 키로 합니다.
-
property name이 "composite", "easing", "offset" 중 하나면 이 루프의 남은 단계 건너뛰고 다음 멤버로 계속.
-
property values를 m의 값으로 합니다.
-
property keyframes를 빈 키프레임 시퀀스로 초기화합니다.
-
각 property values의 값 v에 대해:
-
키프레임 오프셋 누락 계산 절차를 property keyframes에 적용.
-
property keyframes 내 키프레임을 processed keyframes에 추가.
-
-
processed keyframes를 각 키프레임의 계산된 키프레임 오프셋 오름차순으로 정렬합니다.
-
인접 키프레임의 계산된 키프레임 오프셋이 같으면 병합.
-
offsets를 property-indexed keyframe의 "offset" 멤버 타입에 따라 할당:
sequence<double?>
,-
"offset"의 값을 그대로 사용.
double?
,-
길이 1의 시퀀스에 "offset" 값을 단일 아이템으로, 즉 «
offset
».
-
offsets의 각 값을 processed keyframes에서 해당 위치 키프레임 오프셋에 할당.
-
easings를 property-indexed keyframe의 "easing" 멤버 타입에 따라 할당:
sequence<DOMString>
,-
"easing" 값을 그대로 사용.
DOMString
,-
길이 1의 시퀀스에 "easing" 값을 단일 아이템으로, 즉 « "easing" ».
-
easings이 빈 시퀀스면 « "linear" »를 단일 값으로 함.
-
easings이 processed keyframes보다 아이템 수가 적으면, 앞에서부터 반복해 processed keyframes 길이만큼 채움.
-
easings이 processed keyframes보다 길면 남는 아이템을 unused easings로 저장.
-
easings의 각 값을 processed keyframes의 해당 위치 키프레임의 "easing" 속성에 할당.
-
property-indexed keyframe의 "composite" 멤버가 빈 시퀀스가 아니라면:
-
composite modes를 "composite" 멤버의 타입에 따라
CompositeOperationOrAuto
시퀀스로 할당. 단일 값이면 길이 1 시퀀스로. -
composite modes가 processed keyframes보다 짧으면 반복해 채움.
-
auto
가 아닌 각 값을 processed keyframes의 해당 위치 키프레임의 키프레임별 합성 연산에 할당.
-
-
-
processed keyframes이 오프셋 기준 느슨한 정렬이 아니면, TypeError를 throw하고 중단.
-
만약 processed keyframes 내에 키프레임 중 키프레임 오프셋이 null이 아니고 0 미만이나 1 초과이면 TypeError를 throw하고 중단.
-
각 frame에 대해:
-
각 속성-값 쌍을 해당 속성의 문법으로 파싱. 값이 문법에 맞지 않으면 버림. 오류 진단 지원시 사용자 에이전트는 경고를 제공해야 함.
-
frame의 타이밍 함수를 "easing" 속성을
easing
문법으로 파싱한 결과로 설정. 파싱 실패시 TypeError throw 및 중단.참고: 위 두 단계 모두 CSS 파서를 사용하므로 CSS 주석/이스케이프는 허용되지만 성공 시 값에 남지 않습니다.
참고: "easing" 속성 파싱 실패 시, TypeError는 object의 모든 속성 읽기 이후에 throw되어야 하며, 나중에 부분적으로 열린 딕셔너리가 WebIDL에서 지원될 때와 동작이 달라지지 않도록 해야 합니다.
-
-
unused easings의 각 값도
easing
문법으로 파싱. 실패시 TypeError throw 및 중단.이 단계는 아래 모든 경우에 일관적으로 TypeError를 throw하기 위해 필요합니다:
elem
. animate({ easing: 'invalid' }); elem. animate({ easing: [ 'invalid' ] }); elem. animate([{ easing: 'invalid' }]);
6.6.4. KeyframeEffectOptions
딕셔너리
추가적인 파라미터는 KeyframeEffect(target, keyframes,
options)
생성자에 KeyframeEffectOptions
객체를 제공하여 전달할 수 있습니다.
dictionary :
KeyframeEffectOptions EffectTiming {CompositeOperation composite = "replace";CSSOMString ?pseudoElement =null ; };
composite
, 타입 CompositeOperation, 기본값"replace"
-
이 애니메이션을 효과 스택과 합성할 때 사용하는 합성 연산으로, CompositeOperation 열거형 값 중 하나로 지정합니다.
auto
키프레임별 합성 연산을 지정한 모든 키프레임에 적용됩니다. pseudoElement
, 타입 CSSOMString, nullable, 기본값null
6.7.
CompositeOperation
및 CompositeOperationOrAuto
열거형
키프레임 효과의 합성 동작에 사용할 수 있는 값은 CompositeOperation 열거형으로 표현됩니다.
enum {
CompositeOperation "replace" ,"add" ,"accumulate" };
replace
add
accumulate
-
accumulate 합성 연산 값에 해당하며, 애니메이션 효과가 합성 대상 기저 값에 누적됩니다.
키프레임의 합성 동작에 사용할 수 있는 값은 CompositeOperation
열거형의 값과 추가적으로 auto
값을 포함합니다.
enum {
CompositeOperationOrAuto "replace" ,"add" ,"accumulate" ,"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)
-
아래 순서로 동작합니다:
-
target을 이 메서드를 호출한 객체로 설정합니다.
-
target의 관련 Realm에서
KeyframeEffect
객체 effect를 생성합니다.KeyframeEffect(target, keyframes, options)
생성자와 동일 절차를 사용하며, target, keyframes, options 인자를 전달합니다.이 절차에서 예외가 발생하면 예외를 전파하고 중단합니다.
-
options가
KeyframeAnimationOptions
객체이면, timeline을 options의timeline
멤버 값으로, 없으면 이 메서드를 호출한 요소의 기본 문서 타임라인으로 설정합니다. -
target의 관련 Realm에서
Animation
객체 animation을 생성합니다.Animation()
생성자와 동일 절차를 사용하며, effect와 timeline을 인자로 넘깁니다. -
options가
KeyframeAnimationOptions
객체이면, options의id
값을 animation의id
속성에 할당합니다. -
animation에 대해 애니메이션 재생 절차를 auto-rewind 플래그 true로 실행합니다.
-
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
-
생성된
KeyframeEffect
및Animation
의 타이밍 및 애니메이션 옵션입니다.
-
sequence<Animation> getAnimations(options)
-
이 객체에 대해 관련 애니메이션 집합을 반환하거나,
options
파라미터에서subtree
값이 true일 경우, 이 객체에 대해 서브트리 관련 애니메이션 집합을 반환합니다.반환된 리스트는 애니메이션의 합성 순서에 따라 정렬되며, § 5.4.2 효과 스택을 참고하세요.
이 메서드를 호출하면 스타일 변경 이벤트가 타겟 요소에 발생합니다. 따라서 반환된 리스트는 애니메이션 관련 스타일 속성 등 아직 처리되지 않은 대기 중 스타일 변경 적용 이후 상태를 반영합니다.
options
-
getAnimations()
로 반환되는 애니메이션 집합을 제어하는 파라미터입니다.
6.9.
Document
인터페이스 확장
아래 확장들은 Document
인터페이스([DOM] 정의)에 적용됩니다.
partial interface Document {readonly attribute DocumentTimeline timeline ; };
timeline
, 타입 DocumentTimeline, 읽기 전용-
DocumentTimeline
객체로, 기본 문서 타임라인을 나타냅니다.
6.10. DocumentOrShadowRoot
인터페이스 믹스인 확장
아래 확장들은 DocumentOrShadowRoot
인터페이스 믹스인([DOM] 정의)에 적용됩니다.
partial interface mixin DocumentOrShadowRoot {sequence <Animation >getAnimations (); };
sequence<Animation> getAnimations()
-
이 메서드를 호출한 document 또는 shadow root의 서브트리 관련 애니메이션 집합을 반환합니다.
반환 리스트는 애니메이션의 합성 순서에 따라 정렬되며, § 5.4.2 효과 스택을 참고하세요.
이 메서드 호출은 document의 스타일 변경 이벤트를 트리거합니다. 따라서 반환 리스트는 아직 처리되지 않은 애니메이션 관련 스타일 속성 변경 등 대기 중 변경 적용 이후 상태를 반영합니다.
6.11.
Element
인터페이스 확장
DOM 요소는 애니메이션의 타겟이 될 수 있으므로,
Element
인터페이스([DOM])는 아래와 같이 확장됩니다:
Element includes Animatable ;
이 확장으로 아래와 같이 사용할 수 있습니다.
6.12. AnimationPlaybackEvent
인터페이스
애니메이션 재생
이벤트는 AnimationPlaybackEvent
인터페이스로 표현됩니다.
[Exposed =Window ]interface :
AnimationPlaybackEvent Event {constructor (DOMString ,
type optional AnimationPlaybackEventInit = {});
eventInitDict readonly attribute double ?currentTime ;readonly attribute double ?timelineTime ; };dictionary :
AnimationPlaybackEventInit EventInit {double ?currentTime =null ;double ?timelineTime =null ; };
AnimationPlaybackEvent(type, eventInitDict)
-
이벤트 생성 절차([DOM])를 따라 새로운
AnimationPlaybackEvent
객체를 만듭니다.
currentTime
, 타입 double, nullable, 기본값null
-
currentTime
속성 설명 참고. timelineTime
, 타입 double, nullable, 기본값null
-
timelineTime
속성 설명 참고.
6.13. 모델 생동성
모델의 어떤 부분이든 변경이 이루어지면 전체 타이밍 모델이 갱신되고 모든 종속된 스타일도 함께 갱신됩니다.
별도의 언급이 없는 한, 이 명세의 프로그래밍 인터페이스 섹션에서 정의된 인터페이스의 메서드 또는 생성자를 호출하거나, 멤버를 조회/설정해도 스타일 변경 이벤트(style change event)가 발생하지 않습니다.
참고: 이 명세를 확장하는 다른 명세들은 스타일 변경 이벤트가 트리거되는 상황을 추가하여 해당 이벤트에 대한 요구사항을 세분화할 것으로 예상됩니다. 예를 들어, 이 명세의 인터페이스가 CSS 마크업으로 정의된 애니메이션을 표현하는 경우, 많은 메서드들이 지정된 스타일의 변화를 반영하기 위해 스타일 변경 이벤트를 트리거해야 합니다.
위 요구사항과 명세의 다른 규범 요구사항에 기반하여 다음 불변식이 관찰될 수 있습니다:
- Web Animations 모델에 대한 변경은 즉시 반영된다
-
예를 들어,
KeyframeEffect
가Animation
과 연관되어 있고, 프로그래밍 인터페이스를 통해 탐색(seek)될 경우(§ 4.4.4 애니메이션의 현재 시간 설정 참고), 애니메이션의startTime
을 조회하면 모델의 갱신된 상태가 즉시 반영됩니다. - 애니메이션에 의해 영향을 받는 속성의 계산 스타일을 조회하면 애니메이션의 최신 상태가 반영된다
-
예를 들어, 어떤 요소에 새
Animation
을 적용한 직후에 사용 스타일을 조회하면, 새 애니메이션의 결과가 반환값에 반영됩니다. - 동일 태스크 내에서 이루어진 변경은 전체 변경 집합이 한 번에 렌더링되도록 동기화된다
-
모델 변경이 즉시 반영되는 것과 ECMAScript의 run-to-completion 의미론이 결합되어, 예를 들어 지정된 스타일 변화만 렌더링되고 애니메이션은 적용되지 않는 상황이 발생하지 않아야 합니다.
// Element.animate를 지원하지 않는 브라우저 대비 fallback 포함 페이드 효과 elem. style. opacity= '0' ; elem. animate([ { opacity: 1 }, { opacity: 0 } ], 500 ); 참고: 위 예시에서 사용자 에이전트가 위 변화가 전혀 적용되지 않은 프레임을 렌더링할 수 있습니다. 예를 들어 렌더링이 별도 프로세스에서 동작하고, 위 태스크 완료 직후 렌더링이 예약되었으나 변화가 해당 프로세스로 전달되기 전에 렌더링이 이루어지는 경우가 있을 수 있습니다.
currentTime
속성으로 반환된 값은 태스크 내에서는 변하지 않는다-
타임라인은 애니메이션 갱신 및 이벤트 전송 절차가 실행될 때마다 현재 시간을 갱신해야 하므로, 같은 스크립트 블록 내에서
currentTime
을 두 번 조회해도 아래 예시처럼 값은 같습니다. requestAnimationFrame
콜백에 전달된 시간은document.timeline.currentTime
과 같다-
HTML의 이벤트 루프 처리 모델에서 애니메이션 갱신 및 이벤트 전송 절차가 애니메이션 프레임 콜백 실행 전에 수행된다고 정의되어 있고, 해당 콜백에 전달되는 시간(now)은 두 절차 모두에 동일하게 전달되므로, 기본 문서 타임라인의 현재 시간은
requestAnimationFrame
에 전달된 시간과 일치해야 합니다. - 이 프로그래밍 인터페이스의 메서드를 호출해도 일반적으로 트랜지션이 트리거되지 않는다
-
다음 예시를 참고하세요:
// 트랜지션 시작점 설정 div. style. opacity= '1' ; getComputedStyle( div). opacity; // 트랜지션 종료점 설정 div. style. transition= 'opacity 1s' ; div. style. opacity= '0' ; // 애니메이션 실행 div. animate({ opacity: [ 0.5 , 1 ] }, 500 ); // 트랜지션 종료 대기 -- 아래는 절대 호출되지 않음! div. addEventListener( 'transitionend' , () => { console. log( 'transitionend' ); }); 이 경우
animate()
를 호출해도 스타일 변경 이벤트가 트리거되지 않습니다. 결과적으로 대기 중인 스타일 변경은 새 애니메이션으로 인한 스타일 변경과 동시에 처리됩니다. 애니메이션 스타일이 변경 전 스타일 및 변경 후 스타일을 덮어쓰기 때문에, 트랜지션이 생성되지 않고, transitionend 이벤트 핸들러도 절대 호출되지 않습니다.
7. 미디어 프래그먼트와의 통합
Media Fragments 명세 [MEDIA-FRAGS] 는 미디어 리소스의 시간 범위를 지정하는 방법을 정의합니다. 미디어 프래그먼트의 적용은 지정된 리소스의 MIME 타입에 따라 달라집니다. SVG MIME 타입 [SVG11]의 경우, 시간 관련 파라미터의 적용은 Animation Elements 명세에서 정의됩니다.
참고: 미디어 프래그먼트는 리소스의 MIME 타입을 기준으로 동작하도록 정의되어 있습니다. 이로 인해 Web Animations 콘텐츠가 사용되는 모든 상황에서 시간 지정이 지원되지 않을 수도 있습니다.
8. 페이지 표시와의 상호작용
HTML은 사용자 에이전트가 사용자 에이전트 정의 상태를 세션 히스토리 엔트리와 함께 저장하도록 허용하여, 사용자가 페이지 간 이동할 때 페이지의 이전 상태(예: 스크롤 위치 [HTML])를 복구할 수 있도록 합니다.
문서가 언로드/이동될 때 미디어 요소를 일시정지/재개하는 사용자 에이전트라면, Web Animations 콘텐츠가 포함된 문서에도 일관된 처리를 적용하는 것이 권장됩니다. 이 동작이 제공되는 경우, 벽시계 시간(wallclock time)을 추적하는 타임라인의 시간 값을 조정하는 방식으로 구현해야 합니다.
이 방식이 시간 값이 navigationStart
기준이고 requestAnimationFrame
이 document.timeline.currentTime
과 동일한 시간을 사용하는 것과 충돌하지
않는가? [Issue
#2083]
9. 구현 요구사항
9.1. 시간 값의 정밀도
시간 값의 내부 표현은 구현에 따라 다르지만, 사용자 에이전트가 입력된 시간 값을 마이크로초 단위로 표현할 수 있도록 하는 것이 권장됩니다. 이렇게 하면 시간 값이(통상적으로 밀리초 단위) 0.001일 때 0.0과 구분할 수 있습니다.
9.2. 적합성 기준
이 명세는 애니메이션을 위한 추상 모델을 정의하며, 스크립팅을 지원하지 않는 사용자 에이전트의 경우 테스트 가능한 표면이 없으므로 적합성 기준이 없습니다.
스크립팅을 지원하지 않는 사용자 에이전트라 하더라도, 이 명세를 바탕으로 정의된 추가 기술을 구현할 수 있으며, 이 경우 이 명세에서 제공하는 정의가 해당 추가 기술의 적합성 기준의 일부가 됩니다.
적합한 스크립트 기반 Web Animations 사용자 에이전트란 § 6 프로그래밍 인터페이스에서 정의된 API를 구현하는 사용자 에이전트를 의미합니다.
10. 감사의 글
이 명세에 기여해주신 Steve Block, Michael Giuffrida, Ryan Seys, 그리고 Eric Willigers께 감사드립니다.
또한 부드러운 타이밍 함수 제안에 대한 수식 도움을 준 Michiel "Pomax" Kamermans에게도 감사드립니다. 이 기능은 이후 명세로 연기되었습니다.
방송 애니메이션 제작 과정과 기법을 편집자에게 소개해주신 Southern Star Animation의 친절과 인내에 깊은 감사를 드립니다.
11. 최종 공개 이후 변경사항
2022년 9월 8일 Working Draft 이후 다음과 같은 변경이 이루어졌습니다:
-
재생 속도 설정 절차가 시작 시간 유지와, 비단조 타임라인에서 재생 속도 반전 시 시작 시간 위치를 교환하도록 갱신되었습니다.
-
관련 애니메이션 정의를 분리하여 다른 명세에서 사용할 수 있도록 했습니다.
-
현재 애니메이션 효과 정의를 갱신하여, 비유휴 상태이며 비증가 타임라인에 연결된 효과도 현재로 간주하도록 했습니다.
-
§ 4.6 채움 동작 섹션의 코드 예제를 수정했습니다.
변경 로그에서 더 자세한 변경 내역을 볼 수 있습니다.
부록 A: 기존 속성의 애니메이션 타입
일반적으로 속성의 애니메이션 타입은 정의와 함께 제공됩니다. 하지만 오래되었거나 매우 성숙한 명세에서 정의된 일부 속성에는 애니메이션 타입 정보가 포함되어 있지 않을 수 있습니다. 이러한 모든 속성은 아래 예외를 제외하고 애니메이션 타입이 계산값 기준으로 간주됩니다.
font-weight의 애니메이션
font-weight 속성 값은 level 4 이전에는 다음과 같이 결합됩니다:
-
보간은 100단위의 이산적 단계로 이루어집니다. 보간은 <number>처럼 실수 공간에서 이루어지고, 가장 가까운 100단위로 반올림하여 정수로 변환합니다. 100의 배수 중간값은 양의 무한대 방향으로 반올림됩니다.
-
덧셈은 font-weight 값에 대해 Vresult = Va + Vb로 정의됩니다.
참고: 이 정의는 [CSS-FONTS-4]에서 폐지되었으며, 여기서는 font-weight 값이 100의 배수일 필요가 없습니다. 이 경우 font-weight의 애니메이션 타입은 단순히 계산값 기준이 됩니다.
visibility의 애니메이션
visibility 속성의 경우, visible은 이산적 단계로 보간됩니다. 여기서 p 값이 0~1 사이면 visible에 맵핑되며, 그 외 값은 더 가까운 끝점에 맵핑됩니다; 두 값 모두 visible이 아니면 이산 애니메이션이 사용됩니다.
box-shadow 및 text-shadow의 애니메이션
box-shadow 또는 text-shadow 속성의 애니메이션은 결합 그림자 리스트 절차에 따릅니다:
리스트의 각 그림자(none은 길이 0 리스트로 간주)는 계산값 기준 동작처럼 컴포넌트별로 보간됩니다. 하지만 두 입력 그림자 모두 inset이거나 모두 inset이 아니면, 보간된 그림자도 입력 그림자와 같은 속성을 가져야 합니다. 입력 그림자 쌍 중 하나가 inset이고 다른 하나가 inset이 아니면, 전체 그림자 리스트는 이산 애니메이션을 사용합니다. 그림자 리스트의 길이가 다르면, 짧은 리스트는 끝에 transparent 색상, 모든 길이 0, 그리고 inset 속성이 긴 리스트와 맞는 그림자로 패딩됩니다.
두 그림자 리스트 Va와 Vb의 덧셈은 리스트 연결로 정의되며, Vresult는 Va 확장에 Vb를 연결한 값과 같습니다.
누적은 그림자 리스트에 대해 위 보간 규칙을 따르며, 각 컴포넌트별로 타입에 따라 덧셈을 수행하거나, inset 값이 다르면 이산 애니메이션으로 처리합니다.