웹 애니메이션 모듈 레벨 2

W3C 워킹 드래프트,

이 문서에 대한 추가 정보
이 버전:
https://www.w3.org/TR/2025/WD-web-animations-2-20251120/
최신 공개 버전:
https://www.w3.org/TR/web-animations-2/
에디터스 드래프트:
https://drafts.csswg.org/web-animations-2/
히스토리:
https://www.w3.org/standards/history/web-animations-2/
피드백:
CSSWG 이슈 저장소
명세 내 인라인
에디터:
(초대 전문가)
(구글)
이전 에디터:
(구글)
(구글)
이 명세에 대해 편집 제안:
GitHub 에디터
델타 명세:
참여하기:
GitHub에서 텍스트 수정
Animation at Work 슬랙의 ‘waapi’ 채널에 참여하기
IRC: W3C IRC에서 #webanimations
이슈 추적:
GitHub
테스트 스위트:
https://wpt.fyi/results/web-animations/

요약

이 명세는 웹 페이지 표현의 동기화 및 타이밍 변경에 대한 모델을 정의합니다. 또한 이 명세는 이 모델과 상호작용할 수 있는 애플리케이션 프로그래밍 인터페이스(API)를 정의하며, 앞으로의 명세에서 이러한 기능을 선언적으로 노출하는 방법 또한 정의될 것으로 기대합니다.

CSS는 구조화된 문서(예: HTML, XML 등)의 화면, 인쇄물 등에서의 렌더링을 기술하는 언어입니다.

이 문서의 상태

이 섹션은 이 문서가 출판된 시점에서의 상태를 설명합니다. 현재 W3C 발행물 목록과 이 기술 보고서의 최신 버전은 W3C 표준 및 초안 색인에서 확인하실 수 있습니다.

이 문서는 CSS 워킹 그룹워킹 드래프트(권고 단계 사용)로 발행한 것입니다. 워킹 드래프트로의 발행은 W3C 및 소속 회원들의 승인을 의미하지 않습니다.

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

피드백은 GitHub 이슈 등록(권장, 제목에 “web-animations”를 포함, 예: “[web-animations] …의견 요약…”)을 통해 제출해 주세요. 모든 이슈 및 의견은 아카이브에 저장됩니다. 또는 피드백은 (아카이브됨) 공개 메일링 리스트 www-style@w3.org로도 보낼 수 있습니다.

이 문서는 2025년 8월 18일 W3C 프로세스 문서의 규정을 따릅니다.

이 문서는 W3C 특허 정책에 따라 운영되는 그룹에서 작성한 것입니다. W3C는 그룹 결과물과 관련해 제출된 특허 공개 목록을 유지합니다. 해당 페이지에는 특허 공개 방법도 안내되어 있습니다. 개별적으로 관련 특허에 대해 실질적으로 인지하고 있고, 그 특허가 필수 청구항(Essential Claim)을 포함한다고 생각된다면, W3C 특허 정책 6항을 따라 정보를 공개해야 합니다.

1. 델타 명세

이 문서는 델타 명세로, 현재 Web Animations 1단계 [WEB-ANIMATIONS-1]와의 차이점만을 포함하고 있습니다. 1단계 명세가 완성 단계에 가까워지면, 여기의 추가 내용과 병합되어 완전한 2단계 명세로 작성될 예정입니다.

2. 타이밍 모델

이 절에서는 Web Animations의 타이밍 모델의 동작을 설명하고 정의합니다.

2.1. 타이밍 모델 개요

이 절은 참고용(비규범)입니다.

2.1.1. 계층 구조

이 단계의 명세에는 갱신된 타이밍 계층 구조 다이어그램이 포함되어 있습니다.

A hierarchy of timing nodes
타이밍 노드의 계층 구조. 트리의 각 노드는 상위 노드로부터 시간을 상속받습니다.

다음은 갱신된 설명입니다:

이러한 계층적 구조의 결과로, 복잡한 애니메이션 배열도 전체 단위로 되감기, 예약, 가속화 등 다양한 조작이 가능합니다. 상위 노드에 적용된 조작이 하위 노드에 연쇄적으로 내려가기 때문입니다. 또한 시간을 하나의 출처에서 비롯시키기 때문에 애니메이션들의 동기화를 쉽게 할 수 있습니다.

2.2. 타임라인

추가:

타임라인 지속시간은 타임라인이 현재 시간으로 생성할 수 있는 최대 값을 의미합니다. 이 값은 애니메이션의 대상 효과에 대해 고유 반복 지속시간을 계산할 때 사용됩니다. (효과의 반복 지속시간이 "auto"일 때) 이 값은 효과가 가용 시간 전체를 채우도록 계산됩니다. 단조로운(monotonic) 타임라인에서는 현재 시간에 상한이 없으므로 타임라인 지속시간은 결정되지 않습니다. 비단조적인(예: 스크롤) 타임라인의 경우, 지속시간은 고정 상한을 가집니다. 이때 타임라인은 진행 기반 타임라인이 되며, 타임라인 지속시간은 100%로 정해집니다.

2.3. 애니메이션 프레임

알고리즘 1단계의 주석에 다음 항목을 추가:

2.4. 애니메이션

추가:

진행 기반 타임라인과 연관된 애니메이션 효과는 타이밍 속성들을 비율로 변환해야 합니다. 로 변환하는 방법은 다음과 같습니다:

  1. 반복 지속시간이 auto이면, 다음을 수행한다.

    • 시작 지연종료 지연을 0으로 설정한다. 시간과 비율을 혼합할 수 없기 때문이다.

      Note: 향후 버전에서는 이러한 속성에 백분율 할당이 허용될 수 있으며, 이때 값이 시간일 때만 무시되고 백분율일 때는 무시되지 않습니다.

    그 외의 경우:

    1. total time := 종료 시간

    2. 시작 지연 = specified start delay / total time * timeline duration로 계산한다.

    3. 반복 지속시간 = specified iteration duration / total time * timeline duration로 계산한다.

    4. 종료 지연 = specified end delay / total time * timeline duration로 계산한다.

명시된 타이밍을 정규화하는 절차는 다음과 같습니다:

타임라인 지속시간이 결정되면:

그렇지 않으면:
  1. 시작 지연 = specified start delay

  2. 종료 지연 = specified end delay

  3. 반복 지속시간이 auto이면:

    그 외의 경우:

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

애니메이션의 타임라인 설정 절차는 animation의 타임라인을 new timeline(null일 수 있음)로 지정할 때 아래 단계들을 따른다:

  1. old timeline := animation의 기존 타임라인(있다면).

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

  3. previous play state := animation재생 상태.

  4. previous current time := animation현재 시간.

  5. 아래 조건 중 먼저 해당하는 것으로 previous progress를 설정:

    이전 현재 시간이 미해결이라면:

    previous progress = 미해결로 설정.

    종료 시간이 0이면:

    previous progress = 0으로 설정.

    그 외:

    previous progress = previous current time / end time

  6. old timeline이 null이 아니고 단조 증가가 아니라면 from finite timeline = true.

  7. new timeline이 null이 아니고 단조 증가가 아니라면 to finite timeline = true.

  8. animation타임라인new timeline으로 설정.

  9. 아래 조건 중 최초로 해당하는 분기만 실행:

    to finite timeline이 true이면,
    1. 보류 중인 재생 속도 적용animation에 적용

    2. auto align start time을 true로 설정.

    3. 시작 시간을 미해결로 설정.

    4. 대기 시간을 미해결로 설정.

    5. 이전 재생 상태가 "finished" 또는 "running"이면

      1. 보류 중 재생 태스크 예약

    6. 이전 재생 상태가 "paused"이고 previous progress가 해결되었다면:

      1. 대기 시간 = previous progress * end time

    이 단계는, 대기-중(pause-pending) 애니메이션이 시작 시간이 해결된 상태라도 previous progress가 전환 후에도 보존됨을 보장합니다.

    from finite timeline이 true이고 previous progress가 해결된 경우,

    현재 시간 설정 절차를 실행하여 previous progress * end time으로 설정합니다.

  10. animation시작 시간해결됨이면, animation대기 시간미해결로 만든다.

    이 단계는 완료 상태가 고정(sticky)되지 않고, 변경된 현재 시간에 따라 재평가되도록 보장합니다.

  11. 애니메이션 완료 상태 갱신 절차를, did seek 플래그/false, synchronously notify 플래그/false로 animation에 대해 수행합니다.

이슈: new timeline이 null이면, 커스텀 효과미해결 반복 진행도로 호출됨을 보장해야 함 (같은 스크립트 실행 컨텍스트에서 후속 변경으로 중복되지 않는 한).

2.4.2. 애니메이션의 대상 효과 설정

보류 중 재생 태스크 재예약 단계 이후에 다음을 추가:

  1. new effectnull이 아니고 new effect상위 그룹이 있으면, 상위 그룹에서 new effect제거한다.

animation연관 효과new effect로 할당하는 단계 이후에, 아래 단계를 추가:
  1. old effectnull이 아니면, old effect포함 하위커스텀 효과가 연관된 모든 효과에 대해 미해결 반복 진행도로 콜백을 큐에 추가한다.

    이것은 완벽하지 않다. old effect가 같은 태스크 내의 다른 애니메이션에 속해 있을 경우 불필요한 콜백이 발생할 수 있다.

    커스텀 효과 호출 시점의 정의는 검토 및 재작성되어야 할 수 있다.

2.4.3. 연관 효과를 기다리기

다음으로 대체:

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

다음 내용으로 교체:

애니메이션은 준비됨 상태가 되는 최초의 순간에, 모든 다음 조건이 충족되어야 합니다:

참고: 애니메이션은 준비 완료 상태가 아니며 start time 또는 hold time이 없을 경우 그렇다. 스크롤 기반 애니메이션의 경우, auto align start time이 true이면 타임라인을 갱신할 때 시작 시간이 결정된다.

2.4.4. CSSNumberish 시간 검증

CSSNumberish 시간 유효성 검사 절차는 time 값을 입력으로 아래 순서에서 최초로 일치하는 조건에 기반하여 동작합니다:

다음 모든 조건이 참이라면:

  • 해당 애니메이션이 진행 기반 타임라인과 연관되어 있으며,

  • time이 percent 단위의 CSSNumeric 값이 아닌 경우:

TypeErrorthrow한다.

false를 반환한다.

다음 모든 조건이 참이라면:

TypeErrorthrow한다.

false를 반환한다.

그 외

true를 반환한다.

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

애니메이션의 현재 시간은 새로운 값으로 설정하여 애니메이션을 이동(seek)할 수 있습니다. 현재 시간 설정 절차는 두 부분으로 정의됩니다.

애니메이션 animation의 현재 시간을 seek time으로 묵시적으로 설정하는 절차는 아래와 같습니다:

  1. seek time미해결(unresolved) 시간값이면, 다음을 수행합니다.

    1. 현재 시간해결됨(resolved)이라면 TypeError를 throw한다.

    2. 이후 단계 중단.

  2. valid seek time := CSSNumberish 시간 유효성 검사 절차를 seek time 입력값으로 실행한 결과.

  3. valid seek time이 false라면, 이 절차를 중단한다.

  4. auto align start time을 false로 설정한다.

  5. 아래 조건에 따라 animation대기 시간(hold time) 혹은 시작 시간(start time)을 갱신한다:

    아래 중 하나라도 참인 경우:

    1. animation대기 시간seek time으로 설정한다.

    그 외,

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

  6. animation에 연관된 타임라인이 없거나 연관 타임라인비활성일 경우, animation시작 시간미해결로 만든다.

    활성 타임라인이 없을 때는 시작 시간 혹은 애니메이션의 현재 시간만 설정 가능함이 보장된다.

  7. animationprevious current time미해결로 만든다.

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

  1. 묵시적으로 현재 시간 설정 절차를 animationseek time으로 실행한다.

  2. animation보류 중 일시정지 태스크가 있으면, 아래 단계로 일시정지를 동기적으로 완료한다:

    1. animation대기 시간seek time으로 설정한다.

    2. 보류 중 재생 속도 적용 절차 실행.

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

    4. 보류 중 일시정지 태스크를 취소한다.

    5. Resolve animationcurrent ready promiseanimation으로 해결한다.

  3. 애니메이션 완료 상태 갱신 절차를, did seek 플래그 true, synchronously notify 플래그 false로 animation에 실행한다.

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

animation animation의 시작 시간을 new start time으로 설정하는 절차는 다음과 같습니다:

  1. valid start time := CSSNumberish 시간 유효성 검사 절차를 new start time으로 실행한 결과.

  2. valid start time이 false라면, 절차 중단.

  3. auto align start time을 false로 설정한다.

  4. timeline time := animation과 연관된 타임라인의 현재 시간값.
    이때, animation에 연관된 타임라인이 없거나 비활성인 경우 timeline time미해결로 둔다.

  5. timeline time미해결이고 new start time해결됨이면, animation대기 시간미해결로 설정한다.

    활성 타임라인이 없을 때는 시작 시간 혹은 애니메이션의 현재 시간만 설정 가능함이 보장됩니다.

  6. previous current time := animation현재 시간.

    Note: 이는 이전 단계 변경이 반영된 현재 시간으로, 이 과정에서 현재 시간미해결이 될 수도 있다.

  7. 보류 중 재생 속도 적용 절차를 animation에 실행한다.

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

  9. animation대기 시간은 아래 조건에 따라 처리한다:

    new start time해결됨이면,

    animation재생 속도가 0이 아니라면, animation대기 시간미해결로 만든다.

    그 외 (new start time미해결인 경우),
    1. animation대기 시간previous current time으로 설정 (이때 previous current time미해결이어도 됨).

  10. animation보류 중 재생 태스크 또는 보류 중 일시정지 태스크가 있다면 해당 태스크를 취소하고, current ready promiseanimation으로 해결한다.

  11. 애니메이션 완료 상태 갱신 절차를, did seek=true, synchronously notify=false로 animation에 대해 실행한다.

2.4.7. 애니메이션 재생

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

