1. はじめに
このセクションは規範的ではありません。この文書では、ウェブアニメーションの拡張性を提供し、ウェブ上で高パフォーマンスなインタラクティブな手続き型アニメーションを可能にする新しいプリミティブを紹介します。詳細な動機や背景については [explainer] および [principles] を参照してください。
Animation Worklet APIは、一連のアニメーション効果を制御するスクリプトアニメーションを作成するための方法を提供します。このAPIは、ユーザーエージェントがそのようなアニメーションを専用スレッドで実行し、メインスレッドから分離したパフォーマンスを一定程度確保できるように設計されています。
1.1. Web Animations APIとの関係
このセクションは規範的ではありません。Animation
Worklet実行コンテキスト内で動作するアニメーションは、メインのJavaScript実行コンテキスト上でWeb Animations仕様のAnimation
インターフェイスを公開します。つまり、メインスレッドから同じWeb Animation APIを使って制御や検査が可能です。
2. Animation Worklet
Animation Workletは、Worklet
であり、カスタムアニメーションに関連するすべてのクラスを管理します。このworkletはanimationWorklet
属性からアクセスできます。
animationWorklet
の
workletグローバルスコープ型はAnimationWorkletGlobalScope
です。
AnimationWorkletGlobalScope
はanimationWorklet
のグローバルな実行コンテキストを表します。
[Exposed =Window ]partial namespace CSS { [SameObject ]readonly attribute Worklet ; };
animationWorklet
3. Animator
Animatorは、アニメーションスレッド上で動作するアニメーションインスタンスを表します。
Animatorは一意の名前によって識別され、現在の入力時間に応じてアニメーションのキーフレーム効果がどのように進行するかを決定します。AnimatorインスタンスはAnimationWorkletGlobalScope
内に存在し、各インスタンスはWorkletAnimation
インスタンスに関連付けられています。AnimatorはWorkletAnimation
の構築によってのみインスタンス化されます。
2種類のAnimatorがサポートされています: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
を管理します。アニメーションワークレットは、(例:リソースを節約するため)グローバルスコープを一時的に終了したり、(例:特定のスレッドでのみエフェクトが変更可能な場合)実行中のアニメーターインスタンスを異なるグローバルスコープへ移行させることがあります。アニメーションワークレットは、ステートフルアニメーターインスタンスの状態が、インスタンスが異なるグローバルスコープで再生成されても保持されることを保証します。
状態維持の基本的な仕組みは、アニメーションワークレットがlocal stateとしてstate
関数を通じて公開される情報をスナップショットし、後で異なるグローバルスコープでインスタンスが再生成される際に、コンストラクタに渡せるように再現することです。アニメーターインスタンスの移行アルゴリズムは、このプロセスの詳細を記載しています。
ユーザー定義のステートフルアニメーターは、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
コールバック関数型です。 -
ステートフルフラグ
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がアニメーター名とアニメーター定義のマップのキーとして存在する場合、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
-
-
キーと値のペア(name - definition)をアニメーター名とアニメーター定義のマップに追加する。
4. アニメーターインスタンス
アニメーターインスタンスは、構造体であり、AnimationWorkletGlobalScope
内で完全に実現されたカスタムアニメーションインスタンスを記述します。
アニメーター定義への参照を持ち、アニメーション効果やタイムラインなどインスタンス固有の状態を所有します。以下を含みます:
-
アニメーター効果(animation effect)
-
アニメーター現在時刻(対応するworklet animationの現在時刻)
-
アニメータ―タイムライン(timeline)
-
アニメーターシリアライズオプション(シリアライズ可能なオブジェクト)
ステートフルアニメーターインスタンスは、対応するアニメーターインスタンスのアニメーター定義のステートフルフラグがtrueのものです。
4.1. アニメーターインスタンスの作成
各アニメーターインスタンスはAnimationWorkletGlobalScope
内に存在します。
各AnimationWorkletGlobalScope
はアニメーターインスタンス集合を持ちます。この集合は、ユーザーエージェントがAnimationWorkletGlobalScope
スコープ内で新しいアニメーターインスタンスを構築した時に登録されます。各アニメーターインスタンスはドキュメントスコープ内のworklet
animationに対応します。
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»、コールバックthis値はinstance)。
animateFunctionが例外を投げた場合の挙動を明示するべきです。少なくとも、キー フレームのlocalTime値は無視されるため、誤った部分更新が発生しない旨の文言が必要です。
4.3. アニメーターインスタンスの削除
instanceとworkletGlobalScopeが与えられたとき、アニメーターインスタンスを削除するには、ユーザーエージェントは以下の手順を必ず実行します:
-
instanceをworkletGlobalScopeのアニメーターインスタンス集合から削除する。
4.4. アニメーターインスタンスの移行
移行プロセスでは、ステートフルアニメーターインスタンスを別のWorkletGlobalScope
にローカル状態を失うことなく移行できます。
ある WorkletGlobalScope
から別の WorkletGlobalScope
へ アニメーターインスタンスを移行するには、instance、sourceWorkletGlobalScope、destinationWorkletGlobalScope
が与えられた場合、ユーザーエージェントは以下の手順を 必ず 実行しなければならない:
-
serializedStateを未定義とする。
-
タスクをキューし、sourceWorkletGlobalScopeで以下の手順を実行する:
-
animatorNameをinstanceのアニメーター名とする。
-
definitionをsourceWorkletGlobalScopeのアニメーター名とアニメーター定義のマップから検索した結果とする。
definitionが存在しなければ、以降の手順を中止する。
-
statefulをdefinitionのステートフルフラグとする。
-
statefulがfalseなら、以降の手順を中止する。
-
stateFunctionを取得する。
-
stateをstateFunctionを呼び出し、コールバックthis値としてinstanceを渡す結果とする。例外が発生した場合は再スローし、以降の手順を中止する。
-
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に設定されることがあります。例:
-
アニメーターのcurrent time(現在時刻)がタイムライン上で変化したとき
-
アニメーターの対応するWorklet Animationのcurrent timeが変化したとき
§4.2 アニメーターの実行では、アニメーターのアニメーションリクエストフラグをframe-currentにリセットします。
5. Web Animations統合
5.1. Worklet Animation
Worklet Animationは、アニメーションの一種であり、アニメーション再生をアニメーターインスタンスに委譲します。対応するアニメーターインスタンスのライフタイムや再生状態を制御します。アニメーションであるため、Worklet Animationはアニメーション効果とタイムラインを持ちます。ただし他のアニメーションとは異なり、Worklet Animationの現在時刻はアニメーション効果のlocal time(inherited time経由)を直接決定しません。 代わりに、関連するアニメーターインスタンスがアニメーション効果のlocal timeを直接制御します。つまり、タイムラインの現在時刻だけではアニメーションの出力は完全に決定されません。
Worklet
Animationは、Animation
インターフェイスに加えて、以下のプロパティを持ちます:
-
animation animator name(自身のアニメーター定義を識別する)
-
serialized options(新しいアニメーターインスタンスの構築時に使われるシリアライズ可能なオブジェクト)
アニメーションの現在時刻はアニメーターインスタンスへの入力となり、アニメーション効果のローカル時刻値を生成します。アニメーターインスタンスが並列グローバルスコープで実行されている場合、実装はローカル時刻値を用いて最終的な効果値を生成し、ビジュアルの更新を並列で行うこともできます。
5.2. Worklet Animationの作成
[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引数が指定されていればそれを新しいタイムラインとして渡し、指定されていなければ関連する
Document
のデフォルトドキュメントタイムラインを渡す。Window
は現在のグローバルオブジェクトである。 -
以下の最初に一致する条件に従ってeffectを決定する。
- もしeffectsが
AnimationEffect
オブジェクトの場合、 -
effectはeffectsとする。
- もしeffectsが
AnimationEffect
オブジェクトのリストの場合、 -
effectは子をeffectsとする新しい
WorkletGroupEffect
とする。 - それ以外の場合、
-
effectは未定義とする。
- もしeffectsが
-
workletAnimationに対してアニメーションのターゲット効果を設定する手順を実行し、effectを新しい効果として渡す。
-
serializedOptionsをStructuredSerialize(options)の結果とする。例外が発生した場合は再スローする。
-
workletAnimationのシリアライズオプションにserializedOptionsを設定する。
-
workletAnimationのanimation animator nameにanimatorNameを設定する。
5.3. Worklet Animationのタイミングモデル
このセクションでは、worklet animationのタイミングモデルが他のアニメーションとどのように異なるかを説明します。
既存のアニメーションがreadyとみなされる条件に加え、worklet animationは以下の条件が満たされた場合にのみreadyとみなされます:
-
ユーザーエージェントがworklet animationに対応するanimator instanceの作成に必要なセットアップを完了していること。
§5.1 Worklet Animationで説明されている通り、worklet animationのcurrent
timeは、そのanimation effectのlocal
timeを決定しません。代わりに、関連付けられたanimator instanceがlocal
timeを直接制御します。つまり、アニメーション効果のlocal timeはWorkletGlobalScope
(並列実行コンテキストである可能性があります)から制御されます。
上記の意味論から導かれる影響は以下の通りです:
-
current timeやstart timeをworklet animationに設定しても必ずしも出力が変化するわけではなく、アニメーションのplay stateが変化する場合があります。
-
同様に、
finish()
の呼び出しやworklet animationのplayback rateの更新は、アニメーションのplay stateのみを変更し、出力が変化しない場合があります。 -
getComputedTiming()
でアニメーション効果のlocal timeを取得すると、animator instanceが並列実行コンテキストで動作している場合、古い情報が返されることがあります。
Worklet Animationが並列worklet実行コンテキストで実行されている場合、そのアニメーション効果の最新状態は定期的にメインJavaScript実行コンテキストに同期されるべきです。並列worklet実行コンテキストからメインJavaScript実行コンテキストへのeffect valuesの同期は、ドキュメントライフサイクルの一部としてアニメーションフレームコールバックが実行される前に必ず行われなければなりません。このアニメーションモデルの非同期性により、メインJavaScript実行コンテキストでWorklet Animationでアニメーションされているtarget propertyをスクリプトから読み取る場合、ユーザーに表示されているビジュアルフレームで使われている値と比べて古い値が表示される場合があります。これはメインJavaScript実行コンテキストでスクロールオフセットを読むときの非同期スクロールの効果に類似しています。
animator instanceがanimation currentTimeの変更(例えばreverse()、finish()、playbackRateの変更)を通知される適切な仕組みを考案すべきです。これにより適切に反応できるようになります。<https://github.com/w3c/css-houdini-drafts/issues/811>
5.4. アニメーターインスタンスとの連携
worklet animationは任意の時点で最大1つのanimator instanceに対応し、対応するanimator instanceが存在しない場合もあります。worklet animationに対するanimator instanceの対応関係は、アニメーションのplay stateに依存します。
worklet animationのanimator instanceを関連付けるにはworkletAnimationが与えられたとき、ユーザーエージェントは以下の手順を必ず実行します:
-
workletAnimationに対応するanimator instanceが存在する場合、以降の手順を中止する。
-
workletGlobalScopeをworkletAnimationに関連付けられた
AnimationWorkletGlobalScope
とする。 -
taskをworkletGlobalScopeでキューイングし、以下の値を渡して新しいanimator instanceを作成する手順を実行する:
-
workletAnimationのanimation animator name(nameとして)
-
workletAnimationのtimeline(timelineとして)
-
workletAnimationのanimation effect(effectとして)
-
workletAnimationのserialized options(optionsとして)
-
workletGlobalScope(workletGlobalScopeとして)
-
-
手順が成功した場合、結果のanimator instanceをworkletAnimationに対応させる。
worklet animationのanimator instanceの関連付け解除にはworkletAnimationが与えられたとき、ユーザーエージェントは以下の手順を必ず実行します:
-
workletAnimationに対応するanimator instanceが存在しない場合、以降の手順を中止する。
-
workletGlobalScopeをworkletAnimationに関連付けられた
AnimationWorkletGlobalScope
とする。 -
animatorInstanceをworkletAnimationの対応するanimator instanceとする。
-
taskをworkletGlobalScopeでキューイングし、animatorInstance(instanceとして)、workletGlobalScope(workletGlobalScopeとして)を渡してanimator instanceを削除する手順を実行する。
-
workletAnimationは対応するanimator instanceを持たない状態にする。
worklet animationのanimator instanceをセットするにはworkletAnimationが与えられたとき、ユーザーエージェントは以下の手順を必ず実行します:
-
worklet animationのanimator instanceの関連付け解除の手順をworkletAnimationに対して実行する。
-
worklet animationのanimator instanceを関連付ける手順をworkletAnimationに対して実行する。
与えられたworkletAnimationのplay stateがpending、running、またはpausedに変化した場合、worklet animationのanimator instanceを関連付ける手順をworkletAnimationに対して実行する。
与えられたworkletAnimationのplay stateがidleまたはfinishedに変化した場合、worklet animationのanimator instanceの関連付け解除手順をworkletAnimationに対して実行する。
与えられたworkletAnimationに対してset the target effect of an animation手順が呼ばれた場合、worklet animationのanimator instanceをセットする手順をworkletAnimationに対して実行する。
与えられたworkletAnimationに対してset the timeline of an animation手順が呼ばれた場合、worklet animationのanimator instanceをセットする手順をworkletAnimationに対して実行する。
5.5. ScrollTimeline
このセクションは規範的ではありません。ScrollTimeline
はウェブアニメーションAPIに追加提案されている新しい概念です。スクロールコンテナのスクロール位置に応じて時間値が変化するアニメーションタイムラインを定義します。Workletアニメーションはスクロールタイムラインを持つことができ、スクロールオフセットに基づいてスクリプト効果を駆動できます。
注: 入力へのアクセス: スクロール以外にも(タッチやポインター入力など)、追加のユーザー入力をこれらのアニメーションに公開することに関心があります。これにより、著者は現在は困難な入力駆動型のジャンクのないアニメーションを作成できるようになります。適切な抽象化やメカニズムを検討中です。
5.6. WorkletGroupEffect
WorkletGroupEffect
はグループエフェクトの一種であり、子エフェクトのlocalTimeを個別に操作できます。
WorkletGroupEffect
がWorkletAnimation
のanimation effectに設定されている場合、対応するanimator instanceは子エフェクトのlocalTimeを直接制御できます。これにより、1つのworkletアニメーションで複数のエフェクトを連携させることができます。使用例は§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のlocalTimeをtに設定する。
- 親グループがあり、その型が
WorkletGroupEffect
の場合 -
effectのstartTimeを(親の変換後の時間 - t)に設定する。これは実質的にeffectのlocalTimeをtに設定することになります。
- それ以外の場合
-
子エフェクトの時間は親グループによってのみ制御可能であることを示す例外を投げる。
上記インターフェースはweb-animation-2で提案されているGroupEffectの保守的なサブセットのみを公開しています。代わりにweb-animationへの差分仕様に移行すべきです。<https://github.com/w3c/csswg-drafts/issues/2071>
5.7. エフェクトスタックと合成順序
他のアニメーションと同様に、workletアニメーションはエフェクトスタックに参加します。workletアニメーションは特定のanimation classを持たないため、他のJavaScriptで作成されたWebアニメーションと同じ合成順序となります。
6. セキュリティの考慮事項
これらの機能による既知のセキュリティ問題はありません。
7. プライバシーの考慮事項
これらの機能による既知のプライバシー問題はありません。
8. 例
8.1. 例1: Twitterヘッダー
Twitterプロフィールヘッダー効果の例。2つの要素(アバターとヘッダー)がスクロールオフセットと同期して更新されます。// 文書スコープ内。< 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_; } });