1. 소개
이 섹션은 규범적인 내용이 아닙니다.이 문서는 웹 애니메이션의 확장성을 제공하고 웹에서 고성능 상호작용 프로시저 애니메이션을 가능하게 하는 새로운 프리미티브를 소개합니다. 자세한 동기와 근거는 [explainer] 및 [principles]를 참고하세요.
Animation Worklet API는 스크립트를 통해 애니메이션을 생성하고 애니메이션 효과 집합을 제어할 수 있는 방법을 제공합니다. 이 API는 사용자 에이전트가 이러한 애니메이션을 별도의 스레드에서 실행함으로써 메인 스레드와 분리된 성능을 어느 정도 보장할 수 있도록 설계되었습니다.
1.1. Web Animations API와의 관계
이 섹션은 규범적인 내용이 아닙니다.Animation Worklet 실행
컨텍스트 내에서 동작하는 애니메이션은 메인 자바스크립트 실행 컨텍스트에서 Web Animations 명세의 Animation
인터페이스를 노출합니다. 즉, 동일한 Web Animation API를 사용하여 메인 스레드에서 제어 및 검사할 수 있습니다.
2. 애니메이션 워크릿
Animation Worklet은Worklet
으로, 커스텀 애니메이션과 관련된 모든 클래스를 담당합니다. worklet은 animationWorklet
속성을 통해 접근할 수 있습니다.
animationWorklet
의
worklet 전역 스코프 타입은 AnimationWorkletGlobalScope
입니다.
AnimationWorkletGlobalScope
는 animationWorklet
의
전역 실행 컨텍스트를 나타냅니다.
[Exposed =Window ]partial namespace CSS { [SameObject ]readonly attribute Worklet ; };
animationWorklet
3. 애니메이터
Animator는 애니메이션 스레드에서 실행 중인
애니메이션 인스턴스를 나타냅니다.
애니메이터는 고유한 이름으로 식별되며, 현재 입력 시간에 따라 키프레임 효과가 어떻게 진행될지 결정합니다. Animator 인스턴스는 AnimationWorkletGlobalScope
내에 존재하며 각각 WorkletAnimation
인스턴스와 연결됩니다. 애니메이터는 WorkletAnimation
을 생성할 때만 인스턴스화됩니다.
두 가지 애니메이터 타입이 지원됩니다: StatelessAnimator
와 StatefulAnimator
로, 각각 다른 상태 관리 전략을 제공합니다.
3.1. StatelessAnimator 인터페이스
이 인터페이스는 상태를 가지지 않는 애니메이터를 나타냅니다. 이 타입의 애니메이터는 인스턴스 또는 전역 스코프에 저장된 로컬 상태에 의존하지 않습니다. StatelessAnimator
의 animate 함수는 입력이 같으면 항상 동일한 출력을 반환하는 순수 함수로 취급할 수 있습니다.
[Exposed =AnimationWorklet ,Global =AnimationWorklet ,(
Constructor optional any )]
options interface { };
StatelessAnimator
class FooAnimatorextends StatelessAnimator{ constructor( options) { // 새로운 애니메이터가 인스턴스화될 때 호출됩니다. } animate( currentTime, effect) { // 애니메이션 프레임 로직을 여기에 작성합니다. } }
참고: 상태가 없기 때문에 애니메이션 워크릿은 여러 애니메이션 프레임을 병렬로 생성하거나 매우 저렴하게 해제 및 설정을 수행하는 등 최적화를 할 수 있습니다. 이러한 최적화를 위해 StatelessAnimator 사용을 적극 권장합니다.
3.2. StatefulAnimator 인터페이스
이 인터페이스는 상태를 가지는 애니메이터를 나타냅니다. 이 애니메이터는 로컬 상태를 가질 수 있으며, 애니메이션 워크릿은 해당 인터페이스의 요구 사항을 준수하는 한 이 상태를 유지함을 보장합니다.
Animation worklet
은 서로 다른 스레드 또는 프로세스에 걸쳐 존재할 수 있는 WorkletGlobalScope
집합을 관리합니다.
애니메이션 워크릿은 리소스 절약을 위해 전역 스코프를 일시적으로 종료하거나(예: 리소스 절약 목적), 실행 중인 animator instance를 다른 전역 스코프로 이동시킬 수
있습니다(예: 효과가 특정 스레드에서만 변경 가능한 경우). 애니메이션 워크릿은 상태를 유지해야 하는 stateful animator 인스턴스의 상태가 다른 전역 스코프로 재생성되어도 유지됨을
보장합니다.
상태 유지 기본 메커니즘은 애니메이션 워크릿이 state
함수를 통해 노출된 로컬 상태를 스냅샷으로 저장한 뒤, 나중에 잠재적으로 다른 전역 스코프에서 인스턴스가 재생성될 때 해당 객체를 생성자에 전달하여 상태를 복원하는 것입니다. 애니메이터 인스턴스 마이그레이션 알고리즘은 이 과정을 상세히 설명합니다.
사용자가 정의한 stateful animator는 필수 계약을 준수해야 하며, 즉 state 함수가 구조화 직렬화 알고리즘으로 직렬화할 수 있는 상태 객체를 반환해야 하고, 동일한 객체가 생성자에 전달되면 상태를 복원할 수 있어야 합니다.
[Exposed =AnimationWorklet ,Global =AnimationWorklet ,(
Constructor optional any ,
options optional any )]
state interface {
StatefulAnimator any (); };
state
class BarAnimatorextends StatefulAnimator{ constructor( options, state) { // 새로운 애니메이터가 인스턴스화될 때(최초 또는 재생성 시) 호출됩니다. this . currentVelocity= state? state. velocity: 0 ; } animate( currentTime, effect) { // 애니메이션 프레임 로직을 작성할 때 this.currentVelocity를 사용할 수 있습니다. this . currentVelocity+= 0.1 ; } state() { // 반환 객체는 구조화 복제 알고리즘으로 직렬화 가능해야 합니다. return { velocity: this . currentVelocity; } } }
3.3. 애니메이터 정의
애니메이터 정의는 작성자가 정의한
커스텀 애니메이션을 AnimationWorkletGlobalScope
에서
필요에 따라 설명하는 구조체입니다. 구성 요소는 다음과 같습니다:
-
애니메이터 이름 <ident>#.
-
클래스 생성자는
AnimatorInstanceConstructor
콜백 함수 타입입니다. -
stateful 플래그
3.4. 애니메이터 정의 등록
AnimationWorkletGlobalScope
에는
애니메이터
이름-정의 맵이 있습니다.
이 맵은 registerAnimator(name, animatorCtor)
호출 시 채워집니다.
[Exposed =AnimationWorklet ,Global =AnimationWorklet ]interface :
AnimationWorkletGlobalScope WorkletGlobalScope {void registerAnimator (DOMString ,
name AnimatorInstanceConstructor ); };
animatorCtor callback =
AnimatorInstanceConstructor any (any ,
options optional any );
state
registerAnimator(name, animatorCtor)
메서드가 AnimationWorkletGlobalScope
에서
호출되면, 사용자 에이전트는
다음 단계를 반드시 실행해야 합니다:
-
name이 유효한 <ident>가 아니면, throw를 통해 TypeError를 발생시키고 모든 단계를 중단합니다.
-
name이 애니메이터 이름-정의 맵의 키로 존재하면, throw를 통해 NotSupportedError를 발생시키고 모든 단계를 중단합니다.
-
IsConstructor(animatorCtor) 결과가 false이면, throw를 통해 TypeError를 발생시키고 모든 단계를 중단합니다.
-
prototype을 Get(animatorCtor, "prototype")의 결과로 설정합니다.
-
SameValue(prototype,
StatelessAnimator
) 결과가 true라면 stateful을 false로 설정하고, 그렇지 않으며 SameValue(prototype,StatefulAnimator
) 결과가 true라면 stateful을 true로 설정합니다. 둘 다 아니면 throw를 통해 TypeError를 발생시키고 모든 단계를 중단합니다. -
animateValue를 Get(prototype, "animate")의 결과로 설정합니다.
-
animate를 변환하여 animateValue를 Function 콜백 함수 타입으로 변환합니다. 예외가 발생하면 예외를 다시 던지고 모든 단계를 중단합니다.
-
definition을 새 애니메이터 정의로 생성합니다:
-
애니메이터 이름은 name
-
클래스 생성자는 animatorCtor
-
animate 함수는 animate
-
stateful 플래그는 stateful
-
-
(name - definition) 키-값 쌍을 애니메이터 이름-정의 맵에 추가합니다.
4. 애니메이터 인스턴스
애니메이터 인스턴스는 구조체로, AnimationWorkletGlobalScope
에서
완전히 실현된 커스텀 애니메이션 인스턴스를 설명합니다.
이 인스턴스는 애니메이터 정의에
대한 참조를 가지며, 애니메이션 효과나 타임라인 등 인스턴스별 상태를 소유합니다. 구성 요소는 다음과 같습니다:
-
애니메이터 효과는 애니메이션 효과
-
애니메이터 현재 시간은 해당 워크릿 애니메이션의 현재 시간입니다.
-
애니메이터 타임라인은 타임라인입니다.
-
애니메이터 직렬화 옵션은 직렬화 가능한 객체입니다.
상태 기반 애니메이터 인스턴스는 애니메이터 인스턴스 중 해당 애니메이터 정의의 stateful 플래그가 true인 경우입니다.
4.1. 애니메이터 인스턴스 생성
각 애니메이터 인스턴스는 AnimationWorkletGlobalScope
에
존재합니다.
각 AnimationWorkletGlobalScope
에는
애니메이터 인스턴스 집합이
있습니다. 이 집합은 사용자 에이전트가 AnimationWorkletGlobalScope
스코프에서 새로운 애니메이터 인스턴스를
생성할 때 채워집니다. 각 애니메이터
인스턴스는 문서 스코프의 워크릿 애니메이션에 대응됩니다.
새 애니메이터 인스턴스 생성을 위해 name, timeline, effect, serializedOptions, serializedState, workletGlobalScope가 주어졌을 때, 사용자 에이전트는 다음 단계를 반드시 실행해야 합니다:
-
definition을 workletGlobalScope의 애니메이터 이름-정의 맵에서 name으로 조회합니다.
definition이 존재하지 않으면 다음 단계를 중단합니다.
-
animatorCtor를 definition의 클래스 생성자로 설정합니다.
-
options를 StructuredDeserialize(serializedOptions)의 결과로 설정합니다.
-
state를 StructuredDeserialize(serializedState)의 결과로 설정합니다.
-
animatorInstance를 animatorCtor를 인수 «options, state»로 생성한 결과로 설정합니다. 예외가 발생하면 예외를 다시 던지고 모든 단계를 중단합니다.
-
animatorInstance에 다음을 설정합니다:
-
애니메이터 이름: name
-
애니메이터 현재 시간: 미결정 상태
-
애니메이터 효과: effect
-
애니메이터 타임라인: timeline
-
애니메이터 직렬화 옵션: options
-
-
animatorInstance를 workletGlobalScope의 애니메이터 인스턴스 집합에 추가합니다.
4.2. 애니메이터 실행
사용자 에이전트가 새로운 애니메이션 프레임을 생성하려 할 때, 애니메이터 인스턴스 중 연결된 애니메이션 요청 플래그가 frame-requested인 경우, 사용자 에이전트는 해당 프레임에서 애니메이터 실행을 반드시 수행해야 합니다.
참고: 사용자 에이전트는 모든 시각적 프레임에서 애니메이션을 실행할 필요가 없습니다. 애니메이션 프레임 생성을 이후 프레임까지 지연시키는 것도 허용됩니다. 이는 사용자 에이전트가 정책에 따라 다른 서비스 수준을 제공할 수 있도록 해줍니다.
사용자 에이전트가 workletGlobalScope에서 애니메이터 실행을 원할 때, workletGlobalScope의 모든 애니메이터 인스턴스를 반복합니다. 각 instance에 대해 사용자 에이전트는 다음을 반드시 실행해야 합니다:
-
animatorName을 instance의 애니메이터 이름으로 설정합니다.
-
definition을 workletGlobalScope의 애니메이터 이름-정의 맵에서 animatorName으로 조회합니다.
definition이 존재하지 않으면 다음 단계를 중단합니다.
-
instance의 애니메이션 요청 플래그가 frame-current이거나 instance의 효과가 현재 프레임의 시각적 뷰포트에서 보이지 않을 경우, 사용자 에이전트는 이후 단계를 중단할 수 있습니다.
-
animateFunction을 definition의 animate 함수로 설정합니다.
-
currentTime을 instance의 애니메이터 현재 시간으로 설정합니다.
-
effect를 instance의 애니메이터 효과로 설정합니다.
-
animateFunction을 인수 «currentTime, effect»로, instance를 콜백 this 값으로 하여 호출합니다.
animateFunction에서 예외가 발생한 경우 동작을 명확히 해야 합니다. 최소한 키프레임의 localTime 값이 무시되어 잘못된 부분적 업데이트를 방지한다는 문구가 있어야 합니다.
4.3. 애니메이터 인스턴스 제거
애니메이터 인스턴스 제거를 위해 instance와 workletGlobalScope가 주어지면 사용자 에이전트는 다음 단계를 반드시 실행해야 합니다:
-
instance를 workletGlobalScope의 애니메이터 인스턴스 집합에서 제거합니다.
4.4. 애니메이터 인스턴스 마이그레이션
마이그레이션 과정은 상태 기반 애니메이터 인스턴스가 로컬 상태를 잃지 않고
다른 WorkletGlobalScope
로
이동할 수 있도록 해줍니다.
애니메이터 인스턴스
마이그레이션을 위해, WorkletGlobalScope
간에 instance, sourceWorkletGlobalScope, destinationWorkletGlobalScope가
주어지면, 사용자 에이전트는 다음 단계를 반드시 실행해야 합니다:
-
serializedState를 undefined로 설정합니다.
-
작업 큐에 태스크 추가를 sourceWorkletGlobalScope에서 다음 단계가 실행되도록 추가합니다:
-
animatorName에 instance의 애니메이터 이름을 할당합니다.
-
definition을 sourceWorkletGlobalScope의 애니메이터 이름-정의 맵에서 animatorName으로 조회합니다.
definition이 존재하지 않으면 다음 단계를 중단합니다.
-
stateful을 definition의 stateful 플래그로 설정합니다.
-
stateful이 false이면 다음 단계를 중단합니다.
-
stateFunction
-
state를 stateFunction을 instance를 콜백 this 값으로 호출한 결과로 설정합니다. 예외가 발생하면 예외를 다시 던지고 다음 단계를 중단합니다.
-
serializedState를 StructuredSerialize(state) 결과로 설정합니다. 예외가 발생하면 다음 단계를 중단합니다.
-
애니메이터 인스턴스 제거 절차를 instance, sourceWorkletGlobalScope와 함께 실행합니다.
-
-
위 작업이 완료될 때까지 대기합니다. 태스크가 중단되면 이후 단계를 중단합니다.
-
작업 큐에 태스크 추가를 destinationWorkletGlobalScope에서 다음 단계가 실행되도록 추가합니다:
-
새 애니메이터 인스턴스 생성 절차를 다음 인수로 실행합니다:
-
instance의 애니메이터 이름을 name으로 사용
-
instance의 애니메이터 타임라인을 timeline으로 사용
-
instance의 애니메이터 효과를 effect로 사용
-
instance의 애니메이터 직렬화 옵션을 options로 사용
-
serializedState를 state로 사용
-
destinationWorkletGlobalScope를 workletGlobalScope로 사용
-
-
애니메이터 state getter에서 예외가 발생하면 사용자 에이전트는 해당 애니메이터를 제거하지만 다시 생성하지 않습니다. 즉, 해당 애니메이터 인스턴스는 효과적으로 삭제됩니다.
4.5. 애니메이션 프레임 요청
각 애니메이터 인스턴스는 연관된 애니메이션 요청 플래그를 가집니다. 반드시 frame-requested 또는 frame-current여야 하며, 초기값은 frame-current입니다. 상황에 따라 애니메이션 요청 플래그가 frame-requested로 설정될 수 있습니다. 예시는 다음과 같습니다:
§4.2 애니메이터 실행에서는 애니메이터의 애니메이션 요청 플래그를 frame-current로 리셋합니다.
5. Web Animations 통합
5.1. 워크릿 애니메이션
워크릿 애니메이션은 애니메이션의 일종으로, 애니메이션 재생을 애니메이터 인스턴스에 위임합니다. 해당 애니메이터 인스턴스의 생명주기와 재생 상태를 제어합니다.애니메이션이므로, 워크릿 애니메이션은 애니메이션 효과와 타임라인을 가집니다. 하지만, 일반 애니메이션과 달리 워크릿 애니메이션의 현재 시간은 애니메이션 효과의 local time(inherited time 경유)에 직접적으로 영향을 주지 않습니다. 대신 연관된 애니메이터 인스턴스가 애니메이션 효과의 local time을 직접 제어합니다. 즉, 타임라인의 현재 시간이 애니메이션 결과를 완전히 결정하지 않습니다.
워크릿 애니메이션은 Animation
인터페이스에 추가로 다음 속성을 가집니다:
-
애니메이션 애니메이터 이름: 해당 애니메이터 정의를 식별합니다.
-
직렬화 옵션: 새 애니메이터 인스턴스 생성 시 사용되는 직렬화 가능한 객체입니다.
애니메이션 현재 시간이 애니메이터 인스턴스에 입력되고, 해당 인스턴스가 애니메이션 효과를 위한 local time 값을 생성합니다. 애니메이터 인스턴스가 병렬 글로벌 스코프에서 실행되는 경우, 구현체는 local time 값을 이용해 최종 효과 값을 산출하고 시각적 업데이트를 병렬로 수행할 수도 있습니다.
5.2. 워크릿 애니메이션 생성
[Exposed =Window ,Constructor (DOMString ,
animatorName optional (AnimationEffect or sequence <AnimationEffect >)?=
effects null ,optional AnimationTimeline ?,
timeline optional any )]
options interface :
WorkletAnimation Animation {readonly attribute DOMString ; };
animatorName
WorkletAnimation(animatorName, effects, timeline, options)
다음 절차에 따라 새로운 WorkletAnimation
객체를 생성합니다.
-
workletAnimation을 새로운
WorkletAnimation
객체로 설정합니다. -
workletAnimation에 timeline을 새로운 타임라인으로 전달하여 애니메이션의 타임라인 설정 절차를 실행합니다. timeline 인수가 제공되지 않은 경우, 문서 기본 타임라인을
Document
및Window
의 현재 글로벌 객체에 따라 전달합니다. -
아래 조건 중 처음으로 일치하는 결과에 따라 effect를 설정합니다.
- 만약 effects가
AnimationEffect
객체라면, -
effect를 effects로 설정합니다.
- effects가 리스트 형태의
AnimationEffect
객체라면, -
effect를 새로운
WorkletGroupEffect
객체로 설정하고, 자식에 effects를 지정합니다. - 그 외의 경우,
-
effect를 undefined로 설정합니다.
- 만약 effects가
-
workletAnimation에 effect를 새로운 효과로 전달하여 애니메이션의 대상 효과 설정 절차를 실행합니다.
-
serializedOptions를 StructuredSerialize(options)의 결과로 설정합니다. 예외가 발생하면 다시 던집니다.
-
workletAnimation의 직렬화 옵션을 serializedOptions로 설정합니다.
-
workletAnimation의 애니메이션 애니메이터 이름을 animatorName으로 설정합니다.
5.3. 워크릿 애니메이션 타이밍 모델
이 섹션에서는 워크릿 애니메이션의 타이밍 모델이 다른 애니메이션과 어떻게 다른지 설명합니다.
기존 애니메이션이 준비됨으로 간주되는 조건에 추가로, 워크릿 애니메이션은 다음 조건이 참일 때에만 준비됨으로 간주됩니다:
-
사용자 에이전트가 워크릿 애니메이션에 대응되는 애니메이터 인스턴스를 생성하기 위해 필요한 모든 설정을 완료한 경우.
§5.1 워크릿 애니메이션에서 설명했듯이, 워크릿 애니메이션의 현재 시간은
애니메이션 효과의 로컬 시간을 결정하지 않습니다.
대신 연결된 애니메이터 인스턴스가
애니메이션 효과의 로컬 시간을 직접 제어합니다. 즉,
애니메이션 효과의 로컬 시간은 병렬 실행 컨텍스트에 있을 수 있는 WorkletGlobalScope
에서 제어됩니다.
위 의미론의 몇 가지 시사점은 다음과 같습니다:
-
현재 시간이나 시작 시간을 워크릿 애니메이션에 설정해도 출력이 반드시 변경되지는 않지만, 애니메이션의 재생 상태는 변경될 수 있습니다.
-
마찬가지로
finish()
를 호출하거나 워크릿 애니메이션의 재생 속도를 업데이트하면 애니메이션의 재생 상태만 변경되며, 출력은 변경되지 않을 수 있습니다. -
getComputedTiming()
으로 애니메이션 효과의 로컬 시간을 조회하면, 애니메이터 인스턴스가 병렬 실행 컨텍스트에서 실행 중인 경우, 오래된 정보가 반환될 수 있습니다.
워크릿 애니메이션이 병렬 워크릿 실행 컨텍스트에서 실행되는 경우, 애니메이션 효과의 마지막 알려진 상태가 주기적으로 메인 자바스크립트 실행 컨텍스트로 동기화되어야 합니다. 병렬 워크릿 실행 컨텍스트에서 메인 자바스크립트 실행 컨텍스트로 효과 값의 동기화는 문서 라이프사이클의 일부로 애니메이션 프레임 콜백 실행 전에 반드시 발생해야 합니다. 이 애니메이션 모델의 비동기적 특성 때문에, 메인 자바스크립트 실행 컨텍스트에서 Worklet Animation으로 애니메이션되는 대상 속성을 읽을 때, 사용자에게 보여지는 시각적 프레임에서 사용 중인 값과 비교해 오래된 값을 볼 수 있습니다. 이는 메인 자바스크립트 실행 컨텍스트에서 스크롤 오프셋을 읽을 때 비동기 스크롤의 효과와 유사합니다.
애니메이터 인스턴스가 reverse(), finish(), playbackRate 변경 등으로 애니메이션의 currentTime이 변경될 때 알림을 받을 수 있는 적절한 메커니즘을 마련해야 합니다. 그래야 적절히 반응할 수 있습니다. <https://github.com/w3c/css-houdini-drafts/issues/811>
5.4. 애니메이터 인스턴스와의 상호작용
워크릿 애니메이션은 언제든지 최대 하나의 애니메이터 인스턴스에 대응되며, 현재 대응되는 애니메이터 인스턴스가 없을 수도 있습니다. 워크릿 애니메이션에 대한 애니메이터 인스턴스의 대응 관계는 애니메이션의 재생 상태에 따라 달라집니다.
워크릿 애니메이션의 애니메이터 인스턴스 연결을 위해 workletAnimation이 주어지면, 사용자 에이전트는 다음 단계를 반드시 실행해야 합니다:
-
workletAnimation에 대응되는 애니메이터 인스턴스가 있으면 다음 단계를 중단합니다.
-
workletGlobalScope를 workletAnimation과 연관된
AnimationWorkletGlobalScope
로 설정합니다. -
workletGlobalScope에서 새 애니메이터 인스턴스 생성 절차를 실행하도록 태스크를 큐에 넣고, 아래 인수를 전달합니다:
-
workletAnimation의 애니메이션 애니메이터 이름을 name으로.
-
workletAnimation의 타임라인을 timeline으로.
-
workletAnimation의 애니메이션 효과를 effect로.
-
workletAnimation의 직렬화 옵션을 options로.
-
workletGlobalScope를 workletGlobalScope로.
-
-
절차가 성공하면, 결과 애니메이터 인스턴스를 workletAnimation과 연결된 것으로 설정합니다.
워크릿 애니메이션의 애니메이터 인스턴스 연결 해제을 위해 workletAnimation이 주어지면, 사용자 에이전트는 다음 단계를 반드시 실행해야 합니다:
-
workletAnimation에 대응되는 애니메이터 인스턴스가 없으면 다음 단계를 중단합니다.
-
workletGlobalScope를 workletAnimation과 연관된
AnimationWorkletGlobalScope
로 설정합니다. -
animatorInstance를 workletAnimation의 대응 애니메이터 인스턴스로 설정합니다.
-
workletGlobalScope에서 애니메이터 인스턴스 제거 절차를 animatorInstance와 workletGlobalScope를 인수로 하여 실행하도록 태스크를 큐에 넣습니다.
-
workletAnimation이 대응되는 애니메이터 인스턴스가 없도록 설정합니다.
워크릿 애니메이션의 애니메이터 인스턴스 설정을 위해 workletAnimation이 주어지면, 사용자 에이전트는 다음 단계를 반드시 실행해야 합니다:
-
워크릿 애니메이션의 애니메이터 인스턴스 연결 해제 절차를 workletAnimation에 대해 실행합니다.
-
워크릿 애니메이션의 애니메이터 인스턴스 연결 절차를 workletAnimation에 대해 실행합니다.
workletAnimation의 재생 상태가 대기중, 실행중, 또는 일시정지로 변경되면, 워크릿 애니메이션의 애니메이터 인스턴스 연결 절차를 workletAnimation에 대해 실행합니다.
workletAnimation의 재생 상태가 대기 또는 종료됨으로 변경되면, 워크릿 애니메이션의 애니메이터 인스턴스 연결 해제 절차를 workletAnimation에 대해 실행합니다.
workletAnimation에 대해 애니메이션의 대상 효과 설정 절차가 호출되면, 워크릿 애니메이션의 애니메이터 인스턴스 설정 절차를 workletAnimation에 대해 실행합니다.
workletAnimation에 대해 애니메이션의 타임라인 설정 절차가 호출되면, 워크릿 애니메이션의 애니메이터 인스턴스 설정 절차를 workletAnimation에 대해 실행합니다.
5.5. ScrollTimeline
이 섹션은 규범적인 내용이 아닙니다.ScrollTimeline
은 웹 애니메이션 API에 새롭게 제안된 개념입니다. 이 타임라인은 스크롤 컨테이너의 스크롤 위치에 따라 시간값이 결정됩니다. 워크릿 애니메이션
은 스크롤 타임라인을 가질 수 있어, 스크롤 오프셋에 따라 스크립트 효과를 구동할 수 있습니다.
참고: 입력 접근성: 우리는 스크롤링 외에도 추가적인 사용자 입력(예: 터치/포인터 입력)을 이러한 애니메이션에 노출하는 것에 관심이 있습니다. 이를 통해 저지연, 입력 기반 애니메이션(현재로서는 불가능한)을 만들 수 있기 때문입니다. 올바른 추상화와 메커니즘을 찾기 위해 계속 논의 중입니다.
5.6. WorkletGroupEffect
WorkletGroupEffect
는 그룹 효과의 한 종류로, 자식 효과의
로컬
시간을 개별적으로 변경할 수 있게 해줍니다.
WorkletGroupEffect
가 애니메이션 효과로 WorkletAnimation
에 설정되면,
해당 애니메이터 인스턴스는 자식 효과의 로컬 시간을 직접 제어할 수
있습니다. 하나의 워크릿 애니메이션으로 여러 효과를 조정할 수 있습니다. 예시는 §8.2 예제 2: 패럴럭스 배경에서 확인할 수 있습니다.
[Exposed =AnimationWorklet ]interface {
WorkletGroupEffect sequence <AnimationEffect >(); }; [
getChildren Exposed =AnimationWorklet ]partial interface AnimationEffect { // Intended for use inside Animation Worklet scope to drive the effect.attribute double ; };
localTime
effect의 localTime
속성을 값 t로 설정하려면, 사용자 에이전트는 다음 조건 중 처음 일치하는 것에 따라 동작해야 합니다:
- effect가 부모 그룹이 없는 경우,
-
effect의 로컬 시간을 t로 설정합니다.
- effect가 부모 그룹을 가지고 있고, 그 타입이
WorkletGroupEffect
인 경우, -
effect의 시작 시간을 (부모의 변환된 시간 - t)로 설정합니다. 즉, effect의 로컬 시간은 t가 됩니다.
- 그 외의 경우
-
자식 효과의 시간은 부모 그룹만 제어할 수 있음을 알리는 예외를 발생시킵니다.
위 인터페이스는 web-animation-2의 GroupEffect 제안의 보수적인 서브셋만 노출합니다. 대신, web-animation에 대한 델타 명세로 이동되어야 합니다. <https://github.com/w3c/csswg-drafts/issues/2071>
5.7. Effect Stack 및 합성 순서
다른 애니메이션과 마찬가지로, 워크릿 애니메이션도 효과 스택에 참여합니다. 워크릿 애니메이션은 특정 애니메이션 클래스가 없으므로, 다른 자바스크립트 기반 웹 애니메이션과 동일한 합성 순서를 가집니다.
6. 보안 고려사항
이 기능들로 인해 알려진 보안 문제는 없습니다.
7. 개인정보 보호 고려사항
이 기능들로 인해 알려진 개인정보 문제는 없습니다.
8. 예제
8.1. 예제 1: 트위터 헤더.
트위터 프로필 헤더 효과의 예시로, 두 요소(아바타와 헤더)가 스크롤 오프셋에 맞춰 동기적으로 업데이트됩니다.// 문서 스코프에서.< div id = 'scrollingContainer' > < div id = 'header' style = 'height: 150px' ></ div > < div id = 'avatar' >< img ></ div > </ div > < script > await CSS. animationWorklet. addModule( 'twitter-header-animator.js' ); const animation= new WorkletAnimation( 'twitter-header' , [ new KeyframeEffect( $avatar, /* 스크롤 시 크기 축소 */ [{ transform: 'scale(1)' }, { transform: 'scale(0.5)' }], { duration: 1000 , iterations: 1 }), new KeyframeEffect( $header, /* 스크롤 시 투명도 증가 */ [{ opacity: 0 }, { opacity: 0.8 }], { duration: 1000 , iterations: 1 })], new ScrollTimeline({ scrollSource: $scrollingContainer, orientation: 'block' , timeRange: 1000 , startScrollOffset: 0 , endScrollOffset: $header. clientHeight})); animation. play(); // 그룹 효과를 사용하는 이 애니메이션은 // $avatarEl.getAnimations()[0], $headerEl.getAnimations()[0] 등 다양한 핸들에서 접근 가능합니다. </ script >
// AnimationWorkletGlobalScope 내에서. registerAnimator( 'twitter-header' , class HeaderAnimatorextends StatelessAnimator{ constructor( options) { this . timing_= new CubicBezier( 'ease-out' ); } animate( currentTime, effect) { const scroll= currentTime; // scroll 값은 [0, 1000] 범위 // 그룹 효과의 각 자식 localTime을 개별적으로 할당하여 제어 effect. children[ 0 ]. localTime= scroll; effect. children[ 1 ]. localTime= this . timing_( clamp( scroll, 0 , 500 )); } }); function clamp( value, min, max) { return Math. min( Math. max( value, min), max); }
8.2. 예제 2: 패럴럭스 배경.
간단한 패럴럭스 배경 예제입니다.< style > . parallax { position : fixed ; top : 0 ; left : 0 ; opacity : 0.5 ; } </ style > < div id = 'scrollingContainer' > < div id = "slow" class = "parallax" ></ div > < div id = "fast" class = "parallax" ></ div > </ div > < script > await CSS. animationWorklet. addModule( 'parallax-animator.js' ); const scrollTimeline= new ScrollTimeline({ scrollSource: $scrollingContainer, orientation: 'block' , timeRange: 1000 }); const scrollRange= $scrollingContainer. scrollHeight- $scrollingContainer. clientHeight; const slowParallax= new WorkletAnimation( 'parallax' , new KeyframeEffect( $parallax_slow, [{ 'transform' : 'translateY(0)' }, { 'transform' : 'translateY(' + - scrollRange+ 'px)' }], { duration: 1000 }), scrollTimeline, { rate: 0.4 } ); slowParallax. play(); const fastParallax= new WorkletAnimation( 'parallax' , new KeyframeEffect( $parallax_fast, [{ 'transform' : 'translateY(0)' }, { 'transform' : 'translateY(' + - scrollRange+ 'px)' }], { duration: 1000 }), scrollTimeline, { rate: 0.8 } ); fastParallax. play(); </ script >
// AnimationWorkletGlobalScope 내부. registerAnimator( 'parallax' , class ParallaxAnimatorextends StatelessAnimator{ constructor( options) { this . rate_= options. rate; } animate( currentTime, effect) { effect. localTime= currentTime* this . rate_; } });