Note: auto-rewind 플래그는 이 모델을 기반으로 하지만 되감기 동작이 필요 없는 CSS 애니메이션 [CSS-ANIMATIONS-1] 등 다른 명세에서 사용하기 위함이다.

  1. aborted pause를 불리언 플래그로 두고 animation보류 중 일시정지 태스크가 있으면 true, 그렇지 않으면 false로 한다.

  2. has pending ready promise를 불리언 플래그로 두고 초기값은 false로 한다.

  3. has finite timelineanimation에 연관된 타임라인이 있고 그 타임라인이 단조 증가가 아니라면 true로 한다.

  4. previous current timeanimation현재 시간을 할당한다.

  5. enable seekauto-rewind가 true이고 has finite timeline이 false이면 true, 아니면 false로 초기화한다.

  6. 아래 조건 중 첫 번째로 일치하는 것만 수행한다:

    animation실효 재생 속도 > 0이고, enable seek이 true이며, animation

    • previous current time미해결이거나,

    • previous current time이 0 미만이거나,

    • previous current time효과 종료 시점 이상인 경우,

    animation대기 시간을 0으로 설정한다.

    animation실효 재생 속도 < 0이고, enable seek이 true이면서 animation

    • previous current time미해결이거나,

    • previous current time이 0 이하이거나,

    • previous current time효과 종료 시점을 초과하는 경우,

    효과 종료 시점이 양의 무한대이면,

    InvalidStateError DOMException 예외를 throw하고 이 단계를 중단한다.

    그 외,

    animation대기 시간animation효과 종료 시점으로 설정한다.

    animation실효 재생 속도가 0이고 animation현재 시간미해결이면,

    animation대기 시간을 0으로 설정한다.

  7. has finite timeline이 true이고 previous current time이 미해결이라면:

    • auto align start time 플래그를 true로 설정한다.

    Note: 스타일 갱신 중 CSS 애니메이션에 play가 호출될 경우, animation시작 시간은 레이아웃 이후에만 신뢰성 있게 계산 가능하다. 이 경우 애니메이션은 자동 정렬 시작 시간을 가지며, 진행률을 타임라인 범위에 정렬하도록 시작 시간이 자동으로 조정된다.

  8. animation대기 시간해결됨이면, 시작 시간미해결로 둔다.

  9. animation보류 중 재생 태스크 또는 보류 중 일시정지 태스크가 있다면,

    1. 해당 태스크를 취소한다.

    2. has pending ready promise를 true로 한다.

  10. 다음 조건이 모두 만족된다면:

    이 절차를 중단한다.

  11. has pending ready promise가 false면, animationcurrent ready promise새 Promise로, 해당 Relevant Realm에 생성한다.

  12. animationready가 되면, 아래 단계를 실행하도록 태스크를 예약한다:

    1. animation시작 시간 또는 대기 시간 중 하나는 해결됨임을 보장(Assert)한다.

    2. ready timeanimationready해진 시점의 연관 타임라인시간값으로 둔다.

    3. 아래 조건 중 첫 번째로 일치하는 것을 실행한다:

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

      2. new start timeready time - 대기 시간 / 재생 속도 값을 할당한다. 만약 재생 속도가 0이면 new start time = ready time으로 둔다.

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

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

      animation시작 시간이 해결됨이고, animation보류 중 재생 속도가 있으면,

      1. current time to match(ready time - 시작 시간) × 재생 속도 값을 할당한다.

      2. 보류 중 재생 속도 적용animation에 실행한다.

      3. 재생 속도가 0이면 animation대기 시간current time to match로 둔다.

      4. new start timeready time - current time to match / 재생 속도 값을 할당한다. 재생 속도가 0이면 new start time=ready time.

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

    4. Resolve animationcurrent ready promiseanimation으로 해결한다.

    5. 애니메이션 완료 상태 갱신 절차를 did seek=false, synchronously notify=false로 animation에 대해 실행한다.

      위 두 단계의 순서가 중요하다. 이는 길이가 0인 연관 효과를 가진 애니메이션이 current ready promisecurrent finished promise보다 먼저 해결(resolved)하도록 한다.

    위 태스크가 예약되어 실행 전인 동안, animation보류 중 재생 태스크 상태라 한다. 태스크 실행 중일 경우 animation보류 중 재생 태스크가 없는 것으로 본다.

    만약 UA가 animation이 즉시 ready임을 판단하면, 위 태스크를 마이크로태스크로 예약하여 다음 마이크로태스크 체크포인트에서 실행할 수 있다. 단, 동기적으로 실행해서는 안된다.

    보류 중 재생 태스크를 비동기로 실행해야 한다는 요구는 아래 코드를 구현마다 일관되게 동작하게 한다:

    animation.play();
    animation.ready.then(
      () => { console.log('Playback commenced'); },
      () => { console.log('Playback was canceled'); }
    );
    // 어떤 조건에서 재생이 취소될 수도 있음...
    animation.cancel();
    // "Playback was canceled"가 콘솔에 출력됨
    

    위 코드에서 보류 중 재생 태스크가 동기적으로 실행된다면, current ready promise가 reject되지 않는다.

  13. 애니메이션 완료 상태 갱신 절차를 did seek=false, synchronously notify=false로 animation에 실행한다.

애니메이션 재생커스텀 효과 업데이트용 태스크를 예약하는 절차를 포함해야 한다.

2.4.7.1. 시작 시간 자동 정렬

단조롭지 않은(non-monotonic) 타임라인에 붙은 경우, 애니메이션의 시작 시간은 레이아웃 의존적일 수 있다. 이 경우 레이아웃 이후 타임라인이 갱신되고 나서 시작 시간 계산을 유예한다. 타임라인의 현재 시간을 갱신할 때, 연결된 애니메이션의 시작 시간도 조건에 따라 갱신된다. 자동 정렬 시작 시간 계산 절차는 다음과 같다:

  1. auto-align start time 플래그가 false면 이 절차를 중단한다.

  2. 타임라인이 비활성이면 이 절차를 중단한다.

  3. 재생 상태(play state)가 idle이면 이 절차를 중단한다.

  4. 재생 상태가 paused이고, 대기 시간이 해결됨이라면 이 절차 중단.

  5. start offset애니메이션 부착 범위의 시작에 대응하는 타임라인 시간값을 할당한다. 뷰 타임라인의 경우, cover 범위의 비율로 계산 필요.

  6. end offset애니메이션 부착 범위의 끝에 해당하는 타임라인 시간값을 할당한다. 뷰 타임라인의 경우, cover 범위의 비율로 계산 필요.

  7. 시작 시간실효 재생 속도가 0 이상이면 start offset으로, 아니면 end offset으로 설정한다.

  8. 대기 시간을 해제한다.

2.4.8. 애니메이션 일시 정지

애니메이션 정지 절차에서는 연관 효과 뿐만 아니라 연관 효과의 모든 자손도 참조해야 합니다.

마찬가지로 애니메이션 정지 절차에는 커스텀 효과 갱신을 위한 태스크 예약도 포함돼야 합니다.

seek time 설정에 대한 제약은 단조 타임라인(monotonic timeline)을 사용할 때만 적용하도록 업데이트합니다. 스크롤 기반 애니메이션에서는 애니메이션 범위가 계산될 때까지 hold time 설정이 연기되어야 합니다.

다음을 다음으로 교체:

  1. seek time타임 값으로 두고, 처음에는 미해결로 한다.

  2. has finite timeline을 true로 둔다. animation이 연결된 타임라인이 있고, 그 타임라인이 단조 증가가 아니면 true이다.

  3. animation현재 시간미해결이면, 아래 조건에 따라 동작:

    animation재생 속도가 0 이상이면,

    seek time에 0을 할당한다.

    그 외의 경우,
    연관 효과 종료 지점이 양의 무한대이면,

    InvalidStateError InvalidStateError DOMException 예외를 throw하고 중단한다.

    그 외,

    seek timeanimation연관 효과 종료 지점을 할당한다.

  4. seek time해결됨이면,

    has finite timeline이 true이면,

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

    그 외,

    animation대기 시간seek time으로 설정한다.

를 다음으로 교체:

  1. has finite timeline을 true로 둔다. animation에 연결된 타임라인이 있고, 그 타임라인이 단조 증가가 아니면 true이다.

  2. animation현재 시각(current time)미해결(unresolved)이고 has finite timeline이 false인 경우, 아래 조건 중 처음으로 일치하는 항목에 따라 단계를 수행한다:

    만약 animation재생 속도(playback rate)가 ≥ 0이라면,

    hold time을 0으로 설정한다.

    그 외의 경우,
    만약 associated effect endanimation에 대해 양의 무한대(positive infinity)라면,

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

    그 외의 경우,

    hold timeanimationassociated effect end로 설정한다.

  3. has finite timeline이 true이고, animation현재 시각(current time)미해결(unresolved)인 경우

    • auto align start time 플래그를 true로 설정한다.

를 다음으로 교체:

아래 두 조건이 모두 true일 때 가능한 한 빨리 태스크를 예약한다:

를 다음으로 교체:

아래 모든 조건이 true일 때 가능한 한 빨리 태스크를 예약한다:

Note: auto-align start time 플래그가 true라면 일시정지 대기 중인 애니메이션에도 시작 시간이 필요하다. 시작 시간자동 정렬 시작 시간 계산 절차를 따라 설정된다.

2.4.9. 애니메이션 취소

마지막 단계로 다음을 추가:
  1. animation연관 효과모든 포함 하위 중 연결된 커스텀 효과미해결 반복 진행도와 함께 호출하는 태스크를 큐에 추가한다.

    커스텀 효과 호출 절차는 다듬어져야 한다. 현재는 변경 병합이 가능한 경우에도 너무 자주 호출된다.

2.4.10. 속도 제어

다음 문장을 추가:

애니메이션 효과에도 별도로 동작하는 재생 속도가 존재함에 유의해야 합니다.

2.4.11. 애니메이션 전체 진행도 계산

애니메이션의 overallProgress는 해당 현재 시간연관 효과 종료 지점으로 나눈 값입니다.

테스트
overallProgress애니메이션 animation의 계산법:

아래 중 하나라도 true이면:

animationoverallProgress는 null.

animation연관 효과 종료 지점이 0이면,
animation현재 시간이 음수면,

animationoverallProgress는 0.

그 외,

animationoverallProgress는 1.

animation연관 효과 종료 지점이 무한대라면,

animationoverallProgress는 0.

그 외의 경우,
overallProgress = min(max(현재 시간 / animation연관 효과 종료 지점, 0), 1)

2.5. 애니메이션 효과

다음 텍스트가 추가됩니다:

애니메이션연관 효과(associated effect)는 해당 애니메이션에 직접 연관됨(directly associated) 으로 간주한다.

애니메이션 효과(Animation effects)그룹 효과(group effects)를 사용해 계층적으로 결합할 수 있다(자세한 내용은 § 2.10 그룹화와 동기화 참조). 이러한 계층에서 오직 루트(root) 애니메이션 효과만이 애니메이션에 직접 연관될 수 있다. 만약 애니메이션 효과부모 그룹(parent group)을 가지고 있을 때 해당 효과를 연관 효과애니메이션에 지정하면, 그 애니메이션 효과부모 그룹에서 제거된 후 애니메이션에 연관된다.

애니메이션 효과애니메이션에 연관(associated with an animation)되었다고 한다. 이는 해당 효과가 애니메이션에 직접 연관되어 있거나, 혹은 조상(ancestor) 그룹 효과(group effect) 중에 애니메이션에 직접 연관된 것이 있을 때를 포함한다.

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

이 명세는 두 가지 애니메이션 효과 타입을 정의합니다:

2.5.2. 활성 구간

이 명세 단계에서는 활성 구간의 하한값을 다음과 같이 정의합니다:

활성 구간의 하한값은 애니메이션 효과 시작 시점에 의해 결정되나, 애니메이션 효과start delay에 의해 이동될 수 있다.

다음 다이어그램 또한 애니메이션 효과 시작 시점애니메이션 시작 시점 대신 가리켜야 한다.

종료 지연에 대한 설명은 다음과 같이 갱신됨:

종료 지연도 지정할 수 있으나, 주로 시퀀스 효과처럼 애니메이션을 순차적으로 구성할 때만 의미가 있다.

규범적 설명은 다음과 같이 갱신됨:

활성 구간의 하한값은 효과의 시작 시점start delay의 합이다.

애니메이션 효과시작 시점은 (있다면) 상위 그룹이 효과를 시작하도록 예약한 시점이다. 이는 상속 시간으로 나타낸다.

대부분의 경우(상위 그룹이 없을 때 포함) 시작 시점은 0이다. 유일한 예외는 시퀀스 효과로, 이들의 자식 시작 시점§ 2.10.4.1 시퀀스 효과 자식의 시작 시점에서 설명한 대로 설정된다.

시작 시점 이외에도 애니메이션 효과에는 start delay가 있으며, 이는 시작 시점으로부터의 오프셋이다.

시작 시점상위 그룹이 결정하지만, start delay애니메이션 효과 자체의 속성이다.

활성 구간의 하한값(상속 시간 공간 기준)은 시작 시점start delay의 합이다.

이 정의들은 로컬 시간(§ 2.5.3 로컬 시간 및 상속 시간 참조) 및 활성 시간 계산에도 포함된다.

종료 시점 정의와 관련해,

애니메이션 효과종료 시점은 다음 계산 결과이다: max(시작 시점 + start delay + active duration + end delay, 0).

2.5.3. 로컬 시간과 상속 시간

이 절이 추가되었습니다.

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

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

좌표 공간과 마찬가지로 시간 공간도 중첩될 수 있습니다. 그룹 효과는 일반적으로 상위 부모애니메이션으로부터 받은 시간 값에 변환을 적용한 뒤, 그 변환된 시간 값을 자식에게 넘겨줍니다. 자식 애니메이션 효과는 이러한 변환된 시간 공간 내부에서 동작합니다.

자식은 부모로부터 받은 변환된 시간 값을, 즉 상속 시간에, 자신의 시작 시점을 더해서 자체 로컬 시간 공간을 만듭니다(아래 그림 참조).

Inherited time and local time.
상속 시간과 로컬 시간.
시점 t에서 상속 시간은 2.5입니다.
애니메이션 효과 (a)는 시작 시점이 1이므로, 로컬 시간은 1.5입니다.
애니메이션 효과 (b)는 시작 시점이 1이고, start delay가 1인데, 로컬 시간 역시 1.5가 됩니다. 이는 로컬 시간애니메이션 효과시작 시점만 따르며, start delay는 로컬 시간에 영향을 주지 않기 때문입니다.

애니메이션 효과의 특정 시점에서 상속 시간은 아래 조건 중 첫 번째로 일치하는 것에 따라 결정됩니다:

애니메이션 효과부모 그룹이 있으면,

상속 시간은 부모 그룹의 현재 변환 시간입니다.

애니메이션 효과애니메이션에 직접 연관된 경우,

상속 시간은 애니메이션의 현재 시간입니다.

그 외의 경우,

상속 시간은 미해결(unresolved)입니다.

로컬 시간애니메이션 효과상속 시간에서 해당 시작 시점을 뺀 값입니다. 상속 시간미해결이면, 로컬 시간도 미해결이 됩니다.

2.5.4. 애니메이션 효과 단계와 상태

이 절은 비규범(참고)입니다.

in play 상태의 비규범 설명에는 다음 내용이 포함됩니다:

이는 애니메이션 효과 및 모든 조상활성 단계(active phase)에 있는 경우 발생합니다. 애니메이션 효과in play일 때만 '움직임'이 발생합니다.

어떤 애니메이션 효과active phase에 있지만 in play가 아닐 수도 있습니다. 예를 들어, 어떤 애니메이션 효과부모 그룹에 의해 활성 구간(active interval)이 잘리고, 부모와 자식 모두 동일한 fill mode를 적용하면, 자식 애니메이션 효과active phase 내에서 스냅샷될 뿐 더 이상 in play가 아닐 수 있습니다.

current에 대해서도 다음과 같습니다.

이는 애니메이션 효과in play이거나, before phase에 있거나, 또는 조상 중 하나가 이 조건을 만족해 이 애니메이션 효과가(예: 반복 등으로 인해) 다시 재생될 수 있음을 의미합니다.

규범적 in play 정의엔 다음 조건이 포함됩니다:

  1. 애니메이션 효과부모 그룹에 속하고, 그 애니메이션 효과in play이거나, 아니면 애니메이션에 직접 연관되어 있고, 그 애니메이션이 완료 상태가 아니어야 한다.

아래를 다음으로 교체:

  1. 애니메이션 효과애니메이션에 연관되어 있고, 해당 애니메이션이 완료 상태가 아닐 때.

규범적 current 정의에 다음 조건을 추가합니다:

애니메이션 효과의 단계를 결정할 때 사용하는 목록에 아래 정의들을 추가합니다.

진행 타임라인 경계에 있음

아래 절차에 따라 판단:

  1. 아래 중 하나라도 참이면:

    false를 반환

  2. effective start time애니메이션시작 시간이 해석된 값이라면 그것으로, 아니라면 0으로 둔다.

  3. unlimited current time을 아래 조건에 따라 설정:

    시작 시간이 해석된 경우:

    (timeline time - 시작 시간) × 재생 속도

    그 외

    애니메이션의 현재 시간

  4. effective timeline timeunlimited current time / 애니메이션재생 속도 + effective start time으로 둠

  5. effective timeline progresseffective timeline time / 타임라인 지속시간으로 둠

  6. effective timeline progress가 0 또는 1이면 true, 아니면 false 반환

이 절차는 일시정지된 애니메이션에서 현재 시간을 명시적으로 설정할 경우 완전히 올바르지 않을 수 있습니다. 이로 인해 타임라인의 현재 시간과 애니메이션의 현재 시간 간에 리드/래그가 생길 수 있습니다.

이 절차는 아마 더 단순화될 수 있습니다. 실제로 스크롤 경계에 도달했는지만 파악하면 충분할 수 있습니다. 놀라운 동작을 방지하는 것이 목표라면 타임라인 현재 시간이 0 또는 진행 지속시간인지 확인하는 것 만으로도 충분할 수 있습니다.

아래를 다음으로 교체:

애니메이션 효과가 before phase에 있다고 하려면, 로컬 시간미해결이 아니면서 다음 조건 중 하나 이상을 만족해야 한다:

  1. 로컬 시간before-active boundary time 미만이거나,

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

를 다음으로 교체:

애니메이션 효과가 before phase에 있다고 하려면, 로컬 시간미해결이 아니고, 아래 조건 중 하나 이상을 만족해야 한다:

  1. 로컬 시간before-active boundary time 미만이거나,

  2. 애니메이션 방향이 "backwards"이고 로컬 시간before-active boundary time과 같으면서 진행 타임라인 경계에는 없을 때.

아래를 다음으로 교체:

애니메이션 효과가 after phase에 있다고 하려면, 로컬 시간미해결이 아니고, 다음 조건 중 하나 이상을 만족해야 한다:

  1. 로컬 시간active-after boundary time을 초과하거나,

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

를 다음으로 교체:

애니메이션 효과가 after phase에 있다고 하려면, 로컬 시간미해결이 아니고, 다음 조건 중 하나 이상을 만족해야 한다:

  1. 로컬 시간active-after boundary time을 초과하거나,

  2. 애니메이션 방향이 "forwards"이고 로컬 시간active-after boundary time과 같으면서 진행 타임라인 경계에는 없을 때.

2.5.5. 채우기 모드

이 절은 비규범(참고)입니다.

forwards 채우기 모드의 설명이 아래에서:

애니메이션 효과가 after phase일 때, …

아래로 업데이트됨:

애니메이션 효과가 after phase이거나, active phase인데 조상after phase인 경우, …

backwards 채우기 모드 설명도 아래에서:

애니메이션 효과가 before phase일 때, …

아래로 업데이트됨:

애니메이션 효과가 before phase이거나, active phase인데 조상before phase인 경우, …

both 채우기 모드 설명도 아래에서:

애니메이션 효과 …

아래로 업데이트됨:

애니메이션 효과 또는 조상

(2회 등장).

현재 timing function이 [0, 1] 범위를 벗어난 값을 생성할 경우, 그룹 효과에 적용 시 자식이 반복 추가되거나 fill 모드에 진입하여 예상치 못한 동작이 발생합니다. (개별 효과로 적용하면 정의된 동작대로 외삽이 계속됨).

이를 해결하려면 active time 범위를 넘는 시간값에 대해 외삽하도록 하는 ‘overflow’ fill mode를 새로 도입해야 할 수도 있습니다.

자세한 내용은 2013년 도쿄 F2F 15항(Overflowing fill) 회의록 참고.

2.6. 반복

2.6.1. 반복 구간

다음 내용 이후:

단일 반복의 길이를 반복 지속시간(iteration duration)이라고 한다.

다음 내용 추가:

애니메이션 효과의 최초 반복 지속시간은 단순히 그 효과의 고유 반복 지속시간(intrinsic iteration duration)이다. 고유 반복 지속시간은 아래 조건 중 먼저 일치하는 것으로 계산된다:

애니메이션 효과가 그룹 효과인 경우,

§ 2.10.3 그룹 효과의 고유 반복 지속시간 절차를 따른다.

애니메이션 효과가 시퀀스 효과인 경우,

§ 2.10.4.2 시퀀스 효과의 고유 반복 지속시간 절차를 따른다.

타임라인 지속시간이 미해결이거나 반복 횟수가 0인 경우,

0 반환

그 외의 경우

(100% - start delay - end delay) / 반복 횟수

Note: 현재 start delay와 end delay는 0으로 처리된다. 향후 백분율 단위 지연이 지원되면 변경될 수 있다.

반복 지속시간애니메이션 효과에 대해 작성자가 고유 반복 지속시간과는 다른 값으로 설정할 수도 있다.

2.6.2. 반복 시간 공간

이 절은 비규범(참고)입니다.

이 절의 처음 몇 단락을 아래와 같이 대체:

로컬 시간상속 시간(§ 2.5.3 로컬 시간과 상속 시간 참조)을 설명할 때 이미 다양한 시간 공간을 다루었다. 반복은 또 다른 시간 공간, 즉 반복 시간 공간(iteration time space)을 도입한다.

2.6.3. 구간 타이밍

이 절은 비규범(참고)입니다.

설명은 다음과 같이 갱신됨:

아래 예제에서, 반복 효과의 경우 로컬 시간 1초일 때 반복 시간은 0이다. 시퀀스 효과의 경우 상속 시간 1초에서는 오직 B 효과만 실행 중이며, 겹침이 없다.

그리고 그림도 다음과 같이 갱신됨:

Illustration of end-point exclusive timing.
구간 종단 제외(end-point exclusive) 타이밍 예시. 반복 및 시퀀스 애니메이션 효과 모두 구간 경계에서 겹침이 없다.

2.7. 애니메이션 효과 속도 제어

(이 절이 추가되었습니다.)

애니메이션과 마찬가지로, 애니메이션 효과 역시 재생 속도 매개변수를 가진다. 애니메이션 효과재생 속도로컬 시간으로부터 변환된 시간을 계산할 때 곱해지는 유한 실수이다.

재생 속도애니메이션 효과에 설정할 때와 애니메이션에 재생 속도를 설정할 때의 동작은 다르다. 이 동작은 § 2.8 핵심 애니메이션 효과 계산의 시간 계산에서 정의된다.

이 절은 비규범(참고)입니다.

요약하면 애니메이션 효과의 재생 속도 동작은 다음과 같다:

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

2.8.1. 개요

이 절은 비규범(참고)입니다.

설명을 아래에서:

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

아래로 교체:

Web Animations 타이밍 모델의 핵심은 상속 시간(inherited time) 값을 받아 반복 진행도(iteration progress)로 변환하는 과정이다.

애니메이션 효과의 재생 속도를 반영한 다이어그램으로 갱신:

Calculation of the active duration.
활성 지속시간(active duration)의 계산은 반복 지속시간반복 횟수를 곱하고, 다시 재생 속도로 나누어 수행된다.

갱신:

활성 지속시간(active duration)을 확정한 뒤, 애니메이션 효과로컬 시간변환된 진행도(transformed progress)(반복 진행도)로 변환하는 과정은 아래와 같다.

아래로 교체:

활성 지속시간(active duration)을 확정한 뒤, 애니메이션 효과상속 시간변환된 진행도(transformed progress)(반복 진행도)로 변환하는 과정은 아래와 같다.

시간 계산 다이어그램도 아래와 같이 갱신:

An overview of timing model calculations.
타이밍 모델 계산 개요.
(1) 상속 시간시작 시점 을 더해 로컬 시간으로 변환된다.
(2) 로컬 시간start delay를 반영해 활성 시간으로 변환된다.
(3) 활성 시간반복 지속시간으로 나눠지고, iteration start재생 속도 property가 계산에 포함되며, overall progress를 구한다.
(4) overall progress가 반복 내 offset( simple iteration progress )로 변환된다.
(5) simple iteration progress방향성 진행도(directed progress)로 변환되며, 여기에는 playback direction이 반영된다.
(6) 마지막으로 타이밍 함수가 방향성 진행도에 적용되어 변환 진행도를 산출한다.

갱신:

첫 단계인 로컬 시간의 계산법은 Local time에서 설명되어 있다.

아래로 교체:

첫 단계인 로컬 시간의 계산법은 § 2.5.3 로컬 시간과 상속 시간 에서 설명되어 있다.

2.8.2. 활성 지속시간 계산

아래로 업데이트됨:

활성 지속시간(active duration)을 계산하기 위해, 먼저 반복 지속시간(repeated duration)을 다음과 같이 정의한다:

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

반복 지속시간 또는 반복 횟수 중 하나라도 0이면 반복 지속시간은 0이다.

IEEE 754-2008에 따르면 무한대 × 0 결과가 정의되어 있지 않기 때문에, 이 보정이 필요하다.

활성 지속시간은 다음 단계에 따라 계산된다:

  1. 재생 속도가 0이면, Infinity를 반환한다.

  2. 그 외의 경우, 반복 지속시간 / abs(재생 속도) 를 반환한다.

2.8.3. 로컬 시간 변환

2.8.3.1. 활성 시간 계산

활성 시간(active time) 정의의 조건에 부모 그룹(parent group) 관련 내용을 추가:

하지만 활성 시간은 애니메이션 효과가 출력을 내야 하는 상황에만 정의되며, 이는 fill mode, 단계(phase) 및(있다면) 부모 그룹의 단계에 따라 결정된다:

각 단계에 대한 추가 정의는 아래와 같음:

애니메이션 효과가 before phase에 있으면,

결과는 아래 조건 중 처음으로 성립하는 것에 따른다:

부모 그룹이 있고, 그 부모가 after phase

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

애니메이션 효과가 active phase에 있으면,

결과는 아래 조건 중 우선 일치하는 것에 따름:

부모 그룹이 있고, 그 부모가 before phase이고, 이 효과의 fill modenone 또는 forwards인 경우

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

부모 그룹이 있고, 그 부모가 after phase이고, 이 효과의 fill modenone 또는 backwards인 경우

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

그 외

로컬 시간 - start delay

애니메이션 효과가 after phase에 있으면,

결과는 아래 조건 중 우선 일치하는 것에 따름:

부모 그룹이 있고, 그 부모가 before phase인 경우

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

그 외(로컬 시간미해결인 경우),

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

2.8.3.2. 전체 진행도 계산

전체 진행도 정의에서 “그 외(Otherwise)” 분기의 initial progress 정의를 다음과 같이 갱신:

그 외(Otherwise),

아래 조건 중 가장 먼저 일치하는 것으로 overall progress를 계산한다:

재생 속도가 0 미만이면,

overall progress = (활성 시간 - 활성 지속시간) × 재생 속도 / 반복 지속시간

재생 속도가 0이면,

overall progress는 0이다.

그 외의 경우,

overall progress = (활성 시간 × 재생 속도) / 반복 지속시간

2.9. 시간 변환

현재 타이밍 함수그룹 효과에 제한 없이 허용되어 있습니다. 이는 구현과 fill 모드 동작의 복잡성에 대한 우려를 낳았습니다. 결과적으로, 그룹 효과에서 전체 타이밍 함수 허용은 위험(at risk) 상태로 간주됩니다.

대안으로는, 그룹 효과에서의 타이밍 함수를 선형 타이밍 함수만으로 제한하거나, "간단한" 타이밍 함수의 집합(복잡한 함수의 일부 문제를 완화하는 특성을 가진 함수들)으로 제한하는 것이 있습니다.

관련 논의는 2013년 8월 논의 2항 참고.

2.9.1. 변환된 진행도 계산

before flag를 효과의 재생 속도를 반영해서 계산하도록 두 번째 단계를 교체:

  1. current directionforwards이거나, 재생 속도가 0 이상인 경우(둘 다 만족할 때는 제외), going forwards를 true로, 그렇지 않으면 false로 한다.

2.9.2. 변환된 시간 계산

(이 절이 추가됨.)

애니메이션 효과의 변환된 시간(transformed time)은 단순히 변환된 진행도반복 지속시간을 곱한 값이다.

변환된 진행도미해결이면, 변환된 시간미해결이다.

변환된 진행도가 0이고 반복 지속시간이 무한대이면, 변환된 시간은 0이다.

2.10. 그룹화 및 동기화

이 절은 비규범(참고)입니다.

애니메이션 효과의 타이밍 속성을 개별로 지정할 수도 있지만, 여러 애니메이션 효과를 동일한 타이밍 속성으로 동기화해 시간적 관계를 유지하는 것이 유용할 때가 많습니다. 이를 위해 그룹 효과를 사용합니다.

간단한 예시가 아래에 나와 있습니다.

Using groups to share common timing properties.
그룹으로 공통 타이밍 속성 공유.
(a) 각 애니메이션에 5초 지연을 별도로 지정.
(b) 그룹에 지연을 지정하여 동일 효과를 만듦.

그룹 효과애니메이션에 직접 연관된 경우, 해당 애니메이션 효과에 대해 그룹 효과 단위로 탐색, 일시정지, 정지 등이 가능하다.

그룹 효과애니메이션 효과의 한 종류로, 0개 이상의 애니메이션 효과(자식 효과)를 순서 배열로 가진다.

특정 시점에서, 애니메이션 효과는 최대 하나의 그룹 효과자식 효과(부모 그룹)이 될 수 있다. 부모 그룹은 해당 애니메이션 효과와 같은 효과가 될 수 없다.

그룹 효과를 중첩함으로써 계층적 트리 구조를 만들 수 있다. 이런 구조에 사용되는 용어는 [DOM]에서 정의한다:

Note: 애니메이션 효과에 위 용어를 적용할 때, 부모는 오직 부모 그룹만을 의미하며, 애니메이션(animation)은 해당 애니메이션 효과직접 연관되어 있더라도 부모에 포함되지 않으며, 개념적으로 시간의 부모 역할만 한다.

자식 효과와 그 부모 그룹 간의 시간적 관계는 상속 시간(§ 2.5.3 참조) 정의에 포함된다.

2.10.1. 그룹 시간과 자식 시간의 관계

이 절은 비규범(참고)입니다.

그룹 효과의 자식들 타이밍은 그룹 타이밍을 기반으로 한다. 즉, 자식의 시간은 부모의 변환된 시간을 기반으로 한다. 반복의 경우, 자식들은 부모 반복 내 안에서 동작하게 되며, 그룹 반복이 일어나면 자식들도 전체 반복 형태로 동작하게 된다.

예를 들어 그룹 효과반복 횟수가 2라면, 자식들도 그룹의 반복 내에서 번갈아 2번씩 재생된다.

The effect of multiple iterations on the children of a group.
그룹 효과의 자식들은 타이밍을 그룹의 변환 시간으로 평가하므로, 그룹이 반복되면 자식도 반복된다.

이 경우에도 자식 애니메이션 효과하나의 활성 구간만을 갖지만, 부모의 타이밍에 의해 활성 구간이 2회 재생되는 효과가 있다.

그룹 자식에도 반복 횟수와 그룹에도 반복 횟수를 지정하면, 마치 그룹 반복 횟수와 자식 반복 횟수를 곱한 것처럼 된다.

Iteration counts are multiplicative.
반복 횟수가 2인 그룹 효과와 자식 중 하나에 반복 횟수 3을 주면, 해당 자식은 6번 실행된다.

자식들이 부모 그룹 효과변환된 시간을 기준 삼기 때문에, 그룹의 활성 구간 밖에서는 애니메이션이 실행되지 않는다. 이는 그룹의 변환 시간활성 구간 밖에서는 변하지 않기 때문이고, 이로써 그룹이 자식의 재생을 클립(clipping)하는 것이 가능해진다.

Groups clip the active interval of contained children.
첫 번째 예에서는 애니메이션 효과가 음수 지연과 무한 반복 횟수를 가짐.
그러나 동일한 애니메이션 효과를 반복 지속시간이 지정된 그룹 효과에 배치하면, 그룹이 자식 애니메이션 효과활성 구간을 클립(clip)하게 된다.

그룹 효과의 자식들이 부모 그룹의 변환된 시간을 기준 삼는 것에는 다음과 같은 추가 효과가 있다:

2.10.2. 그룹 효과 자식의 시작 시간

그룹 효과자식 효과시작 시점은 0이다.

특정 그룹 효과 유형에 따라 이 정의를 오버라이드하여 다른 동기화 방식을 제공할 수 있다.

2.10.3. 그룹 효과의 고유 반복 지속시간

그룹 효과고유 반복 지속시간은 가장 마지막 자식 효과활성 구간이 종료되는 시간에 기반한다. 자식 효과 개수에 따라 아래와 같이 결정한다.

그룹에 자식 효과가 하나도 없는 경우,

고유 반복 지속시간은 0이다.

그 외의 경우,
  1. 그룹의 각 자식 효과종료 시점을 계산하여, 그 중 최대값을 maximum end time이라 한다. 종료 시점은 시간 또는(진행 기반 타임라인의 경우) 퍼센트 값일 수 있다. 시간과 퍼센트가 섞이면, 가장 큰 시간 값이 100%에 해당하는 것으로 본다.

  2. 고유 반복 지속시간max(0, maximum end time)의 결과이다.

고유 반복 지속시간 정의는 특정 그룹 효과 타입별로 오버라이드될 수 있다.

2.10.4. 시퀀스 효과

이 절은 비규범(참고)입니다.

특정 그룹 효과는 자식들을 동기화하는 다양한 방법을 제공할 수 있습니다. 이 명세는 그룹 효과의 한 추가 타입으로 시퀀스 효과를 정의합니다. 시퀀스 효과는 자식의 시작 시점을 조정하여 순차적으로 한 번에 하나씩 실행되도록 배치합니다.

아래 예시에서 두 가지 배치를 비교할 수 있습니다:

Group effects and sequence effects.
그룹 효과와 시퀀스 효과.
(a)는 자식들이 동시에 실행되는 일반적인 그룹 효과입니다.
(b)는 자식이 차례로 실행되는 시퀀스 효과입니다.

그룹 효과 안에 다른 그룹 효과를 넣을 수도 있으므로, 다양한 그룹을 조합하여 복합 동기화가 가능합니다(아래 예시 참고).

Nesting of group effects.
시퀀스 효과가 일반 그룹 효과를 자식으로 포함.
그룹 효과는 먼저 실행 중인 시퀀스 효과 자식이 끝날 때까지 기다리며, 이후 그룹 효과의 자식들은 동시에 실행된다. 이들이 종료되면 시퀀스 효과의 다음 자식이 실행된다.

시퀀스 효과그룹 효과의 한 종류로, 자식 효과들이 그룹 내 순서대로 차례로 재생되도록 예약한다. 이 시퀀싱은 그룹 내 각 자식 효과시작 시점을 조정하여 이루어진다.

2.10.4.1. 시퀀스 효과 자식의 시작 시간

시퀀스 효과자식 효과시작 시점은 해당 자식의 이전 형제종료 시점이다. 자식에게 이전 형제가 없다면 시작 시간은 0이다.

활성 지속시간 이 양의 무한대인 경우, 종료 시점 및 그 다음 자식의 시작 시점 계산은 IEEE 754-2008에서 정의한 일반 규칙을 따른다. 따라서 시퀀스 효과의 어느 자식이라도 활성 지속시간이 무한대이면, 시퀀스상 이후에 오는 자식들은 실행되지 않는다.

마찬가지로, 위 정의는 시작 시점을 양수로 제한하지 않으므로, 그룹의 앞선 자식에 음수 start delay가 있을 경우, 어떤 자식은 자기 활성 구간이 그룹의 시작 시점 전에 끝나서 실행되지 않을 수 있다.

이 절은 비규범(참고)입니다.

활성 구간의 시작 시점은 애니메이션 효과시작 시점 start delay의 합으로 결정되기 때문에, 시퀀스 효과 자식들의 활성 구간은 반드시 엄밀히 순차적일 필요 없이, start delay를 적절히 지정하면 앞당기거나 늦출 수 있다(아래 그림 참고).

Using negative start delays to overlap children of seq
        groups
시퀀스 효과 자식의 start delay를 조정해, 구간을 겹치게(음수 지연) 하거나 띄워서(양수 지연) 배치하는 예시.

음수 start delay를 사용하면, 두 자식의 활성 구간이 겹치도록 할 수 있다. start delay는 그룹 내 후속 자식의 시작 시점에도 영향을 준다는 점에 주의해야 한다.

2.10.4.2. 시퀀스 효과의 고유 반복 지속시간

시퀀스 효과고유 반복 지속시간은, 그룹의 자식 뒤에 가상 자식 효과를 덧붙였을 때 그 시작 시점과 같으며, 그 계산은 § 2.10.4.1 시퀀스 효과 자식의 시작 시간 정의를 따른다. 단 이 값이 음수일 경우 고유 반복 지속시간은 0이다.

따라서 시퀀스 효과자식 효과가 하나도 없으면, 고유 반복 지속시간은 0이 된다.

3. 애니메이션 모델

3.1. 애니메이션 타입

3.1.1. 애니메이션 불가

애니메이션 대상 속성이 애니메이션 불가일 때 효과 설명을 다음으로 갱신:

애니메이션 효과애니메이션 불가 속성을 대상으로 할 때에도 애니메이션 효과는 여전히 시퀀스 효과 내에서의 시간 점유, 애니메이션current finished promise 이행 지연 등 통상적인 동작을 그대로 가진다.

3.2. 키프레임 효과

3.2.1. 키프레임 효과의 값

키프레임 효과대상 속성으로 참조하는 단일 속성의 효과 값을 계산하는 과정에서, 키프레임 효과 합성 모드 적용 이후 다음 단계를 삽입:

  1. interval endpoints 내 각 keyframe에 대해:

    1. (web-animations-1과 동일)

    2. 해당 키프레임 효과iteration composite operationaccumulate일 경우, current iteration 횟수만큼 다음 단계를 반복:

      • keyframetarget property 속성 값을, property-specific keyframes의 마지막 키프레임 속성값(Va)과 keyframe의 값(Vb)을 누적(accumulation procedure) 규칙에 따라 합성한 값으로 치환한다.

      Note: 인자 순서가 중요하다. 대상 속성의 애니메이션 타입에 대해 누적/가산 규칙이 없으면, 기본값은 Vb를 반환한다. 누적 불가능한 속성의 반복 합성 결과는 keyframe의 대상 속성 초기값(Vb)이어야 하므로, 위 단계에서 Vb로 지정한다.

3.3. 효과 결합

3.3.1. 효과 스택

효과 정렬 절차에 다음 단계 추가:

  1. AB트리 순서로 정렬한다. (이 단계까지 오면 A, B는 반드시 동일 애니메이션의 효과여야 하며, 그렇지 않은 경우 이전 단계에서 이미 정렬이 끝난다.)

효과 정렬 시 적용되는 "animation effect의 연관 애니메이션" 정의를, 그룹 효과도 올바르게 처리하도록 본 명세 단계에서 도입된 애니메이션과의 연관 정의로 대체해야 함.

3.4. 효과 누적

효과 값(effect value)간의 합성(Web Animations § 5.4.4 Effect composition 참조)에서와 비슷하게, 반복 합성 동작(iteration composite operation) 은 동일 키프레임 효과의 반복간 값을 어떻게 결합할지 결정한다.

이 명세에서는 두 가지 반복 합성 동작을 정의한다:

replace

각 반복은 이전 반복과 무관하게 계산된다.

accumulate

반복이 진행되면서 애니메이션은 각 반복 마지막 값을 누적(accumulation procedure)한다.

반복 합성 동작 적용은 효과 값(effect value) 계산(§ 3.2.1 키프레임 효과 값 참조)에 포함된다.

3.5. 커스텀 효과

(이 절이 추가되었습니다.)

이 기능 전체는 재검토가 필요하다. 현 구상은 커스텀 효과 대신 모든 애니메이션 효과onupdate 콜백을 두는 쪽이다. 이러면, 예를 들어 기존 효과에 시간별 로깅이나 특정 시점별 추가 동작만 결합할 때 굳이 상위 그룹을 만들 필요 없이 쉽게 구현 가능하다.

이 절은 비규범적입니다

일부 상황에서는 Web Animations가 제공하는 애니메이션 효과가 충분하지 않을 수 있습니다. 예를 들어, 여기서 정의하는 애니메이션 효과는 특정 CSS 속성만을 대상으로 할 수 있습니다. 따라서 문서 콘텐츠에 영향을 주지 않으면서 뷰포트를 부드럽게 확대하기 위해 SVG 요소의 currentScale 속성을 조정하는 것은 불가능합니다.

이처럼 제공되는 애니메이션 효과가 필요한 기능을 지원하지 않을 경우, 스크립트로 정의된 효과를 사용할 수 있습니다. 이러한 커스텀 효과는 타이밍 모델로부터 반복 진행도현재 반복을 받아, 지정된 시각에 해당하는 효과를 생성할 책임이 있습니다.

스크립트로 정의된 효과를 사용하면, 기본적으로 애니메이션 할 수 없는 속성이나 프로퍼티뿐 아니라 스크립트로 접근 가능한 모든 것, 예를 들면 오디오를 생성하거나 진동을 일으키는 것도 애니메이트할 수 있습니다.

예를 들어 커스텀 효과를 사용해 canvas 요소에 그림을 그리면, CSS나 SVG만으로는 만들기 어려운 패턴의 복잡한 애니메이션 효과도 만들 수 있습니다. 스크립트 기반 애니메이션의 타이밍 제어와 비교해, 이 방식은 애니메이션이 프레임 레이트에 독립적이며 일시 정지, 되감기, 타이밍 효과로 이징, 가속, 다른 애니메이션 동기화, 그리고 추가적인 프로그래밍 없이도 다른 모든 Web Animations와 동일하게 제어될 수 있도록 보장합니다.

커스텀 효과(custom effect)는 타이밍 정보를 전달받는 저자 정의 콜백 프로그래밍이고, update animations and send events 절차에서 전달된다.

타이밍 속성 변경 시에도 호출해야 한다는 점이 맞는가?

3.5.1. 커스텀 효과 샘플링

커스텀 효과(Custom effects)는 아래 기준에 따라 해당 커스텀 효과를 참조하는 애니메이션 효과마다 애니메이션 업데이트 및 이벤트 전송(update animations and send events) 절차(이하 업데이트라고 함)가 수행될 때 호출됩니다.

  1. 이전 업데이트에서, 커스텀 효과를 참조하는 애니메이션 효과가 다음 조건을 만족했다면:

    콜백을 호출하되, 미해결(unresolved) 반복 진행(iteration progress)과 이전 업데이트의 대상 요소를 파라미터로 넘깁니다.

  2. 현재 대상 요소(target element)에 대해, 아래 조건 중 처음으로 일치하는 조건 기준으로 콜백을 호출합니다:

    만약 커스텀 효과를 참조하는 애니메이션 효과가 현재 효과 적용 상태(in effect)가 아니지만, 이전 업데이트에서는 효과 적용 상태였다면,

    콜백에 미해결(unresolved) 반복 진행(iteration progress)과 현재 대상 요소를 파라미터로 넘겨 콜백을 호출합니다.

    그렇지 않고, 커스텀 효과를 참조하는 애니메이션 효과가 다음 중 하나라면:

    참조하고 있는 애니메이션 효과의 현재 반복 진행(iteration progress)대상 요소를 파라미터로 콜백을 호출합니다.

애니메이션 트리 내 특정 지점에서 액션을 트리거해야 하는 경우가 있을 수 있습니다. 대부분은 step-start 이징이 적용된 커스텀 효과를 넣어 해당 구간에서 액션을 수행할 수 있습니다. 그러나 이렇게 하면 컨텐츠에 추가적인 레이아웃 요구사항이 생겨 부담이 커질 수 있습니다.

현재 검토 중인 대안:

  • 0폭(zero-width) 커스텀 효과에 대해 콜백을 호출해야 하는 추가 조건을 정의할 수 있습니다. 예를 들어, 무한 정밀도 기준으로 이전·현재 업데이트 시각 사이에 커스텀 효과와 정렬되는 순간이 있었다면 콜백이 호출되도록 요구할 수 있습니다.

  • 커스텀 효과에 특수 호출 조건을 추가하는 대신, 위에서 설명한 0폭(zero-width) 커스텀 효과 역할만 하는 새로운 유형의 애니메이션 효과(Trigger)를 도입할 수 있습니다. 트리거는 콜백 함수만 생성자에 전달받고, target이나 timing은 필수 아님, 재생 방향(playback direction) 등 콜백의 호출 조건도 추가로 지정 가능하게 할 수 있습니다.

3.5.2. 커스텀 효과의 실행 순서

커스텀 효과애니메이션 효과와 달리 하나의 대상 속성에만 한정되지 않으므로, 실행 순서를 평가하는 방법이 애니메이션 효과와 다릅니다.

커스텀 효과는 모든 애니메이션 효과가 완료되어 결과를 타깃에 적용한 이후에 실행됩니다(결과 합성 적용 참조).

이 부분은 더 명확히 정의되어야 함. 스타일이 flush 되는가? 아마도 그러해야 할 것임. 스크립트 기반 애니메이션 효과 실행 기간 동안 reflow를 중단하고, 이후 한 번만 reflow를 실행할 수 있을까?

커스텀 효과 집합 내부에서의 실행 순서는 [[#the-effect-stack]]에서 정의된 애니메이션 효과의 실행 순서와 동일합니다. 앞에서 정렬된 항목이 뒤의 항목보다 먼저 실행됩니다.

3.6. 애니메이션 트리거

3.6.1. 개요

애니메이션 트리거는 연관된 애니메이션의 재생을 시간 기반 애니메이션에 대해 제어하는 데 사용됩니다. 애니메이션과 마찬가지로 애니메이션 트리거타임라인에 연관되며, 부착 구간(attachment range)에 연결됩니다.

트리거가 스크롤 기반 애니메이션에 어떤 영향을 미쳐야 하는가?

3.6.2. 애니메이션 트리거의 내부 상태

애니메이션 트리거 trigger에는, 처음에는 false인 내부 불리언 did trigger 플래그와, 아래 값 중 하나를 가질 수 있는 내부 state가 있습니다:

idle
연관된 애니메이션 효과 animationbefore 단계에 머물러 있고, 현재 시간은 0입니다.
primary
이 값으로 전환되면 primary 동작 타입이 type에 따라 animation에 적용됩니다.
inverse
이 값으로 전환되면 inverse 동작 타입이 type에 따라 animation에 적용됩니다.

statedid trigger의 값은 아래에 정의된 애니메이션 트리거 상태 업데이트 절차에서 갱신됩니다.

idle 상태 명세에 대한 공식 결론이 필요한가?

3.6.3. 애니메이션 트리거 동작

애니메이션 트리거트리거 동작을 가지고 있으며, 이는 did trigger, state와 함께 연관된 트리거애니메이션 재생에 미치는 효과를 결정합니다.

애니메이션 효과애니메이션 트리거idle 상태로 연결되어 있을 때, 해당 효과는 before 단계에 머물러 있고, 현재 시간은 0을 유지합니다. 트리거의 did trigger 플래그나 state 값에 상관없이 마찬가지입니다. 그 외의 경우 아래와 같이 behavior 값별로 재생에 미치는 영향이 있습니다:

once
stateprimary인 경우,

연관된 애니메이션을 트리거한다.

그 외의 경우,

트리거는 아무 효과도 없다.

repeat
stateprimary인 경우,

연관된 애니메이션을 트리거한다.

stateinverse인 경우,

연관된 애니메이션 효과before 단계로 그리고 연관 애니메이션시작 시간을 0으로 리셋한다.

alternate
stateprimary이고 did trigger가 false인 경우,

연관된 애니메이션을 트리거한다.

stateprimary이고 did trigger가 true인 경우,

연관된 애니메이션을 역방향(reverse) 재생시킨다.

stateinverse인 경우

연관된 애니메이션을 역방향(reverse) 재생시킨다.

state
stateprimary인 경우

연관된 애니메이션을 트리거하거나 재개한다.

stateinverse인 경우

연관된 애니메이션을 일시정지시킨다.

"primary/inverse" 동작 타입에 대한 정확한 정의가 필요한가?

3.6.4. 애니메이션 트리거 활성 구간

애니메이션 트리거활성 구간(active interval)을 하나만 정의합니다. 이 구간은 트리거의 stateprimary인 동안 타임라인 진행의 구간입니다.

3.6.5. 애니메이션 트리거 범위

애니메이션 트리거는 두 개의 범위(range)를가지며, 기본 범위(default range)종료 범위(exit range)가 있습니다. 종료 범위기본 범위를 치환하며, 활성 구간을 확장합니다.

종료 범위의 경계가 기본 범위의 경계와 같거나 더 크기만 가능하다고 명세에 박을 필요가 있을까?

가장 최근의 state state에 따라 활성 구간은 다음과 같이 정의합니다:

stateprimary일 때,

interval종료 범위(exit range)로 지정합니다.

그 외의 경우,

interval기본 범위(default range)입니다.

3.6.6. 애니메이션에 트리거 설정

애니메이션에 트리거 설정 animationnew trigger로 설정하는 절차는 다음과 같다:
  1. old triggeranimation의 현재 애니메이션 트리거로 둔다(있는 경우).

  2. new triggerold trigger가 동일 객체라면 이 절차 중단.

  3. animation트리거new trigger로 둔다.

  4. new trigger에 대한 애니메이션 트리거 상태 업데이트 절차를 수행한다.

3.6.7. 애니메이션 트리거의 타임라인 설정

애니메이션 트리거의 타임라인 설정 triggernew timeline(null일 수도 있음)으로 설정하는 절차는 다음과 같다:
  1. old timelinetrigger의 현재 timeline 값으로 둔다(있는 경우).

  2. new timelineold timeline이 동일 객체라면 이 절차 중단.

  3. trigger.timeline 값을 new timeline으로 설정한다.

  4. trigger에 대해 애니메이션 트리거 상태 업데이트 절차를 수행한다.

3.6.8. 애니메이션 트리거 상태 업데이트

애니메이션 트리거 상태 업데이트 애니메이션 트리거 trigger의 절차는 다음과 같다:
  1. did triggertrigger의 현재 did trigger 플래그 값으로 둔다.

  2. behaviortrigger트리거 동작으로 둔다.

  3. trigger.state를 아래와 같이 설정한다:

    trigger로컬 시간미해결이면,

    이 절차를 중단한다.

    그 외의 경우,
    behavioronce이고 did trigger가 true인 경우,

    이 절차를 중단한다.

    그 외,
    trigger가 자신의 활성 구간 내에 있으면,
    1. trigger.stateprimary로 설정한다.

    2. trigger.did trigger를 true로 설정한다.

    그 외의 경우,
    did trigger가 true인 경우,

    trigger.stateinverse로 설정한다.

타임라인이 다시 idle 상태로 돌아갈 경우 "did trigger" 플래그가 false로 리셋되는 것이 옳은가?

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

4.1. AnimationTimeline 인터페이스

[Exposed=Window]
partial interface AnimationTimeline {
    readonly attribute CSSNumberish? currentTime;
    readonly attribute CSSNumberish? duration;
    Animation play (optional AnimationEffect? effect = null);
};

currentTime 속성 타입을 업데이트합니다.

currentTime, 타입 CSSNumberish, 읽기 전용, nullable

이 타임라인의 현재 시간을 반환하거나, 이 타임라인이 비활성(inactive)이면 null을 반환합니다. 값은 진행 기반 타임라인의 경우 백분율로, 그렇지 않으면 밀리초 단위의 double로 표현됩니다.

duration, 타입 CSSNumberish, 읽기 전용, nullable

이 타임라인의 지속 시간(duration)을 반환합니다.

테스트
Animation play(optional AnimationEffect? effect = null)

타임라인에 연결된 새 Animation 객체를 생성하며, 해당 객체는 ready 상태가 되는 즉시 재생을 시작합니다.

effect가 지정된 경우, 해당 효과가 새 애니메이션의 연관 효과가 됩니다.

이 메서드는 다른 이름으로 변경되거나 아예 제거될 수 있음(TA G 피드백 참고).

effect가 null일 때의 시작 동작 정의 필요.

Animation 객체는 Animation() 생성자를 통해, 이 AnimationTimeline 객체를 timeline 파라미터로, effecteffect 파라미터로 넘겨 생성합니다.

해당 Animation 객체 생성 직후, auto-rewind 플래그를 true로 하여 새 객체에 대해 애니메이션 재생 절차가 실행됩니다.

effect

새로 만들어지는 Animation 객체에 할당할 연관 효과.

4.2. Animation 인터페이스

Animation 인터페이스의 startTime과 currentTime을 업데이트하고, rangeStart, rangeEnd, overallProgress 속성을 다음과 같이 추가 또는 변경합니다:

[Exposed=Window]
partial interface Animation {
    attribute CSSNumberish?       startTime;
    attribute CSSNumberish?       currentTime;
    attribute AnimationTrigger?   trigger;
    attribute (TimelineRangeOffset or CSSNumericValue or CSSKeywordValue or DOMString) rangeStart;
    attribute (TimelineRangeOffset or CSSNumericValue or CSSKeywordValue or DOMString) rangeEnd;
    readonly attribute double? overallProgress;
};

속성 설명은 다음과 같이 추가 또는 변경하세요:

startTime, 타입 CSSNumberish, nullable

설명 변경:

이 애니메이션의 시작 시간. 진행 기반 타임라인과 연관된 경우, 시작 시간은 백분율 단위의 CSSNumericValue 로 반환되어야 합니다. 그 외에는 시작 시간을 밀리초 단위의 double 값으로 반환합니다. 이 속성을 설정하면 set the start time 절차를 따라 새 값으로 업데이트합니다.

currentTime, 타입 CSSNumberish, nullable

설명 변경:

이 애니메이션의 현재 시간입니다. 진행 기반 타임라인과 연관된 경우 현재 시간을 백분율 단위의 CSSNumericValue로 반환해야 합니다. 그 외에는 현재 시간을 밀리초 단위의 double 값으로 반환합니다. 이 속성을 설정하면 set the current time 절차를 따라 새 값으로 설정합니다.

다음도 추가:

rangeStart, 타입 (TimelineRangeOffset or CSSNumericValue or CSSKeywordValue or DOMString)

애니메이션애니메이션 부착 범위의 시작 지점을 지정합니다. 이 속성 설정은 KeyframeAnimationOption rangeStart와 동일한 규칙을 따릅니다. 읽을 때 값은 TimelineRangeOffset 또는 DOMString "normal"입니다.

rangeEnd, 타입 (TimelineRangeOffset or CSSNumericValue or CSSKeywordValue or DOMString)

애니메이션애니메이션 부착 범위의 끝 지점을 지정합니다. 이 속성 설정은 KeyframeAnimationOption rangeEnd와 동일한 규칙을 따릅니다. 읽을 때 값은 TimelineRangeOffset 또는 DOMString "normal"입니다.

overallProgress, 타입 double, 읽기 전용, nullable

overallProgress 값을, 애니메이션연관 효과 종료점 대비 비율로 제공합니다.

trigger, 타입 AnimationTrigger, nullable

애니메이션에 연관된 애니메이션 트리거 지정. 이 속성 설정은 KeyframeAnimationOption trigger와 동일 규칙을 따릅니다.

4.3. AnimationEffect 인터페이스

[Exposed=Window]
partial interface AnimationEffect {
    // Timing hierarchy
    readonly attribute GroupEffect?     parent;
    readonly attribute AnimationEffect? previousSibling;
    readonly attribute AnimationEffect? nextSibling;

    undefined before (AnimationEffect... effects);
    undefined after (AnimationEffect... effects);
    undefined replace (AnimationEffect... effects);
    undefined remove ();
};
getComputedTiming()

이 객체의 duration 속성 설명에는 timing.duration 값이 auto 문자열이면, 이 속성은 현재 계산된 고유 반복 지속시간 값을 반환해야 하며, 이 값은 효과가 진행 기반 타임라인에 연결된 경우 비율(%)로, 그 외엔 밀리초 단위 double로 표현될 수 있음을 명시해야 합니다.

parent, 타입 GroupEffect, 읽기 전용, nullable

부모 그룹을 반환하거나, 이 애니메이션 효과부모 그룹이 없으면 null을 반환합니다.

이름을 parentGroup으로 해야할까요?

previousSibling, 타입 AnimationEffect, 읽기 전용, nullable

이전 형제 애니메이션 효과를 반환합니다.

nextSibling, 타입 AnimationEffect, 읽기 전용, nullable

다음 형제 애니메이션 효과를 반환합니다.

undefined before (AnimationEffect... effects)

effects를 이 애니메이션 효과 앞에 삽입합니다.

  1. 부모 그룹이 없으면, 이 단계 중단.

  2. effects 중 하나라도 이 애니메이션 효과포함 조상이면, HierarchyRequestError 예외를 throw 하면서 이 단계 중단.

  3. 자식 삽입 절차로 effects를 이 애니메이션 효과 앞에 삽입합니다.

이 정의로 인해 아래와 같은 코드는 금지됩니다. effect가 자기 자신의 포함 조상이기 때문입니다:
effect.before(effect); // throws HierarchyRequestError
undefined after(AnimationEffect... effects)

effects를 이 애니메이션 효과 뒤에 삽입합니다.

  1. 부모 그룹이 없으면, 이 단계 중단.

  2. effects 중 하나라도 이 애니메이션 효과포함 조상이면, HierarchyRequestError 예외를 throw 하면서 중단.

  3. reference childeffects 없는 다음 형제(참조 자식)로 설정합니다.

  4. 자식 삽입 절차로 effectsreference child 앞에 삽입합니다.

undefined replace(AnimationEffect... effects)

AnimationEffecteffects로 대체합니다.

  1. 부모 그룹이 없으면, 이 단계 중단.

  2. effects 중 하나라도 부모 그룹의 포함 조상이면, HierarchyRequestError 예외를 throw 하면서 중단.

  3. reference childeffects 없는 다음 형제(참조 자식)로 설정합니다.

  4. 애니메이션 효과 삭제로 이 애니메이션 효과부모 그룹에서 제거합니다.

  5. 자식 삽입으로 effectsreference child 앞에 삽입합니다.

undefined remove()

이 애니메이션 효과부모 그룹이나 애니메이션에서 제거합니다.

remove() 메서드는 부모 그룹 또는 애니메이션에서 효과를 제거하는데 사용할 수 있습니다. 1단계에서 남겨두고 애니메이션에서만 삭제 처리로 단순화할지 결정이 필요합니다.

4.4. EffectTimingOptionalEffectTiming 딕셔너리

partial dictionary EffectTiming {
    double delay;
    double endDelay;
    double playbackRate = 1.0;
    (unrestricted double or CSSNumericValue or DOMString) duration = "auto";
};

partial dictionary OptionalEffectTiming {
    double playbackRate;
};

참고: 이 명세 버전에서는 duration 속성이 CSSNumericValue로 설정될 수 없습니다. 하지만 getComputedTiming()의 duration 계산 결과로 CSSNumericValue가 반환될 수 있습니다. 앞으로의 명세에서는 단위가 유효한 시간 단위 또는 퍼센트인 CSSNumeric 값으로도 duration 설정이 가능해질 수 있습니다.

delay, 타입 double

설명을 다음과 같이 변경:

지정 시작 지연(specified start delay)로, 이는 애니메이션 효과시작 시점에서 활성 구간 시작까지 밀리초(ms) 단위로 나타낸 값입니다. 지정 시작 지연start delay로 변환되며, 타이밍 표준화(normalize specified timing) 절차를 거쳐 적용됩니다.

endDelay, 타입 double

설명을 다음과 같이 변경:

지정 종료 지연(specified end delay)로, 이는 애니메이션 효과활성 구간이 끝난 후, 예를 들어 시퀀스 효과 등에서, 이어질 애니메이션 효과시작 시점까지의 밀리초를 나타냅니다. 지정 종료 지연end delay로 변환되며, 타이밍 표준화 절차를 거쳐 적용됩니다.

duration, 타입 (unrestricted double or CSSNumericValue or DOMString), 기본값 "auto"

설명을 다음과 같이 변경:

지정 반복 지속시간: 0 이상(양의 무한대 포함) 실제 수로, 애니메이션 효과의 단일 반복에 소요되는 밀리초 단위 시간. 또는 문자열 auto반복 지속시간이 애니메이션 효과의 고유 반복 지속시간을 반영한다는 뜻입니다. 지정 반복 지속시간타이밍 표준화 절차에 따라 반복 지속시간으로 변환됩니다.

playbackRate, 타입 double, 기본값 1.0

애니메이션 효과재생 속도 속성. 시간 변환에 곱해지는 배율로, 로컬 시간을 실제 속도와 다르게 할 수 있습니다.

4.5. AnimationEffect 타이밍 갱신

다음 부분을 치환:

input존재하는 각 멤버를 아래와 같이 effect의 해당 타이밍 속성에 할당:

다음으로 교체:

input존재하는 각 멤버를 아래와 같이 effect의 해당 타이밍 속성에 할당:

다음 추가:

타이밍 표준화(normalize specified timing) 절차를 따르십시오.

스타일 변경으로 인해 타이밍 속성이 갱신될 수도 있습니다. CSS 애니메이션 관련 속성 중 타이밍에 영향을 주는 모든 변경은 다시 타이밍 표준화 절차를 실행해야 합니다.

4.6. ComputedEffectTiming 딕셔너리

partial dictionary ComputedEffectTiming {
    CSSNumberish         startTime;
    CSSNumberish         endTime;
    CSSNumberish         activeDuration;
    CSSNumberish?        localTime;
};
startTime, 타입 CSSNumberish

애니메이션 효과의 시작 시점. 진행 기반 타임라인에 연관된 경우 백분율, 그 외에는 밀리초 단위의 double로 표현합니다.

이는 (있다면) 부모 그룹이 이 자식을 자신의 변환 시간 공간상 언제 실행하도록 예약했는지를 나타내며, 즉 애니메이션 효과상속 시간 공간을 의미합니다.

활성 구간의 시작점은 시작 시점start delay를 더한 값입니다.

endTime, 타입 CSSNumberish

설명은 다음과 같이 변경:

종료 시점애니메이션 효과상속 시간 공간 상에서 나타냅니다. 값은 진행 기반 타임라인에 연관된 경우 백분율, 그 외에는 밀리초 단위의 double입니다. 이것은 해당 애니메이션 효과 활성 구간의 끝에 end delay를 더한 값과 같습니다.

activeDuration, 타입 CSSNumberish

설명은 다음과 같이 변경:

활성 지속시간(active duration)을, 진행 기반 타임라인에 연결된 효과라면 퍼센트로, 아니면 밀리초 double로 제공.

localTime, 타입 CSSNumberish, nullable

두 번째 단락을 다음과 같이 변경:

애니메이션 효과애니메이션에 연관되어 있지 않거나, 또는 부모 그룹효과 중(in effect)이 아닌 경우 null이 됨.

다음 추가:

진행 기반 타임라인에 연관된 효과는 퍼센트로, 아닌 경우 밀리초 double로 값이 표현됩니다.

4.6.1. FillMode 열거형

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

설명을 다음과 같이 변경:

GroupEffect에 적용시 backwards와 forwards 모두 fill, KeyframeEffect에 적용시 fill 없음.

4.7. GroupEffect 인터페이스

(이 절이 추가되었습니다.)

그룹 효과GroupEffect 인터페이스로 표현됩니다.

[Exposed=Window]
interface GroupEffect {
  constructor(sequence<AnimationEffect>? children,
              optional (unrestricted double or EffectTiming) timing = {});

  readonly attribute AnimationNodeList  children;
  readonly attribute AnimationEffect?   firstChild;
  readonly attribute AnimationEffect?   lastChild;
  GroupEffect clone ();

  undefined prepend (AnimationEffect... effects);
  undefined append (AnimationEffect... effects);
};
GroupEffect ()

다음 절차에 따라 새로운 GroupEffect 객체를 생성합니다:

  1. GroupEffect 객체를 group으로 생성합니다.

  2. timing inputtiming타이밍 인수 처리 절차를 적용한 결과로 둡니다.

  3. timing input의 값은 아래 조건 중 처음으로 일치하는 결과:

    optionsEffectTiming 객체인 경우,

    timing inputoptions를 할당한다.

    그 외(optionsdouble인 경우),

    모든 멤버를 기본값으로 하고 durationoptions를 할당한 새 EffectTiming 객체를 timing input에 할당한다.

  4. 애니메이션 효과의 타이밍 속성 갱신 절차를 timing input으로 group에 대해 실행합니다.

    이 과정에서 예외가 발생하면, 예외를 전달하고 절차를 중단합니다.

  5. 자식 삽입 절차로 childrennull 앞에 삽입합니다.

children

이 그룹에 자식으로 추가할 애니메이션 효과 시퀀스입니다.

이 자식들은 append() 메서드와 동일하게 순차적으로 추가됩니다.

timing

새 그룹 효과의 타이밍 속성 또는 반복 지속시간입니다.

children, 타입 AnimationNodeList, 읽기 전용

이 그룹에 포함된 자식 효과들의 리스트입니다.

firstChild, 타입 AnimationEffect, 읽기 전용, nullable

그룹 효과첫 자식을 반환합니다.

lastChild, 타입 AnimationEffect, 읽기 전용, nullable

그룹 효과마지막 자식을 반환합니다.

undefined prepend (AnimationEffect... effects)
  1. effects 중 하나라도 이 애니메이션 효과포함 조상이면, HierarchyRequestError 예외를 throw하고 중단합니다.

  2. 자식 삽입 절차로 effects첫 자식 앞에 삽입합니다.

undefined append (AnimationEffect... effects)
  1. effects 중 하나라도 이 애니메이션 효과포함 조상이면, HierarchyRequestError 예외를 throw하고 중단합니다.

  2. 자식 삽입 절차로 effectsnull 앞에 삽입합니다.

GroupEffect clone ()

다음 절차대로 이 GroupEffect 객체의 깊은 복사본을 생성합니다.

  1. source를 복제 대상 GroupEffect 객체로 둡니다.

  2. cloned timingEffectTiming 객체로 두고, 각 멤버는 source.getTiming()의 동명 속성 값을 할당합니다.

  3. cloned children을 빈 AnimationEffect 객체 시퀀스로 둡니다.

  4. source.children의 각 child에 대해, child.clone() 결과를 cloned children에 추가합니다.

  5. GroupEffect() 생성자를 GroupEffect(cloned children, cloned timing) 파라미터로 호출해, 새 GroupEffect 객체를 반환합니다.

4.7.1. timing 인수 처리

GroupEffect() 또는 SequenceEffect() 생성자에 전달되는 timing 파라미터는 EffectTiming 객체, 반복 지속시간을 나타내는 double, 또는 undefined일 수 있습니다.

아래는 타이밍 인수 처리 절차로, timing을 위의 입력을 EffectTiming 객체로 정규화(normalize)합니다.

timingEffectTiming 객체인 경우,

timing을 반환합니다.

timingdouble인 경우,

모든 멤버를 기본값으로, durationtiming을 할당한 새 EffectTiming 객체를 반환합니다.

그 외(undefined),

모든 멤버가 기본값인 새 EffectTiming 객체를 반환합니다.

4.7.2. 계층 구조 조작 정의

효과 집합 effects에 포함되지 않은 effect의 다음 형제는 다음 절차로 결정합니다:

  1. context effecteffect로 둡니다.

  2. context effect다음 형제null이 아닐 때 다음을 반복:

    1. context effect다음 형제로 갱신.

    2. context effecteffects에 포함되지 않았다면, context effect를 반환하고 종료.

  3. null을 반환한다.

애니메이션 효과 삭제effect부모 그룹 또는 애니메이션에서 아래 조건 중 처음 일치하는 절차를 실행:

effect부모 그룹이 있는 경우,

부모 그룹의 자식 효과 리스트에서 effect를 제거한다.

effect애니메이션에 직접 연관되어 있는 경우,

effect애니메이션과의 연관을 해제한다.

일련의 0개 이상의 애니메이션 효과 effectsparent자식 효과 리스트에서 reference child 앞에 자식 삽입할 때 각 effect에 대해 다음 절차 실행:

  1. effect 삭제effect를 부모에서 제거.

  2. effectparent자식 효과 리스트에서 reference child 앞에 삽입.

4.8. AnimationNodeList 인터페이스

애니메이션 효과의 목록은 AnimationNodeList로 표현될 수 있습니다.

AnimationNodeList 인터페이스는 0 ≤ index < length 범위의 인덱스 속성을 지원합니다.

이 인터페이스가 존재하는 유일한 이유는, 자식 노드에 children 멤버로 접근하는 DOM 인터페이스에 익숙한 저자들에게 친숙한 경험을 제공하기 위해서입니다.

[Exposed=Window]
interface AnimationNodeList {
    readonly attribute unsigned long length;
    getter AnimationEffect? item (unsigned long index);
};
length, 타입 unsigned long, 읽기 전용

목록에 있는 애니메이션 효과 개수입니다.

getter AnimationEffect? item(unsigned long index)

index 위치에 있는 애니메이션 효과를 반환합니다. indexlength보다 크거나 같으면 null을 반환합니다.

4.9. SequenceEffect 인터페이스

시퀀스 효과SequenceEffect 인터페이스로 표현됩니다.

[Exposed=Window]
interface SequenceEffect : GroupEffect {
  constructor(sequence<AnimationEffect>? children,
              optional (unrestricted double or EffectTiming) timing = {});

  SequenceEffect clone ();
};
constructor (sequence<AnimationEffect>? children, optional (unrestricted double or EffectTiming) timing)

이 생성자의 각 파라미터 의미와 처리는 GroupEffect() 생성자와 동일합니다.

SequenceEffect clone ()

SequenceEffect 객체의 딥 카피를 생성합니다. 이때 clone() 메서드에 정의된 절차를 사용하나, 새로운 SequenceEffect 객체가 생성됩니다.

4.10. KeyframeEffect 인터페이스

KeyframeEffect 인터페이스는 다음과 같은 내용을 추가하도록 수정됩니다:

partial interface KeyframeEffect {
    attribute IterationCompositeOperation    iterationComposite;
};
KeyframeEffect (target, keyframes, options)

새로운 KeyframeEffect 객체를 생성하는 절차의 5단계를 다음과 같이 수정합니다:

  1. 만약 optionsKeyframeEffectOptions 객체라면, effectiterationCompositecomposite 속성에 options의 해당 값을 할당합니다.

    이러한 속성을 할당할 때, KeyframeEffect 인터페이스의 setter에 정의된 에러 처리가 적용됩니다. 만약 해당 setter에서 options가 지정한 값에 대해 예외를 던져야 하면, 이 절차는 동일한 예외를 던지고 이후 모든 단계를 중지해야 합니다.

KeyframeEffect (source)

동일한 속성을 가진 새로운 KeyframeEffect 객체를 생성하는 절차에, sourceiteration composite operationeffect에 설정하는 단계를 포함합니다.

iterationComposite, 타입 IterationCompositeOperation

키프레임 효과(keyframe effect)iteration composite operation 속성을 IterationCompositeOperation 열거값 중 하나로 지정합니다.

설정 시, 이 애니메이션 효과iteration composite operation 속성에 주어진 값을 설정합니다.

4.10.1. KeyframeEffect 객체 생성

이 절은 비규범적입니다

다음으로 교체:

지속 시간이 지정되지 않으면, 0 값이 사용됩니다.

다음으로 교체:

지속 시간이 지정되지 않으면, 고유 반복 지속시간이 사용됩니다.

다음 추가:

이 기능은 다른 애니메이션 효과와 결합할 때 특히 유용합니다. 예를 들어, 요소를 숨기기 전에 페이드아웃(fade out) 효과를 주려면 visibility를 ‘hidden’으로 전환하는 다음과 같은 방법을 사용할 수 있습니다.

new SequenceEffect(
  [
    new KeyframeEffect(elem, { opacity: 0 }, 1000),
    new KeyframeEffect(elem, { visibility: 'hidden' }, { fill: 'forwards' })
  ]
);

4.10.2. *Keyframe 딕셔너리의 수정

ComputedKeyframe, BaseComputedKeyframe, BaseKeyframe, BasePropertyIndexedKeyframe 등에서 offset 키의 double? 타입은 (CSSNumberish? or TimelineRangeOffset or DOMString)로 대체됩니다. double은 백분율로 해석되며, DOMString 타입은 <keyframe-selector> 구문에 따라 TimelineRangeOffset으로 파싱됩니다. 파싱 결과의 TimelineRangeOffset 또는 CSSNumericValue@keyframes에서 정의된 대로 해석됩니다.

DOMString 값이 유효한 <keyframe-selector>로 파싱되지 않으면, 해당 키프레임은 유효하지 않으며, [[web-animations-1#processing-a-keyframes-argument|처리]] 시 TypeError가 발생합니다 (double 값이 [0,1] 범위를 벗어난 경우와 동일).

4.10.3. KeyframeEffectOptions 딕셔너리

KeyframeEffectOptions 딕셔너리 인터페이스에 다음 멤버가 추가됩니다:

partial dictionary KeyframeEffectOptions {
    IterationCompositeOperation iterationComposite = "replace";
};
iterationComposite, 타입 IterationCompositeOperation, 기본값 "replace"

애니메이션 값이 반복(iteration)마다 누적되는 방식을 정의하는 iteration composite operation을 지정합니다.

4.11. IterationCompositeOperation 열거형

애니메이션 효과iteration composite operation에 사용할 수 있는 값은 IterationCompositeOperation 열거형으로 표현됩니다.

enum IterationCompositeOperation { "replace", "accumulate" };
replace

replace iteration composite operation 값에 해당하며, 생성되는 효과 값(effect value)현재 반복(current iteration)과는 무관하도록 한다.

accumulate

accumulate iteration composite operation 값에 해당하며, 이후 반복에서는 애니메이션 효과가 이전 반복의 마지막 값을 누적합니다.

4.12. EffectCallback 콜백 함수

커스텀 효과는 스크립트에서 EffectCallback 콜백 함수를 제공하여 정의할 수 있습니다.

callback EffectCallback = undefined (double? progress,
                                (Element or CSSPseudoElement) currentTarget,
                                Animation animation);

EffectCallback 은 연관된 KeyframeEffect 객체가 업데이트될 때마다 호출됩니다.

double? progress

iteration progress 값입니다. 이 값이 null이면 함수는 효과를 제거해야 합니다.

(Element or CSSPseudoElement) currentTarget

이 콜백이 동작할 것으로 기대되는 대상 엘리먼트(target element)입니다.

currentTargetanimation.target과 다를 수 있습니다.

만약 animation대상 엘리먼트가 업데이트 사이에 바뀌면, 이 메서드는 progress는 null이고 이전 대상 엘리먼트currentTarget인 상황, 그리고 현재 progress와 업데이트된 대상 엘리먼트currentTarget인 상황에서 각각 한 번씩 호출됩니다. 이렇게 하면 애니메이션 효과를 이전 대상 엘리먼트에서 제거할 수 있습니다.

Animation animation

업데이트되고 있는 Animation 객체입니다.

4.13. Animatable 인터페이스

sequence<Animation> getAnimations(options)

다음 내용 추가:

이 객체가 동일한 애니메이션에 연관된 두 개 이상의 애니메이션 효과대상 엘리먼트인 경우에도, 반환된 목록에는 해당 Animation 객체가 한 번만 나옵니다.

4.14. Animatable 인터페이스 믹스인

Animatable 믹스인 인터페이스에 다음 멤버들이 추가되었습니다:

Animation animate(keyframes, options)

다음과 같이 6단계를 수정합니다:

  1. 만약 optionsKeyframeAnimationOptions 객체라면, triggeroptionstrigger 멤버로 하거나, optionstrigger 멤버가 없다면, 옵션으로 빈 AnimationTriggerOptions 딕셔너리를 가진 새로 생성한 AnimationTrigger로 설정합니다.

  2. animation에 대해 auto-rewind 플래그를 true로 설정하여 애니메이션의 트리거 설정 절차를 실행합니다.

KeyframeAnimationOptions 딕셔너리 인터페이스에 다음 멤버들이 추가되었습니다:

dictionary TimelineRangeOffset {
  CSSOMString? rangeName;
  CSSNumericValue offset;
};

partial dictionary KeyframeAnimationOptions {
    (TimelineRangeOffset or CSSNumericValue or CSSKeywordValue or DOMString) rangeStart = "normal";
    (TimelineRangeOffset or CSSNumericValue or CSSKeywordValue or DOMString) rangeEnd = "normal";
    AnimationTrigger? trigger;
};
rangeStart, 타입 (TimelineRangeOffset or CSSNumericValue or CSSKeywordValue or DOMString), 기본값은 "normal"

존재하고 값이 "normal"이 아니면, 애니메이션애니메이션 첨부 범위의 시작을 지정합니다. DOMString 값은 animation-range-end 값으로 파싱되어 TimelineRangeOffset rangeNameoffset을 생성하거나, 또는 CSSKeywordValue 와 그 value 값이 "normal"인 경우, CSSNumericValue 값은 TimelineRangeOffset 에 offset만 설정하고 rangeName은 null로 해석됩니다.

rangeEnd, 타입 (TimelineRangeOffset or CSSNumericValue or CSSKeywordValue or DOMString), 기본값은 "normal"

존재하고 값이 "normal"이 아니면, 애니메이션애니메이션 첨부 범위의 끝을 지정합니다. DOMString 값은 animation-range-end 값으로 파싱되어 TimelineRangeOffset rangeNameoffset을 생성하거나, CSSNumericValue 값은 TimelineRangeOffset 에 offset만 설정하고 rangeName은 null로 해석됩니다.

trigger, 타입 AnimationTrigger, nullable

존재하는 경우, 애니메이션과 연관된 애니메이션 트리거애니메이션의 트리거 설정 절차로 지정합니다.

CSSKeywordValuevalue 가 "normal"이 아닌 값을 rangeStart 혹은 rangeEnd 에 입력하여 KeyframeAnimationOptions를 받는 API에 넘기면 TypeError가 발생합니다.

Note: rangeNameoffset 속성(들)은 rangeStartrangeEnd 모두 animation-range-start/ animation-range-end 사양을 따르며, 애니메이션에도 동일하게 적용됩니다.

자세한 설명은 [[web-animations-1#the-animatable-interface-mixin]]을 참조하세요.

4.15. AnimationPlaybackEvent 인터페이스

currentTime과 timelineTime의 타입을 double에서 CSSNumberish로 변경.

[Exposed=Window]
interface AnimationPlaybackEvent : Event {
    constructor(DOMString type, optional AnimationPlaybackEventInit
    eventInitDict = {});
    readonly attribute CSSNumberish? currentTime;
    readonly attribute CSSNumberish? timelineTime;
};
dictionary AnimationPlaybackEventInit : EventInit {
    CSSNumberish? currentTime = null;
    CSSNumberish? timelineTime = null;
};

AnimationPlaybackEvent 속성 타입을 업데이트합니다.

currentTime, 타입 CSSNumberish, 읽기 전용, nullable

이벤트가 큐에 추가된 순간 이벤트를 생성한 애니메이션현재 시간입니다. 이벤트가 발생할 때 애니메이션idle 상태였다면 null 입니다.

timelineTime, 타입 CSSNumberish, 읽기 전용, nullable

이벤트가 큐에 추가된 순간 이벤트를 생성한 애니메이션이 연관된 타임라인시간 값입니다. 만약 해당 애니메이션활성 타임라인과 연관되어 있지 않으면 null입니다.

AnimationPlaybackEventInit 멤버 속성 타입을 업데이트합니다.

currentTime, 타입 CSSNumberish, nullable, 기본값 null

currentTime 속성 설명을 참조하세요.

timelineTime, 타입 CSSNumberish, nullable, 기본값 null

timelineTime 속성 설명을 참조하세요.

4.16. AnimationTrigger 인터페이스

[Exposed=Window]
interface AnimationTrigger {
  constructor(optional AnimationTriggerOptions options = {});
  attribute AnimationTimeline timeline;
  attribute AnimationTriggerBehavior behavior;
  attribute any rangeStart;
  attribute any rangeEnd;
  attribute any exitRangeStart;
  attribute any exitRangeEnd;
};
테스트
AnimationTrigger(options)

다음 절차에 따라 새 AnimationTrigger 객체를 생성합니다.

  1. AnimationTrigger 객체 trigger를 생성합니다.

  2. trigger.did trigger를 false로 설정합니다.

  3. trigger.stateidle로 설정합니다.

  4. trigger.behavioroptions.behavior를 설정합니다.

  5. 기본 범위trigger에 대해 options.rangeStartoptions.rangeEnd로 설정합니다. (KeyframeAnimationOption의 rangeStartrangeEnd와 동일한 규칙 적용)

  6. exit 범위options.exitRangeStartoptions.exitRangeEnd로 설정합니다. (위 기본 범위 규칙 동일 적용, 단 값이 "auto"이면 기본 범위와 동일하게 설정)

  7. animation trigger의 타임라인 설정 절차를 triggeroptions.timelinenew timeline으로 하여 실행합니다.

options

새로 생성된 trigger를 위한 설정 파라미터.

timeline, 타입 AnimationTimeline

이 트리거의 타임라인을 반환하거나 타임라인이 비활성이면 `null`을 반환합니다.

behavior, 타입 AnimationTriggerBehavior

이 트리거의 동작(behavior)을 반환합니다.

rangeStart, 타입 any

이 트리거의 기본 범위 시작을 반환합니다.

rangeEnd, 타입 any

이 트리거의 기본 범위 끝을 반환합니다.

exitRangeStart, 타입 any

이 트리거의 exit 범위 시작을 반환합니다.

exitRangeEnd, 타입 any

이 트리거의 exit 범위 끝을 반환합니다.

4.17. AnimationTriggerOptions 딕셔너리

dictionary AnimationTriggerOptions {
  AnimationTimeline? timeline;
  AnimationTriggerBehavior? behavior = "once";
  (TimelineRangeOffset or CSSNumericValue or CSSKeywordValue or DOMString) rangeStart = "normal";
  (TimelineRangeOffset or CSSNumericValue or CSSKeywordValue or DOMString) rangeEnd = "normal";
  (TimelineRangeOffset or CSSNumericValue or CSSKeywordValue or DOMString) exitRangeStart = "auto";
  (TimelineRangeOffset or CSSNumericValue or CSSKeywordValue or DOMString) exitRangeEnd = "auto";
};
timeline, 타입 AnimationTimeline, nullable

트리거가 연관된 타임라인. 지정하지 않으면 기본 문서 타임라인에 연관됩니다.

behavior, 타입 AnimationTriggerBehavior, nullable, 기본값 "once"

트리거의 동작(behavior). 지정하지 않으면 기본값은 once입니다.

rangeStart, 타입 (TimelineRangeOffset or CSSNumericValue or CSSKeywordValue or DOMString), 기본값 "normal"

트리거의 기본 범위의 시작점. 지정하지 않으면 기본 범위의 시작은 "normal"입니다.

rangeEnd, 타입 (TimelineRangeOffset or CSSNumericValue or CSSKeywordValue or DOMString), 기본값 "normal"

트리거의 기본 범위의 끝점. 지정하지 않으면 기본 범위의 끝은 "normal"입니다.

exitRangeStart, 타입 (TimelineRangeOffset or CSSNumericValue or CSSKeywordValue or DOMString), 기본값 "auto"

트리거의 exit 범위의 시작점. 지정하지 않으면 exit 범위의 시작은 "auto"입니다.

exitRangeEnd, 타입 (TimelineRangeOffset or CSSNumericValue or CSSKeywordValue or DOMString), 기본값 "auto"

트리거의 exit 범위의 끝점. 지정하지 않으면 exit 범위의 끝은 "auto"입니다.

4.18. AnimationTriggerBehavior 열거형

enum AnimationTriggerBehavior { "once", "repeat", "alternate", "state" };
once

once (한 번만 실행).

repeat

repeat (반복 실행).

alternate

alternate (왕복 실행).

state

state (상태 기반).

4.19. 모델 라이브니스(Model liveness)

이 절은 비규범적입니다

“ Web Animations 모델에 변경 사항을 적용하면 즉시 효과가 나타난다”라는 절에 다음을 추가합니다:

동일한 개념이 GroupEffect에 자식을 추가하거나 제거하는 등 Web Animations 모델의 더 복잡한 수정에도 적용됩니다.

추가:

프로그래밍 인터페이스를 사용해 모델을 수정해도 EffectCallback 함수가 즉시 호출되지 않습니다.

예를 들어, 아래 코드에서 콜백 함수는 일반 업데이트가 끝나고 스크립트 블록이 완료된 후에 호출됩니다.

var timesCalled = 0;
elem.animate(function() {
  timesCalled++;
}, 10000);
alert(timesCalled); // ‘0’이 표시됩니다

참고: 이 내용은 규범적으로 별도의 위치에 명확히 명시되어야 합니다.

5. 변경 이력

5.1. 레벨 1 이후 변경 사항

이 명세는 이전 단계에 비해 다음과 같은 변경 사항을 포함합니다:

이 모듈에는 또한 [[#custom-effects]]에 대한 실험적 제안도 포함되어 있지만, 이 기능에 대한 설계상 우려가 있으며 향후 개정에서 변경될 수 있습니다. 자세한 논의는 여기에서 확인할 수 있습니다.

5.2. 2023년 2월 21일자 최초 공개 워킹드래프트(First Public Working Draft) 이후의 변경 사항

6. 프라이버시 관련 고려사항

이 모듈에는 보고된 프라이버시 관련 고려사항이 없습니다.

7. 보안 관련 고려사항

이 모듈에는 보고된 보안 관련 고려사항이 없습니다.

적합성(Conformance)

문서 관례(Document conventions)

적합성 요구사항은 설명적 단언과 RFC 2119 용어의 조합으로 표현됩니다. “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, “OPTIONAL” 등의 주요 단어들은 RFC 2119에 따라 해석되어야 합니다. 단, 가독성을 위해 이 사양서에서는 대문자로 사용하지 않을 수 있습니다.

비규범 절, 예제, 참고를 명시적으로 표시한 부분을 제외하고 이 명세의 모든 내용은 규범적입니다. [RFC2119]

이 명세서의 예시는 “for example”이라는 말로 시작하거나 class="example" 속성을 가진 예로 구분됩니다:

이것은 정보 제공용 예시입니다.

안내 문구(note)는 “Note”라는 단어로 시작하며, class="note"로 구분되어 규범 문서와 분리됩니다:

참고, 이것은 정보성 노트입니다.

규범적 권고(advisement)는 강조 스타일로 구분되며 아래와 같이 제시됩니다: UA는 반드시 접근성 대안을 제공해야 합니다.

테스트

이 명세의 내용과 관련된 테스트는 이와 같은 "테스트" 블록에 문서화될 수 있습니다. 이러한 모든 블록은 비규범적입니다.


적합성 클래스

이 명세서의 적합성은 세 종류의 적합성 클래스로 정의됩니다:

스타일 시트
CSS 스타일 시트.
렌더러
UA로서 스타일 시트의 의미를 해석하고 이를 적용해 문서를 렌더링합니다.
저작 도구
UA로서 스타일 시트를 작성합니다.

이 모듈에서 정의된 구문을 사용하는 모든 스타일 시트가 일반 CSS 문법 및 각 기능별 개별 문법에 따라 유효하면 이 명세에 적합한 스타일 시트로 인정합니다.

렌더러는, 스타일 시트를 관련 명세서에 따라 해석하는 것 이외에도, 이 명세에서 정의한 모든 기능을 올바르게 구문 분석하고 해당 동작을 수행해야 적합합니다. 단, 장치의 한계로 인해 문서를 제대로 렌더링할 수 없는 경우에는 비적합으로 간주하지 않습니다. (예: UA가 흑백 디스플레이에서 색을 렌더링할 필요는 없음)

저작 도구는, 스타일 시트가 일반 CSS 문법과 이 모듈 개별 문법에 따라 구문적으로 올바르고, 이 명세서가 스타일 시트에 대해 요구하는 모든 적합성 요건을 충족하면 적합합니다.

부분 구현(Partial implementations)

저자(author)는 전방호환 구문 규칙을 활용해 대체 값(fallback value)을 지정할 수 있도록, CSS 렌더러는 기능을 전혀 지원하지 않을 경우 해당 at-rule, 속성, 값, 구문 및 기타 구문 구조를 반드시 무효(적절히 무시) 처리해야 합니다. 특히 UA는 지원하지 않는 구성요소 값만 선택적으로 무시하고 지원되는 값만 적용해서는 안됩니다: 어떤 값이라도 무효로 간주되면(=지원하지 않으면) CSS 사양상 전체 선언을 무시해야 합니다.

불안정 및 독자기능(Implementations of Unstable and Proprietary Features)

향후 안정화된 CSS 기능과 충돌을 피하기 위해, CSSWG는 권장 관례에 따라 불안정독자 확장 기능을 구현할 것을 권장합니다.

비실험적 구현(Non-experimental implementations)

이 명세가 Candidate Recommendation 단계에 도달하면, 비실험적 구현이 가능해지며, 구현자는 사양에 따라 올바르게 구현된 CR 수준의 모든 기능을 prefix 없이 구현해 배포해야 합니다.

CSS 구현 간 상호 운용성을 확보·유지하기 위해, CSS 워킹 그룹은 비실험적 CSS 렌더러가 구현 보고서와(필요하다면) 사용한 테스트 케이스를 W3C에 제출할 것을 요청합니다. W3C에 제출된 테스트는 CSS 워킹 그룹의 검토 및 수정 대상이 됩니다.

테스트 케이스 및 구현 보고서 제출에 대한 자세한 내용은 CSS 워킹 그룹 웹사이트 https://www.w3.org/Style/CSS/Test/를 참조하시기 바랍니다. 문의는 public-css-testsuite@w3.org 메일링 리스트로 하십시오.

인덱스(Index)

이 명세서에서 정의한 용어

참조로 정의된 용어

참고 문헌

규범적 참고문헌

[CSS-ANIMATIONS-1]
David Baron; 외. CSS Animations Level 1. 2023년 3월 2일. WD. URL: https://www.w3.org/TR/css-animations-1/
[CSS-DISPLAY-4]
Elika Etemad; Tab Atkins Jr.. CSS Display Module Level 4. 2025년 11월 6일. WD. URL: https://www.w3.org/TR/css-display-4/
[CSS-EASING-1]
Brian Birtles; Dean Jackson; Matt Rakow. CSS Easing Functions Level 1. 2023년 2월 13일. CRD. URL: https://www.w3.org/TR/css-easing-1/
[CSS-EASING-2]
CSS Easing Functions Level 2. 2024년 8월 29일. FPWD. URL: https://www.w3.org/TR/css-easing-2/
[CSS-PSEUDO-4]
Elika Etemad; Alan Stearns. CSS Pseudo-Elements Module Level 4. 2025년 6월 27일. WD. URL: https://www.w3.org/TR/css-pseudo-4/
[CSS-TYPED-OM-1]
Tab Atkins Jr.; François Remy. CSS Typed OM Level 1. 2024년 3월 21일. WD. URL: https://www.w3.org/TR/css-typed-om-1/
[CSS-VALUES-4]
Tab Atkins Jr.; Elika Etemad. CSS Values and Units Module Level 4. 2024년 3월 12일. WD. URL: https://www.w3.org/TR/css-values-4/
[CSSOM-1]
Daniel Glazman; Emilio Cobos Álvarez. CSS Object Model (CSSOM). 2021년 8월 26일. WD. URL: https://www.w3.org/TR/cssom-1/
[DOM]
Anne van Kesteren. DOM Standard. Living Standard. URL: https://dom.spec.whatwg.org/
[HTML]
Anne van Kesteren; 외. HTML Standard. Living Standard. URL: https://html.spec.whatwg.org/multipage/
[INFRA]
Anne van Kesteren; Domenic Denicola. Infra Standard. Living Standard. URL: https://infra.spec.whatwg.org/
[RFC2119]
S. Bradner. Key words for use in RFCs to Indicate Requirement Levels. 1997년 3월. Best Current Practice. URL: https://datatracker.ietf.org/doc/html/rfc2119
[SCROLL-ANIMATIONS-1]
Brian Birtles; 외. Scroll-driven Animations. 2023년 6월 6일. WD. URL: https://www.w3.org/TR/scroll-animations-1/
[WEB-ANIMATIONS-1]
Brian Birtles; 외. Web Animations. 2023년 6월 5일. WD. URL: https://www.w3.org/TR/web-animations-1/
[WEBIDL]
Edgar Chen; Timothy Gu. Web IDL Standard. Living Standard. URL: https://webidl.spec.whatwg.org/

IDL 인덱스

[Exposed=Window]
partial interface AnimationTimeline {
    readonly attribute CSSNumberish? currentTime;
    readonly attribute CSSNumberish? duration;
    Animation play (optional AnimationEffect? effect = null);
};

[Exposed=Window]
partial interface Animation {
    attribute CSSNumberish?       startTime;
    attribute CSSNumberish?       currentTime;
    attribute AnimationTrigger?   trigger;
    attribute (TimelineRangeOffset or CSSNumericValue or CSSKeywordValue or DOMString) rangeStart;
    attribute (TimelineRangeOffset or CSSNumericValue or CSSKeywordValue or DOMString) rangeEnd;
    readonly attribute double? overallProgress;
};

[Exposed=Window]
partial interface AnimationEffect {
    // Timing hierarchy
    readonly attribute GroupEffect?     parent;
    readonly attribute AnimationEffect? previousSibling;
    readonly attribute AnimationEffect? nextSibling;

    undefined before (AnimationEffect... effects);
    undefined after (AnimationEffect... effects);
    undefined replace (AnimationEffect... effects);
    undefined remove ();
};

partial dictionary EffectTiming {
    double delay;
    double endDelay;
    double playbackRate = 1.0;
    (unrestricted double or CSSNumericValue or DOMString) duration = "auto";
};

partial dictionary OptionalEffectTiming {
    double playbackRate;
};

partial dictionary ComputedEffectTiming {
    CSSNumberish         startTime;
    CSSNumberish         endTime;
    CSSNumberish         activeDuration;
    CSSNumberish?        localTime;
};

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

[Exposed=Window]
interface GroupEffect {
  constructor(sequence<AnimationEffect>? children,
              optional (unrestricted double or EffectTiming) timing = {});

  readonly attribute AnimationNodeList  children;
  readonly attribute AnimationEffect?   firstChild;
  readonly attribute AnimationEffect?   lastChild;
  GroupEffect clone ();

  undefined prepend (AnimationEffect... effects);
  undefined append (AnimationEffect... effects);
};

[Exposed=Window]
interface AnimationNodeList {
    readonly attribute unsigned long length;
    getter AnimationEffect? item (unsigned long index);
};

[Exposed=Window]
interface SequenceEffect : GroupEffect {
  constructor(sequence<AnimationEffect>? children,
              optional (unrestricted double or EffectTiming) timing = {});

  SequenceEffect clone ();
};

partial interface KeyframeEffect {
    attribute IterationCompositeOperation    iterationComposite;
};

partial dictionary KeyframeEffectOptions {
    IterationCompositeOperation iterationComposite = "replace";
};

enum IterationCompositeOperation { "replace", "accumulate" };

callback EffectCallback = undefined (double? progress,
                                (Element or CSSPseudoElement) currentTarget,
                                Animation animation);

dictionary TimelineRangeOffset {
  CSSOMString? rangeName;
  CSSNumericValue offset;
};

partial dictionary KeyframeAnimationOptions {
    (TimelineRangeOffset or CSSNumericValue or CSSKeywordValue or DOMString) rangeStart = "normal";
    (TimelineRangeOffset or CSSNumericValue or CSSKeywordValue or DOMString) rangeEnd = "normal";
    AnimationTrigger? trigger;
};

[Exposed=Window]
interface AnimationPlaybackEvent : Event {
    constructor(DOMString type, optional AnimationPlaybackEventInit
    eventInitDict = {});
    readonly attribute CSSNumberish? currentTime;
    readonly attribute CSSNumberish? timelineTime;
};
dictionary AnimationPlaybackEventInit : EventInit {
    CSSNumberish? currentTime = null;
    CSSNumberish? timelineTime = null;
};

[Exposed=Window]
interface AnimationTrigger {
  constructor(optional AnimationTriggerOptions options = {});
  attribute AnimationTimeline timeline;
  attribute AnimationTriggerBehavior behavior;
  attribute any rangeStart;
  attribute any rangeEnd;
  attribute any exitRangeStart;
  attribute any exitRangeEnd;
};

dictionary AnimationTriggerOptions {
  AnimationTimeline? timeline;
  AnimationTriggerBehavior? behavior = "once";
  (TimelineRangeOffset or CSSNumericValue or CSSKeywordValue or DOMString) rangeStart = "normal";
  (TimelineRangeOffset or CSSNumericValue or CSSKeywordValue or DOMString) rangeEnd = "normal";
  (TimelineRangeOffset or CSSNumericValue or CSSKeywordValue or DOMString) exitRangeStart = "auto";
  (TimelineRangeOffset or CSSNumericValue or CSSKeywordValue or DOMString) exitRangeEnd = "auto";
};

enum AnimationTriggerBehavior { "once", "repeat", "alternate", "state" };

이슈 인덱스

이게 완전히 맞지는 않습니다. old effect가 같은 작업(task)에서 다른 애니메이션에 연결되어 있다면, unresolved 상태로 추가 콜백을 부르는 것은 아마도 적절하지 않을 것입니다.

커스텀 효과(custom effects)가 호출되는 시점의 정의는 검토 및 리라이트가 필요합니다.

애니메이션을 재생하는 과정에 커스텀 효과 업데이트를 위한 작업(task) 예약(scheduling)이 포함되어야 합니다.
커스텀 효과 호출 절차는 재작업이 필요합니다. 현재는 변경 사항에 대해 너무 자주 호출되어 합칠 수 있는 변경도 개별적으로 발생할 수 있습니다.
일시정지(paused) 상태의 애니메이션에서 애니메이션의 현재 시간이 명확히 설정된 경우, 이 절차는 정확하지 않을 수 있습니다. 이 경우 타임라인(timeline)의 현재 시각과 애니메이션의 현재 시각 사이에 차이가 생길 수 있습니다.
이 절차는 더 간소화될 수 있습니다. 스크롤 경계에 도달했는지만 판별하면 되고, 재생 속도나 시작 시각에 관계없이 적용할 수 있을 것 같습니다. 이 절차가 방지하려는 놀라운 동작(스크롤 한계에서 애니메이션이 비활성화됨)을 ScrollTimeline의 fill-mode 대신 타임라인의 current time이 0 또는 타임라인 지속시간인지 체크하면 충분할 수도 있습니다.
현재 타이밍 함수(timing functions)가 [0, 1] 범위를 벗어난 값을 생성하면, 그룹 효과(group effects)에 적용될 때 예상치 못한 동작이 발생합니다. 자식 효과들은 반복이 늘어나거나 fill 모드로 진입하게 되는데, 만약 타이밍 함수가 자식 효과에 직접 적용된 경우에는 정의된 동작을 따라 계속 외삽(extrapolate)하는 것이 일반적입니다.

이를 해결하려면 활성 시간 범위를 벗어나는 시간 값에 대해 fill 대신 외삽이 동작하는 ‘overflow’ fill 모드를 도입할 필요가 있을 것입니다.

관련 논의는 2013년 도쿄 F2F 회의록 15번(Overflowing fill) 참조.

현재 타이밍 함수의 사용 범위가 그룹 효과(group effect)에서 제한되지 않습니다. 이는 구현 복잡성 증가 및 fill 모드와의 상호작용 복잡성에 대한 우려를 낳고 있습니다. 따라서 그룹 효과에서 모든 타이밍 함수를 허용하는 것은 위험요소로 간주됩니다.

대안으로, 그룹 효과에서는 선형(linear) 타이밍 함수만 허용하거나, “단순(simple)” 타이밍 함수(복잡한 함수가 가지는 문제를 완화할 수 있는 속성을 가진 함수)만 허용할 수 있습니다.

관련 논의는 2013년 8월 논의의 2번 항목 참조.

애니메이션 효과 정렬시 사용하는 "an animation effect의 연관 애니메이션(associated animation)" 정의는, 이 규격의 애니메이션과 연관(associated with an animation) 정의를 참조해서 그룹 효과도 올바르게 처리할 수 있도록 수정되어야 합니다.
이 기능 전체를 재검토할 필요가 있습니다. 현재 구상은 커스텀 효과(custom effects) 대신 각 애니메이션 효과onupdate 콜백을 두는 방식이 낫다는 것입니다. 예를 들어, 기존 효과에 로깅을 추가하거나 특정 시점에 추가 동작을 하려면 함수만 추가하면 되지만, 현 구조에서는 이를 위해 그룹(부모)을 더 만들어야 합니다.
타이밍 속성이 업데이트될 때마다 호출되어야 하지 않나요?
애니메이션 트리에서 특정 지점에서 액션을 트리거해야 하는 경우가 있을 수 있습니다. 많은 경우 step-start easing을 사용한 커스텀 효과를 넣고, 그 구간 동안 액션이 발생하게 할 수 있습니다. 하지만 이렇게 하면 레이아웃 요구사항이 늘어나서 콘텐츠 설계가 복잡해질 수 있습니다.

현재 고려 중인 대안:

좀 더 정밀하게 정의해야 합니다. 스타일이 flush되는가? 대개 그렇다고 생각됩니다. 스크립트 기반 애니메이션 효과를 실행하는 동안 리플로우를 일시 중지(suspend)시키고, 이후 한 번만 처리하는 것이 가능한지 검토가 필요합니다.
트리거가 스크롤 구동 애니메이션(scroll-driven animations)에 영향을 미쳐야 할까요?
idle 상태 정의의 명확한 명세가 필요할까요?
"behavior types primary/inverse"에 대해 더 정확한 정의가 필요할까요?
exit 범위의 경계는 반드시 default range의 경계와 같거나 더 크게 해야 할까요?
타임라인이 다시 idle 상태가 될 경우 "did trigger" 플래그가 false로 초기화되는 것이 올바른/예상 동작일까요?
이 메서드의 이름 변경 혹은 제거 제안이 있었습니다 (참고: TAG 피드백).
effect가 null일 때의 시작 동작 정의가 필요합니다.
이것이 parentGroup이어야 할까요?
remove() 메서드는 효과(effect)를 부모 그룹이나 애니메이션에서 제거하는 데 모두 사용할 수 있습니다. 레벨 1에서 이를 유지하고, 애니메이션에서만 제거하도록 단순히 정의해둘까요?