1. はじめに
Web Animationsは、Webプラットフォーム上でアニメーションと同期をサポートするためのモデルを定義します。 他の仕様がこのモデルを基盤として、宣言的な手段でその機能を公開することを想定しています。 さらに、この仕様はスクリプト対応のユーザーエージェントによって実装可能な、モデルへのプログラミングインターフェースも定義します。
1.1. ユースケース
Web Animationsモデルは、CSS Transitions [CSS-TRANSITIONS-1]、 CSS Animations [CSS-ANIMATIONS-1]、 SVG [SVG11]を表現するために必要な機能を提供することを目的としています。 そのため、Web Animationsモデルのユースケースはこれら3つの仕様のユースケースの集合となります。
プログラミングインターフェースのユースケースには次のようなものがあります:
- 実行中のアニメーションの調査
-
Webアプリケーションでは、特定のアニメーション効果が完了するまで状態更新を待機する必要がある場合がよくあります。 この仕様のプログラミングインターフェースを使えば、現在実行中のすべてのアニメーションの完了を待機できます。 それらがCSS Transitions、CSS Animations、SVGアニメーション、またはプログラミングインターフェースで直接作成されたものであっても関係ありません。
// すべてのアニメーションが終了したら要素を削除する Promise. all( elem. getAnimations(). map( animation=> animation. finished) ). then(() => elem. remove()); また、アプリケーションによっては、待機せずにアニメーションの再生状態を問い合わせたい場合もあります。
- 実行中のアニメーションの制御
-
アニメーションを外部入力に応じて制御できると便利な場合があります。 例えば、モーダルダイアログ表示前に既存のアニメーションすべてを一時停止し、ユーザーの注意をそらさないようにする必要があるかもしれません。
- スクリプトによるアニメーションの作成
-
ECMAScriptで
requestAnimationFrame
[HTML]を使ってアニメーションすることも可能ですが、 そのようなアニメーションは宣言的アニメーションとは、CSSカスケードでの表現や別スレッドで実行可能などのパフォーマンス最適化の点で挙動が異なります。 Web Animationsプログラミングインターフェースを使えば、宣言的アニメーションと同じ挙動・パフォーマンス特性を持ったスクリプトによるアニメーションを作成できます。 - アニメーションのデバッグ
-
複雑なアプリケーションでは、要素が現在の状態に至った理由を把握するのが困難な場合があります。 Web Animationsプログラミングインターフェースを使えば、 実行中のアニメーションを調査して「なぜこの要素のopacityが変化しているのか?」などの疑問に答えることができます。
// elem上のopacityアニメーションのidを出力する for ( const animationof elem. getAnimations()) { if ( animation. effectinstanceof KeyframeEffect&& animation. effect. getKeyframes() . some( frame=> frame. hasOwnProperty( 'opacity' )) ) { console. log( animation. id); } } 同様に、アニメーションを細かく調整するには再生速度を落として再再生することがよくあります。
// transformアニメーションを遅くして再生する const transformAnimations= elem. getAnimations(). filter( animation=> animation. effectinstanceof KeyframeEffect&& animation. effect. getKeyframes(). some( frame=> frame. hasOwnProperty( 'transform' ) ) ); for ( const animationof transformAnimations) { animation. currentTime= 0 ; animation. updatePlaybackRate( 0.5 ); } - アニメーションのテスト
-
アニメーションを利用するアプリケーションをテストする際、アニメーションが完了するまで待つのは現実的でない場合が多いです。 そのため、アニメーションを特定の時刻にシークすることが望ましいです。
// アニメーションの半分までシークしてopacityが50%か確認 for ( const animationof elem. getAnimations()) { const { delay, activeDuration} = animation. effect. getComputedTiming(); animation. currentTime= delay+ activeDuration/ 2 ; } assert. strictEqual( getComputedStyle( elem). opacity, '0.5' ); // アニメーション終了後にロード画面が非表示になることを確認 for ( const animationof elem. getAnimations()) { animation. finish(); } // イベントハンドラが動作するよう1フレーム待つ requestAnimationFrame(() => { assert. strictEqual( getComputedStyle( document. querySelector( '#loading' )). display, 'none' ); });
1.2. 他の仕様との関係
CSS Transitions [CSS-TRANSITIONS-1]、CSS Animations [CSS-ANIMATIONS-1]、 SVG [SVG11]はすべてWebページ上でアニメーションコンテンツを生成する仕組みを提供します。 これら3つの仕様は多くの類似機能を提供しますが、記述方法は異なっています。 本仕様では3つの仕様の共通機能を包含する抽象的なアニメーションモデルを提案します。 このモデルはこれらの仕様の現行挙動と後方互換性があり、観測可能な変化なしにこのモデルで定義可能です。
SVG 1.1のアニメーション機能はSMIL Animation [SMIL-ANIMATION]で定義されています。 SVGのアニメーション機能をWeb Animationsモデルで定義することで、SVGとSMIL Animationの依存を排除できることを目指しています。
アニメーションフレームコールバック(通称"requestAnimationFrame")[HTML]のように、 本仕様のプログラミングインターフェース部分ではスクリプトからアニメーションを生成できます。 ただし本仕様で定義されたインターフェースで生成されたアニメーションは、生成後はユーザーエージェントによって完全に実行されるため、 マークアップで定義されたアニメーションと同じパフォーマンス特性を持ちます。 このインターフェースを用いることで、より簡単かつ高性能にスクリプトからアニメーションを作成できます。
プログラミングインターフェースで使用される時間値は アニメーションフレームコールバック [HTML]で使われるものと対応しており、両インターフェースが同時利用できるよう実行順序も定義されています。
本仕様のプログラミングインターフェース部分はHTML [HTML]で定義されているインターフェースにもいくつか追加を行います。
1.3. 本仕様の概要
本仕様はまずアニメーションの抽象モデルを定義します。 その後、この抽象モデルに基づいて定義されたプログラミングインターフェースについて説明します。 プログラミングインターフェースは抽象モデルに基づいて定義され、スクリプト対応のユーザーエージェントにのみ関係します。
2. 仕様の規約
この仕様は、アニメーションやアニメーション効果などの抽象概念、およびそれらに属する再生速度や反復期間などのプロパティについて説明することから始まります。 これらのプロパティに加えて、再生速度を設定する手順や開始時刻を設定する手順など、プロパティを更新するための特定の手続きが存在することがよくあります。
この仕様で特定の手順へのリンクがない場合、ユーザーエージェントがプロパティを更新するよう求められるテキスト(例:「animationの開始時刻を未解決にする」)は、関連する手順を呼び出すことなく直接プロパティを更新することを指すものと理解してください。
この仕様に特有でないさらなる文書規約については、文書の規約で説明されています。
3. ウェブアニメーションモデル概要
概観として、Webアニメーションモデルは主に2つの独立した構成要素、タイミングモデルとアニメーションモデルから構成されています。それぞれの役割は下記の通りです:
- タイミングモデル
-
ある時刻を受け取り、反復進捗と呼ばれるアニメーションの1回の反復内での割合に変換します。 また、いくつかのアニメーションが反復するたびに挙動が異なるため、反復インデックスも記録されます。
- アニメーションモデル
-
タイミングモデルによって生成された反復進捗値や反復インデックスを受け取り、それらをターゲットプロパティに適用する値の系列へと変換します。
この流れは、図示すると以下のように表せます:
現在時刻がタイミングモデルに入力され、反復進捗値と反復インデックスが生成されます。
これらのパラメータがアニメーションモデルの入力として使われ、適用する値が出力されます。
例として、以下のようなアニメーションを考えます:
-
3秒後に開始する
-
2回実行される
-
毎回2秒かかる
-
四角形の幅を50ピクセルから100ピクセルに変化させる
最初の3つのポイントはタイミングモデルに関係します。 6秒の時点ではアニメーションが2回目の反復の半分まで進んでいると計算され、0.5という結果を出します。 アニメーションモデルはその情報を用いて幅を計算します。
この仕様はタイミングモデルから始まり、続いてアニメーションモデルに進みます。
4. タイミングモデル
このセクションでは、Web Animationsタイミングモデルの挙動を説明・定義します。
4.1. タイミングモデル概要
このセクションは規範的ではありません
Web Animationsタイミングモデルには2つの特徴があります。ステートレスであり、階層構造を持ちます。
4.1.1. ステートレス
Web Animationsタイミングモデルは、入力時刻を受け取り、出力として反復進捗を生成します。 出力は入力時刻のみに基づき、過去の入力に依存しないため、このモデルはステートレスと記述できます。 この性質により、モデルには以下の特性があります:
- フレームレート非依存
-
出力は過去の入力に依存しないため、モデルの更新頻度が進捗に影響することはありません。 入力時刻が実時間の進捗に比例していれば、デバイスの性能に関係なくアニメーションは同じ速度で進行します。
- 方向非依存
-
入力の順序が重要でないため、モデルは方向性を持ちません。 そのため、モデルを任意の時刻に更新する際に特別な処理は不要です。
- 定数時間でのシーク
-
各入力が過去の入力と独立しているため、将来の任意の時刻へのシーク操作に必要な処理は、少なくとも理論上は定数時間です。
タイミングモデルのステートレスな挙動にはいくつか例外があります。
まず、モデルのプログラミングインターフェースで定義されたメソッドのいくつかは、 アニメーションの一時停止などの再生制御を提供します。 これらのメソッドは呼び出された時刻に基づいて定義されるため、状態的(stative)です。 これらのメソッドは主に利便性のために提供されており、コアのタイミングモデルには含まれず、上位レイヤーで実装されています。
同様に、アニメーションの終了時の挙動では、 メディア(関連効果)の終了時刻に動的な変更が加えられると、変更のタイミングによって異なる結果になることがあります。 この挙動は直感的かつHTMLと整合的であると判断されており、惜しいながらも採用されています。 そのため、モデルはタイミングプロパティに動的変更がない限りステートレスとみなせます。
最後に、モデルが更新されるたび、一時的な状態が確立されると考えられます。 この一時状態はプログラミングインターフェースから返される値に影響しますが、次回の更新には影響せず、上述のステートレスな性質と矛盾しません。
4.1.2. 階層構造
タイミングモデルのもう一つの特徴は、時間が継承されることです。 時間はタイムラインから始まり、複数のステップを経て各アニメーション効果へとカスケードします。 各ステップで、時間は前後にシフトしたり、スケールしたり、反転したり、一時停止したり、繰り返されたりします。
ツリー内の各ノードは親ノードから時間を取得します。
この仕様レベルでは階層は浅いですが、今後の仕様レベルでグループ効果の概念が導入され、より深いタイミング階層が可能になります。
4.2. 時間値
タイミングはタイミングノード間の階層的な時間関係に基づいています。 親ノードは時間値という形で子ノードにタイミング情報を提供します。
時間値は、ある瞬間からのミリ秒数を表す実数です。 時間値と実際の壁時計のミリ秒との関連は、 時間階層を通過する際に適用される様々な変換によって不明瞭になることがあります。
将来的には、スクロール位置やUIジェスチャーに基づくタイムラインもあり得ます。その場合、時間値とミリ秒との関係はさらに弱まります。
時間値は、例えばタイミングノードが時間値を生成できない状態の場合など、未解決にもなり得ます。
4.3. タイムライン
タイムラインは、同期のための時間値の発生源を提供します。
任意の時点で、タイムラインは、単一の現在の時間値を持ち、単純にタイムラインの現在時刻と呼ばれます。
タイムラインは、常に意味のある時間値を返すとは限らず、未解決な時間値しか返せない場合があります。 例えば、ドキュメントのloadイベント発火など、まだ発生していない瞬間を基準として定義されている場合です。 タイムラインは、その時間値が未解決である時、非アクティブタイムラインとみなされます。
タイムラインは、報告された現在時刻が前回の報告時点より常に大きいか等しい場合、単調増加タイムラインです。
特定の種類のタイムラインは、タイムライン時刻をオリジン基準時刻に変換する手順を定義でき、時間値timeに対して、壁時計ベースのタイムラインで生成された時間値同士を比較できるようにします。
タイムラインはドキュメントに関連付けられたタイムラインとなる場合があります。
アニメーションの更新とイベント送信をDocument
docでタイムスタンプnowに対して実行する場合、以下の手順を踏みます:
-
docに関連付けられた全ての現在時刻を持つタイムラインの現在時刻を、タイムスタンプとしてnowを渡して更新します。
タイミングモデルの階層性により、タイムラインの現在時刻を更新する際には、以下も含みます:
-
現在時刻が更新されたアニメーションに対してアニメーションの完了状態の更新手順を実行。
-
そのようなアニメーションのアニメーションイベントのキューイング。
-
置換されたアニメーションの削除をdocに対して行います。
-
注: これは、前のステップでタイムラインの更新の一環としてPromiseオブジェクトの解決や拒否によってキューされたマイクロタスクが、アニメーションイベントのディスパッチより先にコールバックされることを保証するためです。
-
events to dispatchをdocの保留中アニメーションイベントキューのコピーとする。
-
docの保留中アニメーションイベントキューをクリアする。
-
events to dispatch内のアニメーションイベントを以下の方法で安定ソートする:
注: イベントの順序を安定してソートする目的は、異なるデバイスの性能やフレームレートにかかわらず、できる限りイベントを一貫した順序でディスパッチするためです。
注: 安定ソートが必要なのは、同時刻でキューされるイベントが時々あるためです。たとえばCSSアニメーションでdurationが0の場合、
animationstart
とanimationend
両方のイベントが同時にディスパッチされ、その順序を保持する必要があります。 -
ディスパッチ手順に従い、events to dispatch内の各イベントを対応するターゲットに、前ステップで定めた順序で送信する。
この手順を実行するたび、新たなアニメーションフレームが確立されると表現すると便利な場合があります。 アニメーションやアニメーション効果のタイミングプロパティの変更やオブジェクトの追加・削除は、タイミングモデルやアニメーションモデルの出力を変化させることがありますが、これら操作自体は新しいアニメーションフレームを作成するのではなく、単に現在のアニメーションフレームを更新するだけです。
4.3.1. ドキュメントタイムライン
ドキュメントタイムラインは、タイムラインの一種であり、ドキュメントに関連付けられ、現在時刻が、アニメーションの更新とイベント送信手順が毎回実行される際に与えられるnowタイムスタンプからの固定オフセットとして計算されます。 この固定オフセットはドキュメントタイムラインの起点時刻と呼ばれます。
"origin time"より良い用語が必要です—"time origin"と似すぎています。[Issue #2079]
関連付けられたドキュメントのタイムオリジンが確立される前は、ドキュメントタイムラインは非アクティブです。
ドキュメントタイムラインがアクティブになると、単調増加となります。
ドキュメントタイムラインが、Document
で、アクティブなドキュメントでない場合も、非アクティブとみなされます。
タイムライン時刻timeline timeをオリジン基準時刻に変換するには、ドキュメントタイムラインtimelineに対して、timeline timeとtimelineの起点時刻の合計を返す。timelineが非アクティブの場合は、未解決の時間値を返す。
4.3.2. デフォルトドキュメントタイムライン
各Document
は、ドキュメントタイムラインを持ち、これをデフォルトドキュメントタイムラインと呼びます。
デフォルトドキュメントタイムラインは各ドキュメントごとに固有であり、document.open() [HTML]の呼び出しを含め、ドキュメントの存続期間中持続します。
デフォルトドキュメントタイムラインの起点時刻はゼロです。
ドキュメントタイムラインに渡されるnowタイムスタンプ値にはスケーリングが適用されないため、生成される時間値は壁時計のミリ秒に比例します。
さらに、デフォルトドキュメントタイムラインの時間値はタイムオリジンからのオフセットがゼロなので、
document.timeline.currentTime
はPerformance.now()
[HR-TIME]にほぼ対応します。ただしdocument.timeline.currentTime
は、アニメーションの更新とイベント送信手順の呼び出し間は変化しません。
4.4. アニメーション
タイムラインの子はアニメーションと呼ばれます。 アニメーションは、あるアニメーション効果(一定時間の挙動の静的な記述)を取り、それをタイムラインに結びつけて実行します。 アニメーションは、アニメーション効果とタイムラインとの接続を、再生・一時停止・シーク・速度制御などで実行時に制御できます。 アニメーションとアニメーション効果の関係は、DVDプレイヤーとDVDの関係に類似しています。
アニメーションは、単一のアニメーション効果(関連効果と呼ばれる)をタイムラインに結びつけ、再生制御を提供します。 これらの関連付けは両方とも任意かつ設定可能であり、 アニメーションは、ある時点で関連効果もタイムラインも持たない場合があります。
アニメーションのタイミング用ドキュメントは、そのタイムラインが関連付けられているDocument
です。
アニメーションがタイムラインに関連付けられていない場合や、そのタイムラインがドキュメントに関連付けられていない場合、タイミング用ドキュメントはありません。
アニメーションの開始時刻は、関連効果の再生開始が予定される時点のタイムラインの時間値です。 開始時刻は初期状態では未解決です。
アニメーションは、ホールド時刻(時間値)も保持しており、一時停止などの状況でアニメーションの出力時間値(現在時刻)を固定するために用いられます。 ホールド時刻も初期状態では未解決です。
競合するアニメーションの相対順序を確立するため、アニメーションは作成された順にグローバルアニメーションリストへ追加されます。ただし、特定のアニメーションクラスは、アニメーションの順序付けに別の方法を提供することがあります(§ 5.4.1 アニメーションクラス参照)。
4.4.1. アニメーションのタイムライン設定
アニメーションのタイムラインを設定する手順(animationをnew timelineに設定、nullも可)は次の通りです:
-
old timelineをanimationの現在のタイムライン(あれば)とする。
-
new timelineがold timelineと同じオブジェクトなら、この手順を中止する。
-
animationのタイムラインをnew timelineに設定する。
-
animationの開始時刻が解決済みなら、animationのホールド時刻を未解決にする。
注: このステップは、animationの完了再生状態が「固着」せず、更新された現在時刻に基づいて再評価されることを保証します。
-
animationに対して、did seekフラグをfalse、synchronously notifyフラグをfalseに設定し、アニメーションの完了状態の更新手順を実行する。
4.4.2. アニメーションの関連効果設定
アニメーションの関連効果を設定する手順(animationをnew effectに設定、nullも可)は次の通りです:
-
old effectをanimationの現在の関連効果(あれば)とする。
-
new effectがold effectと同じオブジェクトなら、この手順を中止する。
-
animationに保留中一時停止タスクがあれば、animationがreadyになるとすぐにそのタスクを再スケジュールする。
-
animationに保留中再生タスクがあれば、animationがreadyになりnew effectを再生できるときにそのタスクを再スケジュールする。
-
new effectが
null
でなく、かつnew effectが他のアニメーション(previous animation)の関連効果である場合、previous animationに対しこの手順をnullをnew effectとして再実行する。 -
animationの関連効果をnew effectにする。
-
animationに対して、did seekフラグをfalse、synchronously notifyフラグをfalseに設定し、アニメーションの完了状態の更新手順を実行する。
4.4.3. アニメーションの現在時刻
アニメーションは、関連効果に対して時間値を提供し、それをアニメーションの現在時刻と呼びます。
現在時刻は以下から最初に一致する条件で計算されます:
4.4.4. アニメーションの現在時刻の設定
アニメーションの現在時刻は新しい値に設定することができ、アニメーションをシークできます。 現在時刻の設定手順は2つの部分に分かれています。
現在時刻を静かに設定する手順(animationの現在時刻をseek timeに設定)は次の通りです:
-
seek timeが未解決な時間値の場合、以下の手順を実行する。
-
animationに関連付けられたタイムラインがない、または関連タイムラインが非アクティブなら、animationの開始時刻を未解決にする。
これは、アクティブなタイムラインがない場合、開始時刻または現在時刻のどちらかだけを設定できるという不変条件を保持します。
現在時刻を設定する手順(animationの現在時刻をseek timeに設定)は次の通りです:
-
animationの現在時刻をseek timeに静かに設定する手順を実行する。
-
animationに保留中一時停止タスクがあれば、次の手順で一時停止操作を同期的に完了する:
-
animationのホールド時刻をseek timeに設定する。
-
保留中再生速度をanimationに適用する。
-
保留中一時停止タスクをキャンセルする。
-
resolve手順でanimationの現在のreadyプロミスをanimationで解決する。
-
-
animationに対して、did seekフラグをtrue、synchronously notifyフラグをfalseに設定し、アニメーションの完了状態の更新手順を実行する。
4.4.5. アニメーションの開始時刻の設定
開始時刻を設定する手順(animation、animationの開始時刻をnew start timeに設定)は次の通りです:
-
timeline timeを、animationに関連付けられたタイムラインの現在の時間値とする。 animationに関連付けられたタイムラインがない、または関連タイムラインが非アクティブの場合は、timeline timeを未解決とする。
-
timeline timeが未解決かつnew start timeが解決済みの場合、animationのホールド時刻を未解決にする。
-
previous current timeをanimationの現在時刻とする。
-
保留中再生速度の適用をanimationに行う。
-
animationの開始時刻をnew start timeに設定する。
-
animationのホールド時刻を下記から最初に一致する条件で更新する:
-
animationに保留中再生タスクまたは 保留中一時停止タスクがあれば、そのタスクをキャンセルし、resolve手順で animationの現在のreadyプロミスをanimationで解決する。
-
animationに対して、did seekフラグをtrue、synchronously notifyフラグをfalseに設定し、アニメーションの完了状態の更新手順を実行する。
4.4.6. 関連効果の待機
このセクションは規範的ではありません
アニメーションによって行われる一部の操作は即座に発生しない場合があります。 例えば、ユーザーエージェントによってはアニメーションの再生を別プロセスや専用グラフィックスハードウェアに委譲し、セットアップのオーバーヘッドが発生することがあります。
そのようなアニメーションがトリガー時点から時刻計算される場合、セットアップ時間に対応してアニメーションの最初と2番目のフレーム間で大きなジャンプが生じることがあります。
この問題を避けるため、Web Animationsは通常、アニメーションの最初のフレームが完了した瞬間からタイミングを開始します。 これは、アニメーション上の開始時刻が未解決として表現され、アニメーションが準備完了になると解決されます。 この挙動を回避したい場合は、開始時刻を解決済みの時間値に設定できます。
アニメーションは、以下の両方の条件が初めて真になる瞬間に準備完了となります:
4.4.7. 現在のreadyプロミス
各アニメーションは現在のreadyプロミスを持ちます。 現在のreadyプロミスは、初期状態では解決済みのPromiseであり、アニメーション自身を値として新たな解決済みPromiseを作成する手順で生成され、アニメーションの関連Realmで作成されます。
このオブジェクトは、アニメーションが新たに保留中再生タスクや保留中一時停止タスクをキューした場合(以前は保留中タスクがなかった場合)、またはアニメーションがキャンセルされた場合(§ 4.4.14 アニメーションのキャンセル参照)には、新しいPromiseオブジェクトに置き換えられます。
同じオブジェクトが保留中再生・一時停止の両方のリクエストで使われるため、著者はPromiseオブジェクトが解決された際にアニメーションの状態を確認することを推奨します。
例えば、次のコード片では、現在のreadyプロミスが解決された時点でアニメーションの状態はrunningになります。
これは、play
操作が保留中再生タスクがまだキュー済みの間に実行され、現在のreadyプロミスが再利用されるためです。
4.4.8. アニメーションの再生
アニメーションを再生する手順(animation、auto-rewindフラグ付き)は次の通りです:
-
aborted pauseを、animationに保留中一時停止タスクがあればtrue、なければfalseとする。
-
has pending ready promiseを初期値falseのブール値とする。
-
auto-rewindフラグがtrueの場合、以下から最初に一致する条件の手順を実行:
-
seek timeを0に設定する。
-
- もし associated effect end が正の無限大の場合
-
throw "
InvalidStateError
"DOMException
を投げて、 これらの手順を中止する。 - それ以外の場合
-
seek time を animation の associated effect end に設定する。
-
以下3条件がすべて満たされた場合:
seek timeを0に設定する。
注: このステップにより、auto-rewindフラグの設定に関係なく、アイドル状態のアニメーションは再生されます。
-
has finite timelineを、animationが関連付けられているタイムラインが単調増加でない場合trueとする。
-
seek timeが解決済みなら:
- has finite timelineがtrueの場合
-
-
animationの開始時刻をseek timeに設定する。
-
保留中再生速度の適用をanimationに行う。
-
- それ以外の場合
-
animationのホールド時刻をseek timeに設定する。
-
animationに保留中再生タスクまたは保留中一時停止タスクがあれば、
-
そのタスクをキャンセルする。
-
has pending ready promiseをtrueに設定する。
-
-
以下4条件がすべて満たされた場合:
この手順を中止する。
-
has pending ready promiseがfalseの場合、animationの現在のreadyプロミスをanimationの関連Realmで新しいPromiseにする。
-
animationが準備完了になるとすぐに実行されるタスクをスケジュールする。そのタスクは次を実行:
-
以下から最初に一致する条件に従う:
-
resolve手順でanimationの現在のreadyプロミスをanimationで解決する。
-
animationに対して、did seekフラグをfalse、synchronously notifyフラグをfalseに設定し、アニメーションの完了状態の更新手順を実行する。
このタスクがスケジュールされて未実行の間、animationは保留中再生タスクを持つとされます。タスク実行中はanimationは保留中再生タスクを持たないとされます。
ユーザーエージェントがanimationが即座に準備完了であると判断した場合、上記のタスクを次のマイクロタスクチェックポイントで実行されるマイクロタスクとしてスケジュールしてもよいが、同期的に実行してはならない。
上記の保留中再生タスクを非同期に実行する要件は、次のようなコードが各実装で一貫した挙動となることを保証します:
animation
. play(); animation. ready. then( () => { console. log( 'Playback commenced' ); }, () => { console. log( 'Playback was canceled' ); } ); // 何らかの条件で再生をキャンセルする必要があると仮定... animation. cancel(); // "Playback was canceled" がコンソールに出力される。 上記コードで保留中再生タスクを同期的に実行した場合、現在のreadyプロミスはrejectされません。
-
animationに対して、did seekフラグをfalse、synchronously notifyフラグをfalseに設定し、アニメーションの完了状態の更新手順を実行する。
4.4.9. アニメーションの一時停止
アニメーションの開始時刻が未解決のとき、その現在時刻は一時停止されます。
アニメーションの再生と同様、一時停止は即座に発生しない場合があります(§ 4.4.6 関連効果の待機参照)。 例えば、アニメーションが別プロセスで実行されている場合、アニメーションプロセスによって描画された状態を反映するために現在時刻を同期する必要があるかもしれません。
アニメーションを一時停止する手順(animation)は次の通りです:
-
animationに保留中一時停止タスクがあれば、これらの手順を中止する。
-
has finite timelineを、animationが関連付けられているタイムラインが単調増加でない場合trueとする。
-
animationの現在時刻が未解決の場合、以下から最初に一致する条件に従う:
- animationの再生速度が0以上の場合
-
seek timeを0に設定する。
- それ以外の場合
-
- もし associated effect end が animation に対して正の無限大の場合
-
throw "
InvalidStateError
"DOMException
を投げて、これらの手順を中止する。 - それ以外の場合
-
seek time を animation の associated effect end に設定する。
-
seek timeが解決済みの場合:
-
has pending ready promiseを初期値falseのブール値とする。
-
animationに保留中再生タスクがあれば、そのタスクをキャンセルし、has pending ready promiseをtrueにする。
-
has pending ready promiseがfalseの場合、animationの現在のreadyプロミスをanimationの関連Realmで新しいPromiseに設定する。
-
以下の両方の条件が初めて満たされた瞬間に実行されるタスクをスケジュールする:
タスクは次の手順を実行します:
-
ready timeを、ユーザーエージェントがanimationの関連効果の一時停止処理を完了した瞬間のタイムラインの時間値とする。
-
animationの開始時刻が解決済みでホールド時刻が解決済みでない場合、 ホールド時刻を
(ready time - 開始時刻) × 再生速度
で評価した結果とする。注: ホールド時刻は、アニメーションが完了状態の場合や、保留中再生タスクがある場合はすでに設定されていることがあります。 いずれの場合もpaused状態に入る際にホールド時刻を維持したいです。
-
保留中再生速度の適用をanimationに行う。
-
animationの開始時刻を未解決にする。
-
resolve手順でanimationの現在のreadyプロミスをanimationで解決する。
-
animationに対して、did seekフラグをfalse、synchronously notifyフラグをfalseに設定し、アニメーションの完了状態の更新手順を実行する。
上記のタスクがスケジュールされて未実行の間、animationは保留中一時停止タスクを持つとされます。タスク実行中はanimationは保留中一時停止タスクを持たないとされます。
保留中再生タスクと同様、ユーザーエージェントは保留中一時停止タスクを非同期で実行する必要がありますが、それは次のマイクロタスクチェックポイントでも構いません。
-
-
animationに対して、did seekフラグをfalse、synchronously notifyフラグをfalseに設定し、アニメーションの完了状態の更新手順を実行する。
4.4.10. 終了に到達
このセクションは規範的ではありません
DVDプレイヤーやカセットプレイヤーは、通常メディアの終端まで再生し、到達すると停止します。 これらのプレイヤーが逆再生できる場合、メディアの始端に到達すると停止するのが一般的です。 この挙動を模倣し、HTMLのメディア要素 [HTML]との一貫性を持たせるため、 Web Animationsのアニメーションの現在時刻は、 その関連効果の終了時刻を超えて再生されず、逆再生の場合は0未満に進行しません。
アニメーションが再生範囲の自然な境界に達した場合、完了したと言います。
現在時刻の制限効果は下図のとおりです。
ただし、現在時刻を関連効果の終了後にシークすることは可能です。 その場合、現在時刻は進行せず、アニメーションはシークされた時刻で一時停止したかのように振る舞います。
例えば、関連効果がないアニメーションの現在時刻を5秒にシークすることもできます。 後から5秒より遅い終了時刻を持つ関連効果がそのアニメーションに関連付けられた場合、再生は5秒から始まります。
上記と同様の挙動は、アニメーションの関連効果の長さが変化した場合にも発生します。
4.4.11. 現在のfinishedプロミス
各アニメーションは現在のfinishedプロミスを持ちます。 現在のfinishedプロミスは初期状態ではpendingなPromiseオブジェクトです。
アニメーションが完了再生状態を離れるたび、新しいpromiseに置き換えられます。
4.4.12. 完了状態の更新
再生速度が正の場合、 現在時刻は 関連効果終了まで増加し続けます。
関連効果終了は、アニメーションの関連効果の終了時刻と等しいです。 アニメーションに関連効果がない場合、関連効果終了は0になります。
この境界に到達(または通過)し、開始時刻が解決済みの実行中アニメーションは完了状態になります。
この境界の判定は、アニメーションオブジェクトを変更するたびに、下記のアニメーションの完了状態の更新手順でチェックされます。この手順はアニメーションの更新とイベント送信手順の一部としても実行されます。いずれの場合も、下記定義のdid seekフラグはfalseです。
各アニメーションについて、ユーザーエージェントは直前の現在時刻(時間値)を管理します。初期値は未解決です。
通常再生中はアニメーションの現在時刻は上記の境界に制限されますが、 現在時刻を設定する手順を使えば境界外の時刻にシークすることも可能です。
アニメーションの完了状態の更新手順(animation、did seekフラグ(現在時刻設定後か示す)、synchronously notifyフラグ(完了イベントのキューイングやfinished promiseの即時解決を期待する文脈か示す))は次の通りです:
-
unconstrained current timeを、did seekがfalseならホールド時刻に未解決時間値を代入して現在時刻を計算した結果、trueなら現在時刻自身とする。
注: タイムラインの方向が変わる場合にも対応するために必要です。これがないと、一度完了したアニメーションがタイムラインが逆方向に進んでも完了のままになります。
-
以下3条件がすべて真なら、
-
unconstrained current timeが解決済みである
-
animationが保留中再生タスクや保留中一時停止タスクを持たない
この場合、下記条件でanimationのホールド時刻を更新:
- 再生速度が0より大きく、unconstrained current timeが関連効果終了以上の場合
-
did seekがtrueならホールド時刻をunconstrained current timeにする。
falseならホールド時刻を、直前の現在時刻と関連効果終了の最大値にする。 直前の現在時刻が未解決の場合はホールド時刻を関連効果終了にする。
- 再生速度が0未満、unconstrained current timeが0以下の場合
-
did seekがtrueならホールド時刻をunconstrained current timeにする。
- 再生速度が0でなく、animationがアクティブタイムラインに関連付けられている場合
-
以下を実行:
-
-
current finished stateを、animationの再生状態が完了ならtrue、それ以外はfalseとする。
-
current finished stateがtrueで現在のfinishedプロミスが未解決なら、下記を実行:
-
完了通知手順は下記手順:
-
resolve手順でanimationの現在のfinishedプロミスをanimationで解決する。
-
AnimationPlaybackEvent(finishEvent)を作成。
-
finishEventの
currentTime
属性をanimationの現在時刻に設定する。 -
finishEventの
timelineTime
属性をanimationの関連タイムライン現在時刻に設定する。タイムラインがないか、非アクティブの場合は、timelineTime
はnull
。 -
animationにタイミング用ドキュメントがあれば、そのタイミング用ドキュメントの保留中アニメーションイベントキューにターゲットanimationと共に追加する。予定イベント時刻には、変換したanimationの関連効果終了のオリジン基準時刻を使う。
それ以外の場合は、タスクをキューし、finishEventをanimationにディスパッチする。そのタスクソースはDOM操作タスクソース。
-
synchronously notifyがtrueなら、キュー済みの完了通知マイクロタスクをキャンセルし、直ちに完了通知手順を実行する。
falseなら、マイクロタスクをキューして、すでにキューされていなければanimationの完了通知手順を実行する。
-
-
current finished stateがfalseで、animationの現在のfinishedプロミスが既に解決済みなら、animationの現在のfinishedプロミスを新しいPromise(animationの関連Realm)にする。
通常は、アニメーションの完了状態の通知は非同期で行われます。これにより、アニメーションが一時的に完了再生状態に入っても、イベント発火やpromise解決が発生しないようにできます。
例えば、次のコード片ではanimation
が一時的に完了状態になります。もし完了状態の通知が同期的に行われていれば、このコードはfinishイベントのキューや現在のfinishedプロミスの解決を引き起こします。しかし、2文の順序を逆にしてiterations
を先に更新すれば、このようなことは起きません。
このような予期せぬ挙動を避けるため、アニメーションの完了状態通知は通常非同期で行われます。
var animation= elem. animate({ left: '100px' }, 2000 ); animation. playbackRate= 2 ; animation. currentTime= 1000 ; // animationは今完了 animation. effect. updateTiming({ iterations: 2 }); // animationはもう完了ではない
唯一の例外は、アニメーションの完了手順(通常はfinish()
メソッド呼び出し)を実行した場合です。この場合は著者が明示的に完了を意図しているので、完了状態の通知は下記の通り同期的に行われます。
var animation= elem. animate({ left: '100px' }, 1000 ); animation. finish(); // finishイベントは即座にキューされ、finished promiseも // 解決される。次の文で // animationが完了状態でなくなっても。 animation. currentTime= 0 ;
アニメーションの完了手順同様、アニメーションのキャンセル手順も、cancelイベントを同期的にキューし、 現在のfinishedプロミスと現在のreadyプロミスも同期的にrejectします。
4.4.13. アニメーションの完了
アニメーションは、下記のアニメーションの完了手順を使うことで、現在の再生方向の自然な終端まで進めることができます:
-
もし animation の effective playback rate が 0 である場合、 または animation の effective playback rate が 0 より大きく、 associated effect end が無限大の場合は、 throw "
InvalidStateError
"DOMException
を投げて、これらの手順を中止する。 -
Apply any pending playback rate を animation に適用する。
-
limit を次のように設定する:
- もし playback rate が 0 より大きい場合
-
limit を associated effect end にする。
- それ以外の場合
-
limit を 0 にする。
-
Silently set the current time を limit に設定する。
-
もし animation の start time が unresolved であり、かつ animation が関連付けられた active timeline を持つ場合、 start time を
timeline time - (limit / playback rate)
(timeline time は関連付けられた timeline の現在の time value)で評価した値にする。 -
もし pending pause task が存在し、start time が resolved の場合、
-
hold time を unresolved にする。
-
pending pause task をキャンセルする。
-
Resolve で animation の current ready promise を animation で解決する。
-
-
もし pending play task が存在し、 start time が resolved の場合、そのタスクをキャンセルし、 resolve で animation の current ready promise を animation で解決する。
-
animation に対して、did seek フラグを true、synchronously notify フラグを true に設定し、 update an animation’s finished state 手順を実行する。
4.4.14. アニメーションのキャンセル
アニメーションはキャンセルすることができ、これにより現在時刻が未解決となり、関連効果による効果がすべて削除されます。
アニメーションをキャンセルする手順(animation)は次の通りです:
-
animationの再生状態がidleでない場合、以下を実行:
-
保留中タスクのリセット手順をanimationに実行する。
-
reject手順でanimationの現在のfinishedプロミスを"AbortError"のDOMExceptionでrejectする。
-
現在のfinishedプロミスの[[PromiseIsHandled]]内部スロットをtrueにする。
-
animationの現在のfinishedプロミスを、新しいPromise(animationの関連Realm)にする。
-
AnimationPlaybackEvent(cancelEvent)を作成する。
-
cancelEventの
currentTime
をnull
に設定する。 -
timeline timeを、animationが関連付けられているタイムライン現在時刻とする。タイムラインがアクティブでない場合は、timeline timeを未解決な時間値とする。
-
cancelEventの
timelineTime
をtimeline timeに設定する。timeline timeが未解決なら、null
に設定する。 -
animationにタイミング用ドキュメントがあれば、タイミング用ドキュメントの保留中アニメーションイベントキューにcancelEventとターゲットanimationを追加する。animationがアクティブなタイムラインに関連付けられており、タイムライン時刻をオリジン基準時刻に変換する手順を定義している場合は、予定イベント時刻をその手順でtimeline timeを変換した結果とする。 それ以外の場合は、予定イベント時刻を未解決な時間値とする。
それ以外の場合は、タスクをキューし、cancelEventをanimationにディスパッチする。タスクソースはDOM操作タスクソース。
-
保留中タスクのリセット手順(animation)は次の通りです:
-
animationが保留中再生タスクも保留中一時停止タスクも持たない場合、この手順を中止する。
-
animationが保留中再生タスクを持つ場合、そのタスクをキャンセルする。
-
animationが保留中一時停止タスクを持つ場合、そのタスクをキャンセルする。
-
保留中再生速度の適用をanimationに行う。
-
reject手順でanimationの現在のreadyプロミスを"AbortError"のDOMExceptionでrejectする。
-
animationの現在のreadyプロミスの[[PromiseIsHandled]]内部スロットをtrueにする。
-
animationの現在のreadyプロミスを新たな解決済みPromiseオブジェクト(値はanimation、animationの関連Realm)にする。
4.4.15. 速度制御
アニメーションの再生速度は 再生速度 を設定することで制御できます。 例えば、再生速度を2に設定すると、アニメーションの現在時刻は タイムラインの2倍の速さで増加します。 同様に、再生速度を-1に設定すると アニメーションの現在時刻は タイムラインの時間値が増加するのと同じ速度で減少します。
アニメーションは 再生速度 を持ち、 関連付けられたタイムラインの時間値の変化速度からアニメーションの現在時刻へのスケーリング係数を提供します。 再生速度の初期値は1です。
アニメーションの再生速度を0に設定すると、事実上一時停止状態になります(ただし再生状態が必ずしも一時停止になるとは限りません)。
4.4.15.1. アニメーションの再生速度の設定
再生速度の設定手順( アニメーション animationをnew playback rateに設定)は次の通りです:
-
animation の保留中再生速度をクリアする。
-
previous timeを、現在時刻の変更前の値とする。
-
previous playback rateを、animationの現在の実効再生速度とする。
-
再生速度をnew playback rateに設定する。
-
以下のうち最初に一致する条件の手順を実行:
- animationが単調増加 なタイムラインに関連付けられており、previous timeが解決済みの場合
-
現在時刻の設定手順でanimationの現在時刻をprevious timeにする。
-
animationがnull以外のタイムラインに関連付けられていて、かつ単調増加でなく、 animationの開始時刻が解決済み、 関連効果終了が無限大でなく、かつ いずれかが成立する場合:
-
previous playback rate < 0 かつ new playback rate ≥ 0
-
previous playback rate ≥ 0 かつ new playback rate < 0
-
-
animationの開始時刻を
関連効果終了 - 開始時刻
で評価した値にする。注: この操作は非単調タイムライン上でアニメーションの開始/終了時刻を反転し、開始時刻の相対オフセットを保ちます。
4.4.15.2. アニメーションの再生速度をシームレスに更新する
別プロセスやスレッド上で実行中のアニメーションの場合、 再生速度の設定手順は、 アニメーションの実行プロセス/スレッドが更新操作側と同期していないとジャンプを引き起こす可能性があります。
アニメーションの再生速度をシームレスに変更するために、 アニメーションには 保留中再生速度 を持たせることができ、 必要な同期後に(他プロセスやスレッドの場合)適用されます。
初期状態で保留中再生速度は未設定です。
実効再生速度は、 animationの保留中再生速度があればそれを、なければ再生速度を使います。
アニメーション animationに 保留中再生速度の適用を行う手順:
再生速度をシームレスに更新する手順(アニメーション animation、new playback rateで現在時刻を保ったまま)は次の通りです:
-
previous play stateをanimationの再生状態とする。
注: animationの実効再生速度を更新する前に再生状態を記録する必要があります。 このロジックでは、animationが現在完了状態であれば、保留中再生速度を即座に適用したいからです。
-
animationの保留中再生速度をnew playback rateに設定する。
-
以下から最初に一致する条件による手順を実行:
- animationが保留中再生タスクまたは保留中一時停止タスクを持つ場合
-
これらの手順を中止する。
注: 保留中タスクの種類によって、走行中に保留中再生速度が適用されるため、追加アクションは不要です。
-
保留中再生速度の適用手順をanimationに実行する。
注: 2つ目の条件は、未解決の現在時刻かつ保留中再生タスクがない実行中アニメーションに対して、以下の再生処理を行わないようにするためです。
- previous play stateが完了の場合
-
-
unconstrained current timeを、animationの現在時刻をホールド時刻に未解決時間値を代入して計算した値とする。
-
animationの開始時刻を
timeline time - (unconstrained current time / 保留中再生速度)
(timeline timeは関連タイムラインの現在時間値)に設定する。 -
保留中再生速度の適用手順をanimationに実行する。
-
アニメーションの完了状態の更新手順をanimationに対してdid seekフラグfalse、synchronously notifyフラグfalseで実行する。
-
- それ以外の場合
-
アニメーション再生手順でanimationのauto-rewindフラグをfalseで実行する。
4.4.16. アニメーションの逆再生
アニメーションの逆再生手順(animation animation)は次の通りです:
-
もしanimationに関連付けられているタイムラインが存在しない場合、または関連付けられているタイムラインが非アクティブである場合、throwし、「
InvalidStateError
」DOMException
を発生させ、これらの手順を中止する。 -
original pending playback rate を animation の pending playback rate とする。
-
animation の pending playback rate を effective playback rate の加法逆数(すなわち
-effective playback rate
)に設定する。 -
animation に対して auto-rewind フラグを true にして play an animation の手順を実行する。
もし play an animation の手順で例外が発生した場合は、animation の pending playback rate を original pending playback rate に戻し、例外を伝播する。
4.4.17. 再生状態
アニメーションは、以下のいずれかの再生状態となり得ます。各状態には非規範的な説明も付与されています:
animation animation の再生状態は、次の条件のうち最初に一致する状態となります:
-
すべての次の条件が真の場合:
-
→ idle
-
いずれかの次の条件が真の場合:
-
animationが保留中一時停止タスクを持つ場合
-
-
→ paused
-
→ finished
- それ以外の場合
-
→ running
注意:paused再生状態は finished再生状態よりも優先されます。
ただし、自然な再生範囲外で一時停止されたアニメーションは、例えば以下のように開始時刻を設定することで、再開せずにpaused状態からfinished状態に変換できます:
animation. effect. updateTiming({ duration: 5000 }); animation. currentTime= 4000 ; animation. pause(); animation. ready. then( function () { animation. effect. updateTiming({ duration: 3000 }); alert( animation. playState); // 'paused'と表示 animation. startTime= document. timeline. currentTime- animation. currentTime* animation. playbackRate; alert( animation. playState); // 'finished'と表示 });
4.4.18. アニメーションイベント
アニメーションイベントには、この仕様で定義されるアニメーション再生イベントや、 CSSトランジションのイベント [CSS-TRANSITIONS-1]、 CSSアニメーションのイベント [CSS-ANIMATIONS-1] が含まれます。 今後の仕様でさらに多様なアニメーションイベントが追加される可能性もあります。
各Document
は、保留中アニメーションイベントキューを保持し、アニメーションイベントとその対応するイベントターゲット、
予定イベント時刻を格納します。
予定イベント時刻は時間値であり、
タイムオリジン基準で、アニメーションが無限に高頻度で更新された場合にイベントが理想的にディスパッチされるタイミングを表します。
この値はアニメーションの更新とイベント送信手順でキューされたアニメーションイベントを時系列でソートするために使われます。
なお、この値は例えばアニメーションのタイムラインがタイムオリジンと無関係な値を生成する場合(例:スクロール位置を追跡するタイムライン)や、
タイムラインが非アクティブの場合は未解決となることがあります。
4.4.18.1. アニメーションイベントのソート
以下の定義は、イベントキューのソートを補助するためのものです。
アニメーション時刻をタイムライン時刻に変換する手順: 時間値 time(アニメーションの開始時刻基準)について、以下を実行:
-
timeが未解決なら、timeを返す。
-
次を計算して返す:
time × (1 / playback rate) + start time
(playback rateとstart timeはそれぞれアニメーションの再生速度と開始時刻)。
タイムライン時刻を原点相対時刻に変換するには、時間値 time(時間値と同じスケールで表現される)、タイムライン timelineについて、次の手順を実行します。
-
timeline timeを、アニメーション時刻をタイムライン時刻に変換する手順でtimeを変換した結果とする。
-
timeline timeが未解決なら、timeを返す。
-
アニメーションが非アクティブタイムラインに関連付けられている場合、未解決な時間値を返す。
-
関連タイムラインにタイムライン時刻をオリジン基準時刻に変換する手順がない場合、未解決な時間値を返す。
-
関連タイムラインの定義された手順でtimeline timeをオリジン基準時刻に変換した結果を返す。
4.4.18.2. アニメーション再生イベント
アニメーションの再生中に、状態の変化はアニメーション再生イベントによって報告されます。
アニメーション再生イベントはタイミングモデルのプロパティです。そのため、アニメーションの関連効果が存在しない場合や目に見える結果がない場合でも、イベントはディスパッチされます。
4.4.18.3. アニメーション再生イベントの種類
- finish
-
アニメーションがfinished再生状態になったときにキューされます。
- cancel
-
アニメーションが他の状態からidle再生状態になったときにキューされます。新たなアニメーションが最初からidleの場合はcancelイベントは生成されません。
- remove
-
アニメーションが自動的に削除されたときにキューされます。 詳細は§ 5.5 アニメーションの置換参照。
4.5. アニメーション効果
アニメーション効果は、タイミング階層内の項目を指す抽象的な用語です。
4.5.1. アニメーション効果とアニメーションの関係
アニメーションの関連効果(設定されていれば)は、アニメーション効果の一種です。 関連効果は、そのアニメーションに関連付けられていると言います。 ある時点では、アニメーション効果は最大で1つのアニメーションにのみ関連付けられます。
アニメーション効果effectは、timelineに関連付けられていると言えるのは、effectがアニメーションに関連付けられていて、そのアニメーションがtimelineに関連付けられている場合です。
4.5.2. アニメーション効果の種類
この仕様では、キーフレーム効果という1種類のアニメーション効果のみを定義しています。 今後の仕様レベルでさらに多様なアニメーション効果が定義されます。
すべてのアニメーション効果は、以下のセクションで説明する共通プロパティを持ちます。
4.5.3. アクティブ区間
アニメーション効果が実行される期間をアクティブ区間と呼びます。 各アニメーション効果はこの区間を1つだけ持ちます。
アクティブ区間の下限は、通常はこのアニメーション効果に関連付けられたアニメーションの開始時刻に対応しますが、アニメーション効果の開始遅延によってシフトする場合があります。
区間の上限はアクティブ期間によって決まります。
開始時刻、開始遅延、アクティブ期間の関係は下図で説明します。
(a) 遅延なしのアニメーション効果:開始時刻とアクティブ区間の始端は一致。
(b) 正の遅延がある場合:アクティブ区間の始端は遅延分だけ後ろ倒し。
(c) 負の遅延がある場合:アクティブ区間の始端は遅延分だけ前倒し。
終了遅延も指定可能ですが、主にアニメーションのシーケンス制御時に使われます。
アニメーション効果は、アクティブ区間を定義します。この区間は、効果がその効果を生むようにスケジュールされている期間であり、アクティブ区間外で適用される塗りつぶしモードは例外です。
開始遅延は、アニメーション効果が関連付けられたアニメーションの開始時刻からの符号付きオフセットです。
アクティブ区間の長さはアクティブ期間と呼ばれ、計算方法は§ 4.8.2 アクティブ期間の計算で定義されています。
開始遅延に似て、アニメーション効果には
終了遅延もあり、主に他のアニメーション効果の終了時刻基準でシーケンス制御する際に使われます。
これは通常シーケンス効果(今後の仕様で導入)と組み合わせてのみ有効ですが、SVGのmin
属性([SVG11]第19章)表現の目的でここに含まれます。
終了時刻は、アニメーション効果に対しmax(開始遅延 + アクティブ期間 + 終了遅延, 0)
で評価されます。
4.5.4. ローカル時刻
ローカル時刻は、ある時点のアニメーション効果について、以下から最初に一致する条件で決まります:
- アニメーション効果がアニメーションに関連付けられている場合
- それ以外の場合
-
ローカル時刻は未解決です。
4.5.5. アニメーション効果のフェーズと状態
ある時点で、アニメーション効果は3つのフェーズのいずれかにあります。 アニメーション効果がローカル時刻を未解決で持つ場合、いずれのフェーズにも属しません。
フェーズの違いは下図で示します。
フェーズの種類:
これらのフェーズに加えて、アニメーション効果は複数の重複する状態にも分類できます。 状態は1フレームだけ確立され、主にモデルの静的部分記述のために使われます。
これらの状態とモデル内での使い方の概要:
- 再生中
- 現在
- 効果中
-
解決済みのアクティブ時刻を持つアニメーション効果に対応。 これはアニメーション効果がアクティブフェーズにある場合や、アクティブフェーズ外でも塗りつぶしモード(§ 4.6 塗りつぶし挙動参照)によりアクティブ時刻が解決される場合。 効果中のアニメーション効果のみがターゲットに結果を適用します。
これらの状態の規範的定義は後述します。
アニメーション効果のフェーズ判定には以下の定義が必要です:
- アニメーション方向
-
効果がアニメーションに関連付けられていて、関連アニメーションの再生速度が0未満なら"逆方向"、それ以外は"順方向"。
- アクティブ前境界時刻
- アクティブ後境界時刻
アニメーション効果は、前フェーズにあるのは、効果のローカル時刻が未解決でなく、かつ以下いずれかの条件を満たす場合:
-
ローカル時刻がアクティブ前境界時刻未満、または
-
アニメーション方向が"逆方向"で、ローカル時刻がアクティブ前境界時刻と等しい場合。
アニメーション効果は、後フェーズにあるのは、効果のローカル時刻が未解決でなく、かつ以下いずれかの条件を満たす場合:
-
ローカル時刻がアクティブ後境界時刻より大きい、または
-
アニメーション方向が"順方向"で、ローカル時刻がアクティブ後境界時刻と等しい場合。
アニメーション効果は、アクティブフェーズにあるのは、効果のローカル時刻が未解決でなく、かつ前フェーズでも後フェーズでもない場合です。
さらに、上記いずれのフェーズにも属さない場合をアイドルフェーズと呼ぶことがあります。
アニメーション効果は、再生中であるのは、以下すべての条件が真の場合です:
-
アニメーション効果がアニメーションに関連付けられていて、しかもそのアニメーションが完了状態ではない。
アニメーション効果は、現在であるのは、以下いずれかの条件が真の場合です:
-
アニメーション効果がアニメーションに関連付けられていて、再生速度が0より大きく、アニメーション効果が前フェーズである場合
-
アニメーション効果がアニメーションに関連付けられていて、再生速度が0未満、アニメーション効果が後フェーズである場合
-
アニメーション効果がアニメーションに関連付けられていて、アイドル状態でなく、nullでない関連タイムラインに関連付けられていて、しかもそのタイムラインが単調増加でない場合
アニメーション効果は、効果中であるのは、アクティブ時刻(§ 4.8.3.1 アクティブ時刻の計算参照)が未解決でない場合です。
4.5.6. 関連アニメーション
アニメーションがアニメーション効果の関連に基づいて関連すると定義できます。
アニメーションが関連となる条件:
サブツリーの関連アニメーションは、要素・疑似要素・document・shadow root(target)について、アニメーションのうち、そのアニメーションに含まれるアニメーション効果の効果ターゲットが、targetの包含的子孫(またはtargetがdocumentやshadow rootの場合は子孫)や、そうした子孫の疑似要素であるものの集合です。
4.6. 塗りつぶし挙動
アニメーション効果が再生中でないときの効果は、その塗りつぶしモードによって決まります。
塗りつぶしモードの種類は以下の通りです:
-
none(なし)
-
forwards(順方向)
-
backwards(逆方向)
-
both(両方)
これらモードの規範的定義は、アクティブ時刻の計算(§ 4.8.3.1 アクティブ時刻の計算)に組み込まれています。
著者は塗りつぶしモードを使って、効果が無期限に適用されるアニメーションを作ることは推奨されません。塗りつぶしモードは、CSSアニメーションで定義されるanimation-fill-modeプロパティを表現するために導入されました([CSS-ANIMATIONS-1])。 しかしこれにより、アニメーション状態が無限に蓄積される状況が生じ、§ 5.5 アニメーションの置換で定義されるアニメーションの自動削除が必要になります。 さらに、無期限に塗りつぶしされるアニメーションは、すべてのアニメーションが完了した後も、アニメーションスタイルがCSSカスケード内で優先されるため、指定スタイルの変更が長期間反映されなくなる場合があります([css-cascade-3])。
可能であれば、著者はアニメーションの最終状態を直接指定スタイルで設定することを推奨します。 これはアニメーションが完了するのを待ってからスタイルを更新することで実現できます。例:
// 次のアニメーションが完了した直後の最初のフレームで、`finished` promiseのコールバックは // スタイル更新前に実行されるため、ちらつきません。 elem. animate({ transform: 'translateY(100px)' }, 200 ). finished. then(() => { elem. style. transform= 'translateY(100px)' ; });
あるいは、アニメーション開始時に指定スタイルを設定し、元の値からアニメーションすることもできます。例:
複数アニメーションを重ねる複雑な効果の場合、最終値を記録するため一時的にforwards塗りつぶしモードを使うことが必要な場合があります。 例:
elem. addEventListener( 'click' , async evt=> { const animation= elem. animate( { transform: `translate( ${ evt. clientX} px, ${ evt. clientY} px)` }, { duration: 800 , fill: 'forwards' } ); await animation. finished; // commitStylesは`animation`までのスタイルを記録し、elemの指定スタイルを更新します。 animation. commitStyles(); animation. cancel(); });
4.6.1. 塗りつぶしモード
各塗りつぶしモードの効果は次の通りです:
- none
-
アニメーション効果が再生中でない場合、何の効果もありません。
- forwards
-
アニメーション効果が後フェーズにある場合、 スケジュール上最後に再生中だった瞬間と同じ反復進行度値を生成します。
その他の再生中でない時は効果がありません。
- backwards
-
アニメーション効果が前フェーズにある場合、 スケジュール上最初に再生中になる瞬間と同じ反復進行度値を生成します。
その他の再生中でない時は効果がありません。
- both
-
アニメーション効果が前フェーズにある場合はbackwards塗りつぶし挙動が使われます。
アニメーション効果が後フェーズにある場合はforwards塗りつぶし挙動が使われます。
これら塗りつぶしモードの例を以下に示します。
(a) fill mode "none"。アクティブフェーズ外では効果なし。
(b) fill mode "forwards"。アクティブフェーズ終了後も反復進行度値が維持される。
(c) fill mode "backwards"。アクティブフェーズ開始まで塗りつぶし値が生成される。
(d) fill mode "both"。アクティブフェーズ前後で塗りつぶし値が生成される。
注: 塗りつぶしモードの設定はアクティブ区間の端点やフェーズ間境界には影響しません。 ただし塗りつぶしモードはタイミングモデルの他のプロパティに影響します。なぜならアクティブ時刻は、 アニメーション効果がアクティブフェーズ内または塗りつぶしが適用される場合のみ定義される(未解決でない)ためです。
4.7. 反復
4.7.1. 反復区間
アニメーション効果が一定回数または無限に繰り返すよう指定することができます。 この反復はアクティブ区間内で行われます。 1回の反復が行われる時間領域を反復区間と呼びます。
アクティブ区間とは異なり、アニメーション効果は複数の反復区間を持つことができますが、通常は現在の反復に対応する区間のみが重要です。
1回の反復の長さは反復期間と呼ばれます。 アニメーション効果の初期反復期間は0です。
- 反復期間
-
アニメーション効果が1回反復するのにかかる時間。
- アクティブ期間
-
全アニメーション効果が完了するまでの時間(反復も含む)。 これは反復期間より長い場合も短い場合もあります。
4.7.2. 反復の制御
アニメーション効果が繰り返す回数は反復回数と呼ばれます。 反復回数は0以上の実数です。 反復回数が正の無限大の場合、アニメーション効果は無限に繰り返されます。
反復回数に加え、アニメーション効果には反復開始プロパティもあり、アニメーション効果が始まる反復系列内のオフセットを指定します。 反復開始は0以上の有限実数です。
これらパラメータの挙動は§ 4.8 コアアニメーション効果計算で定義されています。
最初の例では反復回数が2.5で、3回目の反復が途中で反復区間で切られます。
2番目の例では反復開始が0.5で、最初の反復の途中からアニメーション効果が始まります。
反復回数パラメータとは異なり、反復開始パラメータはアクティブ期間の長さには影響しません。
反復開始が1以上の場合、アニメーション効果がiteration composite operationでaccumulateを指定している場合以外は、一般に有用ではありません。
4.7.3. 反復時空間
Web Animationsでは、すべての時刻は何らかの基準点に対して相対的です。 これら異なる基準点によって、異なる時空間が生じます。
これはコンピュータグラフィックスで使われる座標空間と比較できます。 時空間のゼロ時刻は、座標空間の原点に相当します。
繰り返されるアニメーションについては、アニメーションが繰り返されるごとに新しい時空間が確立されると説明できます。それが反復時空間です。
反復時空間とは、アニメーション効果の現在の反復の開始がゼロ時刻となる時空間です。
Web Animationsモデル内では、アクティブ時刻についても言及します。これはアクティブ区間の開始に対して相対的な時刻です。 ただし、この時空間はモデル内部でのみ使用され、プログラミングインターフェースやマークアップには公開されません。
これらの時空間を下図に示します。
注: 時空間自体には境界はありませんが、Web Animationsではアクティブ時刻や反復進行度が、図に示されるように一定範囲に制限されます。 例えば、アクティブ時空間で-1秒という時刻は有効ですが、アクティブ時刻の計算法(§ 4.8.3.1 アクティブ時刻の計算)では負の値が返されることはありません。
これら以外にも、ドキュメント時空間についても言及できます。これは、時間値がデフォルトドキュメントタイムライン上で表される時空間であり、Document
の現在のグローバルオブジェクトに属します。
4.7.4. 区間タイミング
アニメーション効果が繰り返されるとき、反復の境界での動作を定義する必要があります。
これには、そしてすべての区間タイミングについて、Web Animationsは端点排他的なタイミングモデルを採用しています。
これは、区間の開始時刻は区間に含まれ、終了時刻は含まれないことを意味します。
区間表記では[開始, 終了)
と書きます。
このモデルによって、区間を繰り返したり並べた場合でも区間同士が重複しません。
以下の例では、繰り返し効果においてローカル時刻1秒の時、反復時刻は0となります。 シーケンスされたアニメーションでは、タイムライン時刻1秒の時、アニメーションBの関連効果のみが再生中であり、重複はありません。
この動作の例外として、塗り(fill)を行う場合、塗りが区間の端点で始まるときはその端点が使用されます。 この動作は§ 4.8.3.3 単純反復進行度の計算のアルゴリズムから導かれ、下図で示されます。
4.8. コアアニメーション効果の計算
4.8.1. 概要
Web Animationsのタイミングモデルの中心は、ローカル時刻値を反復進行度に変換する処理です。
この処理の第一段階は、アクティブ区間の境界を計算することです。これはアクティブ持続時間によって決まります。
この処理を下図に示します。
アクティブ持続時間の計算法は、§ 4.8.2 アクティブ持続時間の計算で現行標準的に定義されています。
アクティブ持続時間が確定したら、アニメーション効果のローカル時刻を変換済み進行度(反復進行度)に変換する処理が下図で示されます。
(1) ローカル時刻は関連アニメーションから決定されます。
(2) ローカル時刻はアクティブ時刻に変換されます。この際、開始遅延を考慮します。
(3) アクティブ時刻は反復期間で割り、さらに反復開始プロパティも考慮して全体進行度を算出します。
(4) 全体進行度時刻は、1回の反復内のオフセットに変換されます。これが単純反復進行度です。
(5) 単純反復進行度は、再生方向を考慮して指向性進行度に変換されます。
(6) 最後に、タイミング関数が指向性進行度に適用され、変換済み進行度が得られます。
最初のステップであるローカル時刻の計算は、§ 4.5.4 ローカル時刻で説明されています。 図のステップ2〜4は次節以降で説明します。 ステップ5と6は、§ 4.9.1 指向性進行度の計算および§ 4.10.1 変換済み進行度の計算で説明されています。
4.8.2. アクティブ持続時間の計算
アクティブ持続時間は次のように計算します:
アクティブ持続時間 =反復期間 × 反復回数
反復期間または反復回数のいずれかが0の場合、アクティブ持続時間は0となります。
この明確化は、IEEE 754-2008において無限大とゼロの乗算結果が未定義であるため必要です。
4.8.3. ローカル時刻の変換
4.8.3.1. アクティブ時刻の計算
アクティブ時刻は、ローカル時刻と開始遅延に基づきます。 ただし、これはアニメーション効果が出力を生成すべき場合のみ定義され、そのため塗りモードやフェーズによって以下のように決まります:
- アニメーション効果がbeforeフェーズの場合
-
結果は次の条件のうち最初に一致したものに依存します:
- アニメーション効果がactiveフェーズの場合
- アニメーション効果がafterフェーズの場合
-
結果は次の条件のうち最初に一致したものに依存します:
- それ以外(ローカル時刻が未解決の場合)
4.8.3.2. 全体進行度の計算
全体進行度は、完了した反復回数(部分反復も含む)を示し、以下のように定義されます:
-
以下の条件のうち最初に一致したものに基づいて、overall progressの初期値を計算します:
- 反復期間が0の場合
-
アニメーション効果がbeforeフェーズであれば、overall progressは0とし、それ以外の場合は反復回数とします。
- それ以外の場合
-
overall progress + 反復開始
の計算結果を返します。
4.8.3.3. 単純反復進行度の計算
単純反復進行度は、現在の反復内での進行度の割合であり、再生方向や効果に適用されるタイミング関数による時刻変換を無視し、以下のように計算されます:
-
全体進行度が無限大の場合、simple iteration progressは
反復開始 % 1.0
とし、それ以外の場合は全体進行度 % 1.0
とします。 -
以下のすべての条件が真の場合:
-
上記で計算したsimple iteration progressが0である かつ
-
アニメーション効果がactiveフェーズ または afterフェーズである かつ
-
反復回数が0ではない。
simple iteration progressは1.0とします。
上記の手順により、アニメーションのアクティブ区間が反復の終了点と一致した場合、次の反復の開始ではなく最終反復の端点を保持して塗りを行う動作が実現されます。
最後の条件は、反復回数が0でアニメーションが1度も再生されていない場合にこの動作が適用されないようにします。
-
-
simple iteration progressを返します。
4.8.4. 現在の反復の計算
現在の反復は、以下の手順で計算できます:
-
それ以外の場合、
floor(全体進行度)
を返します。
4.9. 方向制御
アニメーション効果は、方向制御によって反復ごとに異なる方向で再生するよう設定できます。 このために、アニメーション効果には再生方向パラメータがあり、次のいずれかの値を取ります:
-
normal,
-
reverse,
-
alternate, または
-
alternate-reverse.
これらの値の意味は、後述する指向性進行度の計算に組み込まれています。
これらの値の非規範的な定義は以下の通りです:
- normal
-
すべての反復は指定通りに再生されます。
- reverse
-
すべての反復は指定された方向と逆に再生されます。
- alternate
-
偶数回の反復は指定通り、奇数回の反復は指定された方向と逆に再生されます。
- alternate-reverse
-
偶数回の反復は指定された方向と逆に、奇数回の反復は指定通りに再生されます。
4.9.1. 指向性進行度の計算
指向性進行度は、単純反復進行度から以下の手順で計算されます:
-
以下のリストから最初に一致した条件に基づいて、current directionを計算します:
-
current directionがforwardsなら単純反復進行度を返します。
それ以外の場合は
1.0 - 単純反復進行度
を返します。
4.10. 時刻変換
アニメーション効果の進行速度を制御したいことは多くあります。 例えば、アニメーションの速度をイージングすることで、動きに勢いを持たせ、より自然な効果が得られます。 CSS Easing Functions Module [CSS-EASING-1] は、この目的のためのタイミング関数を定義しています。
アニメーション効果には 1つのタイミング関数が関連付けられています。 デフォルトのタイミング関数は線形タイミング関数です。
4.10.1. 変換済み進行度の計算
変換済み進行度は、指向性進行度から以下の手順で計算します:
-
before flagの値を次のように計算します:
-
§ 4.9.1 指向性進行度の計算で定義された手順に従い、current directionを決定します。
-
current directionがforwardsの場合、 going forwardsはtrue、それ以外はfalseとします。
-
アニメーション効果がbeforeフェーズかつgoing forwardsがtrue、 またはアニメーション効果がafterフェーズかつgoing forwardsがfalseのとき、 before flagをセットします。
-
-
アニメーション効果のタイミング関数に、指向性進行度を入力進行度値として、before flagをbefore flagとして渡した評価結果を返します。
4.11. 反復進行度
反復進行度は、アニメーション効果の変換済み進行度そのものです。
5. アニメーションモデル
いくつかのアニメーション効果について、Web Animationsのアニメーションモデルは タイミングモデルから得られた反復進行度と現在の反復の値を使って 対応する出力を計算します。
そのアニメーション効果ごとの出力は、効果スタックで他の出力と組み合わせて ターゲットプロパティに適用されます(§ 5.4 効果の合成参照)。
5.1. 概要
アニメーション効果は、タイミング出力の変化に応じて影響を与えるゼロ個以上の関連プロパティを持ちます。これらのプロパティは効果のターゲットプロパティと呼ばれます。
反復進行度、現在の反復、基底値が与えられると、アニメーション効果は、 各アニメーション可能なターゲットプロパティについて、 そのプロパティに適したアニメーション型の手順を適用して 効果値を生成します。
5.2. プロパティのアニメーション
特に指定がない限り、すべてのCSSプロパティはアニメーション可能です。 プロパティ値の合成方法は、各プロパティの定義テーブルにあるアニメーション型行によって定義されます:
- アニメーション不可
-
このプロパティはアニメーション不可です。
アニメーションキーフレームにリストされても処理されず、
トランジションにも影響を受けません。
注: プロパティがアニメーションから除外される理由は、アニメーションすると過度に複雑になる場合が多いためです。 例えば、アニメーションパラメータを定義するプロパティはアニメーション不可ですが、 これは複雑な再帰動作を生むためです。
注: アニメーション効果がアニメーション不可なプロパティのみをターゲットにしていても、 アニメーション効果としての通常の動作(イベント発火やアニメーションの現行標準終了プロミスの履行遅延など)は保持されます。
- 離散
-
このプロパティ値は意味のある合成ができません。
したがって加法不可であり、補間は
VaからVbへ50%(p=0.5)で切り替わります。
すなわち
- 算出値ごと
- 対応する個々の算出値成分を、 その値型に応じた手順(補間・加算・累積)で合成します (CSS Values 4 § 3 値の合成:補間、加算、累積参照)。 成分数や型が一致しない場合、 または任意の成分値が離散アニメーションであり、値が一致しない場合は、 プロパティ値は離散として合成されます。
- 繰り返し可能リスト
-
算出値ごとと同様ですが、
2つのリストのアイテム数が異なる場合は、最小公倍数まで繰り返してから合成します。
各アイテムは算出値ごとで合成されます。
合成できない値のペアや、任意の成分値が離散アニメーションの場合は、
プロパティ値は離散として合成されます。
注: 繰り返し可能リストの概念により、リストが概念的に指定長まで繰り返される場合 (background-originはbackground-imageリストの長さまで繰り返される) または無限に繰り返される場合でも、任意の値間でスムーズに遷移でき、 算出値が正しく結果を表し(継承も正しく行われる可能性があります)、となります。
- (本文参照)
- 上記以外の特殊な補間動作を持つプロパティについては、個別にアニメーション動作が明示的に指定されます。
アニメーション型がプロパティ定義にまだ含まれていないプロパティのアニメーション型は、付録A:既存プロパティのアニメーション型で定義されています。
5.2.1. カスタムプロパティ
カスタムプロパティが、registerProperty()メソッドによって現在のグローバルオブジェクトに登録されている場合、 アニメーション型は、プロパティの算出値ごとであり、 プロパティの構文定義で使用される型から導出されます。 プロパティの指定された構文に対応する算出値型が存在しない場合 (例えば、構文がユニバーサル構文定義の場合)や、 カスタムプロパティが登録されていない場合は、 アニメーション型は離散となります。
5.3. キーフレーム効果
キーフレーム効果とは、タイミングモデルの出力を利用して、要素や疑似要素(::before
や::after
など[select])のCSSプロパティを更新するアニメーション効果の一種であり、
これらは効果ターゲットと呼びます。
効果ターゲットは、
Element
であるターゲット要素と、疑似要素セレクターであるターゲット疑似セレクターから構成されます。
効果ターゲットがElement
であれば、
ターゲット要素はその要素で、
ターゲット疑似セレクターはnull
となります。
効果ターゲットが疑似要素であれば、
ターゲット要素はその発生要素であり、
ターゲット疑似セレクターはその疑似要素を特定するために必要なものとなります。
この方法で指定されたすべての効果ターゲット(例えば::part()疑似要素や非対応疑似要素など)が算出プロパティ値を持つとは限らないことに注意してください。
5.3.1. キーフレーム
効果値はキーフレーム効果について、 分数オフセット位置に配置された一連のプロパティ値間を補間することで計算されます。 各オフセットでインデックス付けされたプロパティ値の集合をキーフレームと呼びます。
キーフレームのオフセットは[0, 1]の範囲にある値、もしくは特別な値nullです。 キーフレームのリストはキーフレーム効果ごとに オフセット順にゆるくソートされている必要があります。これは、nullでないキーフレームのオフセットを持つ各キーフレームについて、そのオフセットが直前のnullでないキーフレームのオフセット以上でなければならないことを意味します。
キーフレームが重複したり非対応値を持つ場合の動作は、§ 5.3.4 キーフレーム効果の効果値で定義されています。
各キーフレームには、指定されたキーフレームとリスト内の次のキーフレーム間の期間に適用されるタイミング関数が関連付けられています。 リスト内の最後のキーフレームに指定されたタイミング関数は決して適用されません。
各キーフレームは、キーフレーム固有合成操作を持つ場合があり、設定されていればそのキーフレームで指定されたすべての値に適用されます。 操作の種類と意味は、キーフレーム効果全体に関連付けられる合成操作と同じであり、§ 5.4.4 効果合成で定義されています。 キーフレーム固有合成操作が未設定の場合は、そのキーフレームに指定された値には合成操作が用いられます。
5.3.2. プロパティ値の算出
Element
elementが与えられたとき、プロパティ値を算出するには:
propertyの定義テーブルの「算出値」行に従ってvalueを解決し、依存関係を解決するためのコンテキストとしてelementの算出値を使用し、その結果を返します。
注: element上の算出値は、このアルゴリズムで影響を受けません。
このアルゴリズムは、キーフレームで指定されたプロパティ値が順序依存性を確立できることを意味します。 プロパティ値を算出する場合、valueが持つ依存関係の算出値は先に計算されなければなりません。
var animation= elem. animate([{ fontSize: '10px' , width: '10em' }, { fontSize: '20px' , width: '20em' }], 1000 ); animation. currentTime= 500 ; console. log( getComputedStyle( elem). fontSize); // Should be 15px console. log( getComputedStyle( elem). width); // Should be 225px
この例では、10em
のプロパティ値を算出するには、
算出値としてfont-sizeをターゲット要素上で知る必要があります。これは効果値としてfont-sizeに決定され、そのためにはfont-sizeのプロパティ値も算出しなければなりません。
よって、プロパティ値の算出には順序制約が伴います。
5.3.3. 算出キーフレームの計算
キーフレーム効果の効果値を計算する前に、 そのキーフレーム上のプロパティ値は算出され、nullのキーフレームのオフセットには使用するオフセットが算出されます。この解決結果が算出キーフレームです。
適切な値が割り当てられたnullのキーフレームのオフセットを含むキーフレームの集合の算出キーフレームのオフセットは、算出キーフレームオフセットと呼びます。
算出キーフレームオフセットを生成するため、キーフレームの列keyframesを受け取る欠損キーフレームオフセットの算出手順を定義し、以下の手順を実行します:
-
keyframes内の各キーフレームについて、 そのキーフレームの算出キーフレームオフセットを、もとのキーフレームのオフセット値と同じにします。
-
keyframesに複数のキーフレームがあり、最初のキーフレームの算出キーフレームオフセットがnullの場合、 最初の算出キーフレームオフセットを0に設定します。
-
最後のキーフレームの算出キーフレームオフセットがnullの場合、その算出キーフレームオフセットを1に設定します。
-
各ペアのキーフレームAとBについて:
-
AがBよりkeyframes内で前に現れ、
-
AとBの算出キーフレームオフセットがnullでなく、
-
AとBの間にあるすべてのキーフレームの算出キーフレームオフセットがnullである場合、
AとBの間にある各キーフレームの算出キーフレームオフセットを以下のように計算します:
-
offsetkを、算出キーフレームオフセットのkの値とします。
-
nを、AとBを含む間のキーフレーム数から1を引いた値とします。
-
keyframeがAの直後ならindexは1、というように、A~B間のキーフレーム列におけるkeyframeの位置をindexとします。
-
keyframeの算出キーフレームオフセットを offsetA + (offsetB − offsetA) × index / nとします。
-
算出キーフレームは以下の手順で生成します。 この手順は、算出プロパティ値が計算可能なキーフレーム効果の効果ターゲットにのみ実施されることに注意してください。
-
computed keyframesを空のキーフレームのリストとします。
-
このキーフレーム効果に指定されたキーフレームのリストの各keyframeについて、以下の手順を実行します:
-
新しい空のキーフレーム、computed keyframeをcomputed keyframesに追加します。
-
keyframeで指定された各プロパティについて:
-
プロパティ値を算出するを、keyframeで指定された値をvalue、ターゲット要素をelementとして実行し、そのプロパティと結果値をcomputed keyframeに追加します。
-
ショートハンドプロパティの場合は、対応するロングハンドプロパティも追加します。
-
論理プロパティ[CSS-LOGICAL-1]の場合は、 対応する物理プロパティ[CSS-WRITING-MODES-4]を、 writing-modeおよびdirectionの算出値に基づき、 効果ターゲットについて追加します。
例えば、keyframeのborder-widthプロパティ値が"12pt"の場合、ユーザーエージェントは、ロングハンドプロパティであるborder-bottom-width、border-left-width、border-right-width、border-top-widthそれぞれについて"16px"の算出値を算出できます。 その結果、computed keyframeにはborder-widthの値は含まれず、 代わりに各ロングハンドプロパティとその値"16px"が含まれることとなります。
ショートハンドプロパティの展開や論理プロパティの物理プロパティへの置換で競合が起きた場合は、以下のルールを順に適用し、解決します:
-
ロングハンドプロパティはショートハンドプロパティより優先します(例:border-top-colorはborder-topより優先)。
-
ロングハンド成分が少ないショートハンドプロパティは多いものより優先します(例:border-topはborder-colorより優先)。
-
物理プロパティは論理プロパティより優先します。
-
ロングハンド成分数が同じショートハンドプロパティでは、IDL名(CSSプロパティからIDL属性へのアルゴリズム[CSSOM])のUnicodeコードポイント順で早いものが優先されます。
-
-
-
欠損キーフレームオフセットの算出手順をcomputed keyframesに適用します。
-
computed keyframesを返します。
5.3.4. キーフレーム効果の効果値
キーフレーム効果のターゲットプロパティとして参照される単一プロパティの効果値は、指定されたiteration progress、current iteration、underlying valueに対して次の手順で計算されます。
-
iteration progressが未解決なら、この手順を中止します。
-
target propertyを、効果値を計算するためのロングハンドプロパティとします。
-
キーフレーム効果に効果ターゲットがない場合、 または効果ターゲットで算出プロパティ値が計算できない場合、この手順を中止します。
-
property-specific keyframesを、このキーフレーム効果に対する算出キーフレーム集合として取得します。
-
property-specific keyframesから、target propertyのプロパティ値がないキーフレームを除外します。
-
property-specific keyframesが空なら、underlying valueを返します。
-
property-specific keyframes内にキーフレームで算出キーフレームオフセットが0のものがなければ、 キーフレームを新規作成し、算出キーフレームオフセットを0、プロパティ値を合成の中立値、合成操作をaddとして、property-specific keyframesの先頭に追加します。
-
同様に、property-specific keyframes内にキーフレームで算出キーフレームオフセットが1のものがなければ、 キーフレームを新規作成し、算出キーフレームオフセットを1、プロパティ値を合成の中立値、合成操作をaddとして、property-specific keyframesの末尾に追加します。
-
interval endpointsを空のキーフレーム列とします。
-
以下の最初に一致した条件に従い、interval endpointsを決定します:
- iteration progress < 0 かつ キーフレームで算出キーフレームオフセット0が複数ある場合
-
property-specific keyframesの最初のキーフレームをinterval endpointsに追加します。
- iteration progress ≥ 1 かつ キーフレームで算出キーフレームオフセット1が複数ある場合
-
property-specific keyframesの最後のキーフレームをinterval endpointsに追加します。
- それ以外の場合
-
-
interval endpointsに、iteration progress以下かつ1未満の算出キーフレームオフセットを持つproperty-specific keyframesの最後のキーフレームを追加します。該当がなければ(例えばiteration progressが負の場合)、算出キーフレームオフセットが0の最後のkeyframeを追加します。
-
前のステップで追加したkeyframeの次のproperty-specific keyframesをinterval endpointsに追加します。
-
-
interval endpoints内の各keyframeについて:
-
interval endpointsにキーフレームが1つだけなら、そのkeyframeのtarget propertyのプロパティ値を返します。
-
start offsetをinterval endpointsの最初のキーフレームの算出キーフレームオフセットとします。
-
end offsetをinterval endpointsの最後のキーフレームの算出キーフレームオフセットとします。
-
interval distanceを
(iteration progress - start offset) / (end offset - start offset)
で評価した結果とします。 -
transformed distanceを、interval endpointsの最初のキーフレームに関連付けられたタイミング関数にinterval distanceを入力進行度として渡して評価した結果とします。
-
interval endpointsの2つのキーフレームで指定されたtarget propertyの値を、最初の値をVstart、2つ目をVendとし、transformed distanceを補間パラメータpとして、補間手順(target propertyのアニメーション型で定義)を適用した結果を返します。
この手順は、効果に指定されたキーフレームリストについて以下を前提としています:
-
各キーフレームは、[0, 1]の範囲の算出キーフレームオフセットを持つ。
-
キーフレームリストは、算出キーフレームオフセットの昇順でソートされている。
-
1つのプロパティについて、各キーフレーム上に指定されるプロパティ値は高々1つである。
これらの条件を満たすのはモデル利用者の責任です(例えば宣言的マークアップやプログラミングインターフェースなど)。
本仕様で定義されるプログラミングインターフェースの場合、これらの条件は算出キーフレーム生成手順によって満たされ、この手順への入力となります。
注: この手順ではキーフレームの重複を許容します。 重複箇所では出力値はそのオフセットで定義された最後のキーフレームの値にジャンプします。 0や1で重複したキーフレームがある場合、iteration progress値が0未満または1以上の場合の出力値は、keyframesの最初のキーフレームまたは最後のキーフレームの値となります。
例えば、font-sizeプロパティが10px
から20px
へ移行中の場合、キーフレームで1em
と指定すると、キーフレーム算出時にはfont-sizeの遷移で生成される[10px
, 20px
]範囲の算出値が解決に使われます。
この制限を撤廃する案も検討しました。範囲外のiteration progress値で非線形なプロパティ値変化を指定したい場合が有用なケースがあるためです。 例:緑から黄へ補間するアニメーションで、オーバーシュートするタイミング関数によって一時的に黄を越えて赤まで補間し、その後黄へ戻る。
この効果はキーフレームやタイミング関数の修正で達成可能ですが、そのアプローチはタイミングとアニメーション効果の分離というモデルを崩すように思われます。
どのようにこの効果を実現すべきかは未定ですが、キーフレームオフセットを[0, 1]の外に許容すると、0や1のキーフレーム自動生成仕様と不整合になる可能性があります。
section 4 (Keyframe offsets outside [0, 1]) of minuted discussion from Tokyo 2013 F2F
5.4. 効果の合成
キーフレーム効果の効果値を計算した後、それらはアニメーション効果のターゲットプロパティに適用されます。
複数のin effectのキーフレーム効果が同じプロパティをターゲットにすることがあるため、複数のキーフレーム効果の結果を合成する必要があります。 このプロセスは合成と呼ばれ、各ターゲットプロパティごとに効果スタックを確立することに基づいています。
合成されたキーフレーム効果の結果は、ターゲットプロパティに指定された他の値と合成されます。
下図はその構成を示します:
同じプロパティをターゲットにするキーフレーム効果の結果は効果スタックで合成されます。
合成結果はCSSカスケードに適切な位置で挿入されます。
この操作の前半(同じプロパティをターゲットにする効果値の合成)については、 どのようにキーフレーム効果同士を合成するか、 およびどの順序でそれらを適用するか(つまり相対的な合成順序)を決定する必要があります。
どのように効果値を合成するかは、対応するキーフレーム効果の合成操作によって決まります。
各アニメーションプロパティの合成順序は、効果スタックで決定されます。
5.4.1. アニメーションクラス
本仕様は、他の仕様がこのモデル上にマークアップやプログラミングインターフェースを定義する際に用いる共通アニメーションモデルを提供します。あるアニメーションを生成した特定のマークアップやプログラムインターフェースが、そのアニメーションクラスを定義します。
さらなる仕様では、異なるアニメーションクラス間や特定のクラス内で、合成順序に対する特殊な挙動を定義できます。
例えば、classが"CSS animation"のアニメーションは、 "CSS transition"のクラスより高い合成順序を持ち、クラス未指定の他のアニメーションより低い順序を持つと定義されています。
"CSS animation"オブジェクトの集合内では、animation-nameプロパティなどの要素に基づいて専門的な合成順序が定義されています。
5.4.2. 効果スタック
各キーフレーム効果がターゲットとするプロパティターゲットプロパティごとに効果スタックが関連付けられます。 効果スタックは、キーフレーム効果の相対合成順序を確立します。
任意の2つのキーフレーム効果AとBの合成順序は、効果スタック内で以下のプロパティ比較により決定されます:
-
AとBを、以下の条件を順に適用し順序が確定するまでソートします:
-
まだ順序が確定しなければ、共通クラス内で定義されたクラス固有の合成順序でソートします。
-
まだ順序が確定しなければ、関連アニメーションのグローバルアニメーションリスト内の位置でソートします。
より早くソートされるアニメーション効果は、より低い合成順序を持ちます。
5.4.3. 効果スタックの結果の計算
効果スタックの最終値を計算するには、スタック内の各キーフレーム効果の効果値を合成順序で合成します。
効果スタックの評価プロセスの各ステップは、入力として基底値を受け取ります。
スタック内の各キーフレーム効果について、キーフレーム効果から適切な効果値を取得し、基底値と合成して新しい値を作ります。 この値は、次のキーフレーム効果との合成時の基底値となります。
効果スタックの最終値(合成値と呼ぶ)は、スタックの最後(最も高い合成順序)のキーフレーム効果の効果値とその時点の基底値を合成した結果です。
5.4.4. 効果の合成
効果値と基底値の合成に使われる具体的な操作は、効果値を生成したキーフレーム効果の合成操作によって決まります。
本仕様では、次の3つの合成操作を定義します:
- replace
- add
-
効果値を加算して基底値に合成します。 アニメーション型によっては、加算操作が可換でない場合があり、そのときの順序は
基底値 + 効果値
です。 - accumulate
-
効果値を累積して基底値に合成します。 アニメーション型によっては、累積操作が可換でない場合があり、そのときの順序は基底値、次に効果値です。
5.4.5. 合成結果の適用
合成値をターゲットプロパティに適用するには、指定値をCSSカスケードに追加します。
この指定値がカスケードに追加されるレベルは、効果スタック内で最も高い合成順序の効果が関連付けられているアニメーションのクラスによって決まります。 デフォルトでは、指定値はカスケードの「アニメーション宣言」レベルに追加されます([css-cascade-3])。
例えば、最も高い合成順序の効果が"CSS transition"クラスのアニメーションに関連付けられている場合、合成値はカスケードの「トランジション宣言」レベルに追加されます。
CSSのターゲットプロパティに対して計算された合成値は、次の手順で適用されます。
-
プロパティのbase valueを、アニメーションがない場合にそのプロパティの算出値を計算した結果値とします。
-
プロパティの効果スタックを確立します(§ 5.4.2 効果スタック参照)。
-
プロパティのbase valueを初期基底値として効果スタックの合成値を計算します(§ 5.4.3 効果スタックの結果の計算参照)。
-
確立されたターゲットプロパティの効果スタックの先頭の効果に関連付けられているアニメーションのクラスで定義されたレベルに合成値をCSSカスケードに挿入します。
5.5. アニメーションの置換
本仕様で定義されるプログラミングインターフェースを使用すると、要素のアニメーションスタイルに無限に新しいアニメーションを繰り返し追加することができます。
例えば、以下のコードを考えてみましょう:
elem. addEventListener( 'mousemove' , evt=> { circle. animate( { transform: `translate( ${ evt. clientX} px, ${ evt. clientY} px)` }, { duration: 500 , fill: 'forwards' } ); });
これはマウスが動くたびに新しいforwards fillアニメーションを生成し、すぐに何百、何千ものforwards fillアニメーションが作られます。
ユーザーエージェントがすべてのアニメーションを保持しなければならない場合、アニメーションリストが際限なく増加し、メモリリークを引き起こします。
この節では、上書きされたアニメーションが明示的な保持要求がない限り自動的に削除されるメカニズムを定義します。
5.5.1. 置換状態
アニメーションは、次の値のいずれかを持つ置換状態を保持します:
-
active(アクティブ)
-
removed(削除済)
-
persisted(保持)
アニメーションの置換状態がremovedの場合、そのアニメーション効果はターゲットプロパティの効果スタックに含まれません。
5.5.2. 置換されたアニメーションの削除
すべての次の条件を満たす場合、アニメーションは置換可能です:
Document
docの置換されたアニメーションの削除を求められた場合、すべてのアニメーションanimationについて、下記の条件を満たすものに対して:
以下の手順を実行します:
-
イベントを生成し、
AnimationPlaybackEvent
removeEventとします。 -
removeEventの
currentTime
属性を、animationの現在時刻に設定します。 -
removeEventの
timelineTime
属性を、animationが関連付けられているタイムラインの現在時刻に設定します。 -
animationがタイミング用ドキュメントを持つ場合は、removeEventをそのタイミング用ドキュメントの保留アニメーションイベントキューに、ターゲットanimationとともに追加します。 イベント予定時刻には、animationが関連付けられているタイムラインの現在時刻にタイムライン時刻を原点相対時刻へ変換手順を適用した結果を使用します。
それ以外の場合は、タスクをキューし、removeEventをanimationでdispatchします。 このタスクのタスクソースはDOM操作タスクソースです。
5.6. アニメーションの副作用
少なくとも1つのアニメーション効果によってターゲットとされ、かつcurrentまたはin effectであり、 そのアニメーションの置換状態がremovedでないすべてのプロパティについて、 ユーザーエージェントはwill-changeプロパティ([css-will-change-1])が効果ターゲット上でそのプロパティを含んでいるかのように振る舞わなければなりません。
上記要件の結果として、たとえばアニメーションが要素のtransformプロパティをターゲットにする場合、 スタッキングコンテキストが効果ターゲットに作成されます。 これはアニメーションがbeforeフェーズ、 activeフェーズ、 または塗りモードが"forwards"または"both"の場合はafterフェーズである間、有効です。
6. プログラミングインターフェース
上記の抽象モデルに加え、Web Animationsはこのモデルへのプログラミングインターフェースも定義します。 このインターフェースは宣言的手段で生成されたアニメーションの検査・拡張や、手続き的手法が適している場合に直接アニメーションを生成するために使用できます。
6.1. プログラミングインターフェースにおける時間値
時間値はプログラミングインターフェースでは
double
型で表されます。未解決の時間値は
null
値で表現されます。
6.2.
AnimationTimeline
インターフェース
タイムラインは、Web Animations APIではAnimationTimeline
インターフェースで表現されます。
[Exposed =Window ]interface {
AnimationTimeline readonly attribute double ?currentTime ; };
6.3.
DocumentTimeline
インターフェース
ドキュメントタイムライン(デフォルトドキュメントタイムラインを含む)は、Web Animations APIではDocumentTimeline
インターフェースで表現されます。
dictionary {
DocumentTimelineOptions DOMHighResTimeStamp originTime = 0; }; [Exposed =Window ]interface :
DocumentTimeline AnimationTimeline {constructor (optional DocumentTimelineOptions options = {}); };
originTime
, 型 DOMHighResTimeStamp, デフォルト値0
DocumentTimeline (options)
-
新しい
DocumentTimeline
を作成します。 タイムラインが関連付けられるDocument
は、Document
であり、 関連付けられたWindow
の 現在のグローバルオブジェクトとなります。options
-
新しく作成されるタイムラインの構成パラメータです。 本現行標準では
originTime
メンバーのみ定義しますが、他の規格で拡張される場合があります。
6.4. Animation
インターフェース
アニメーションは
Web Animations APIではAnimation
インターフェースで表現されます。
[Exposed =Window ]interface :
Animation EventTarget {constructor (optional AnimationEffect ?effect =null ,optional AnimationTimeline ?timeline );attribute DOMString id ;attribute AnimationEffect ?effect ;attribute AnimationTimeline ?timeline ;attribute double ?startTime ;attribute double ?currentTime ;attribute double playbackRate ;readonly attribute AnimationPlayState playState ;readonly attribute AnimationReplaceState replaceState ;readonly attribute boolean pending ;readonly attribute Promise <Animation >ready ;readonly attribute Promise <Animation >finished ;attribute EventHandler onfinish ;attribute EventHandler oncancel ;attribute EventHandler onremove ;undefined cancel ();undefined finish ();undefined play ();undefined pause ();undefined updatePlaybackRate (double playbackRate );undefined reverse ();undefined persist (); [CEReactions ]undefined commitStyles (); };
Animation (effect, timeline)
-
以下の手順で新しい
Animation
オブジェクトを作成します。-
animationを新しい
Animation
オブジェクトとします。 -
animationに対し、アニメーションのタイムラインを設定する手順を実行し、timelineをnew timelineとして渡します。timeline引数がない場合は、
Document
のデフォルトドキュメントタイムライン(Window
の現在のグローバルオブジェクトに関連付けられている)を渡します。 -
animationに対し、アニメーションの関連効果を設定する手順を実行し、sourceをnew effectとして渡します。
effect
timeline
-
オプション値。指定すれば新しく作成されるアニメーションに関連付けるタイムラインを指定します。 省略時は、
Document
のデフォルトドキュメントタイムライン(Window
の現在のグローバルオブジェクトに関連付けられている)を使用します。
-
id
, 型 DOMString-
アニメーションを識別するための文字列。
effect
, 型 AnimationEffect、null許容-
このアニメーションの関連効果。 この属性を設定すると、アニメーションの関連効果を設定する手順に従いオブジェクトの関連効果が更新されます。
timeline
, 型 AnimationTimeline、null許容-
このアニメーションに関連付けられたタイムライン。 この属性を設定すると、アニメーションのタイムラインを設定する手順に従いオブジェクトのタイムラインが更新されます。
startTime
, 型 double、null許容-
このアニメーションの開始時刻を返します。 この属性を設定すると、開始時刻を設定する手順に従いオブジェクトの開始時刻を新しい値で更新します。
currentTime
, 型 double、null許容-
このアニメーションの現在時刻。 この属性を設定すると、現在時刻を設定する手順に従いオブジェクトの現在時刻を新しい値に更新します。
playbackRate
, 型 double-
このアニメーションの再生速度。 この属性を設定すると、再生速度を設定する手順に従いオブジェクトの再生速度を新しい値に更新します。
この属性を設定すると、再生速度の同期更新が行われ、別プロセスやスレッドで再生中のアニメーションの再生状態との同期は試みません。 そのため、再生中のアニメーションに対し
playbackRate
を設定するとジャンプすることがあります。再生中のアニメーションの再生速度を滑らかに変更するには、非同期の
updatePlaybackRate()
メソッドを使ってください。 playState
, 型 AnimationPlayState、読み取り専用-
このアニメーションの再生状態。
replaceState
, 型 AnimationReplaceState、読み取り専用-
このアニメーションの置換状態。
pending
, 型 boolean、読み取り専用ready
, 型 Promise<Animation>、読み取り専用-
このオブジェクトの現行標準readyプロミスを返します。
finished
, 型 Promise<Animation>、読み取り専用-
このオブジェクトの現行標準終了プロミスを返します。
onfinish
, 型 EventHandler-
finishイベントのイベントハンドラ。
oncancel
, 型 EventHandler-
cancelイベントのイベントハンドラ。
onremove
, 型 EventHandler-
removeイベントのイベントハンドラ。
void cancel()
-
このアニメーションによるすべての効果をクリアし、再生を中止します。アニメーションのキャンセル手順を実行します。
void finish()
-
アニメーションを現在の方向で関連効果の終了点までシークします。アニメーションの終了手順を実行します。
- DOMException 型
InvalidStateError
- DOMException 型
void play()
-
アニメーションの再生を開始または再開します。アニメーションの再生手順を実行し、auto-rewindフラグにtrueを渡します。
void pause()
-
このアニメーションの再生を一時停止します。アニメーションの一時停止手順を実行します。
void updatePlaybackRate(playbackRate)
-
このアニメーションの再生速度を非同期で更新します。再生速度のシームレスな更新手順を実行し、
playbackRate
をnew playback rateとして渡します。playbackRate
-
更新後の再生速度を指定する有限実数。
void reverse()
-
このアニメーションの再生速度を反転し、アニメーションの逆再生手順を実行して再生します。 play()と同様、このメソッドはアニメーションを一時停止状態から解除し、すでに逆方向で終了している場合は関連効果の開始点までシークします。
void persist()
void commitStyles()
-
このアニメーションのアニメーション効果が生成した効果値を、それぞれの効果ターゲットのインラインスタイルに書き込みます。算出スタイルのコミット手順を実行します。
このメソッドは、このインターフェースの多くの他のメソッドとは異なり、スタイル変更イベントを発火します(§ 6.13 モデルのライブ性参照)。
算出スタイルのコミット手順は、アニメーションがremovedであっても効果値を含むため、 このメソッドはアニメーションが置換された後も(§ 5.5.2 置換されたアニメーションの削除参照)アニメーションの効果のみを残したい場合に有用です。
コミットされる値は算出値であり、ライブアニメーションが生成する値のようにCSS変数の変化やem単位の再計算など、コンテキスト変化には反映されません。
置換後も塗りアニメーションの結果を完全に残したい場合(§ 5.5 アニメーションの置換参照)は、
persist()
メソッドを使えます。ただし、その場合アニメーションはリソースを引き続き消費します。
算出スタイルをコミットするには、アニメーションanimationについて:
-
各targetについて:
-
targetがstyle属性を持つことができる要素でない場合(例:疑似要素や、style属性が定義されていない文書形式の要素)、throwし、「
NoModificationAllowedError
」DOMException
を発生させ、これらの手順を中止する。 -
保留中のスタイル変更を適用した後、targetが描画されていない場合、throwし、「
InvalidStateError
」DOMException
を発生させ、これらの手順を中止する。描画されているの定義は、display: contentsとの関係でまだ議論中です。 この手順の目的では、display: contentsであっても、他にレイアウトボックスが関連付けられる(接続済みで、display: noneのサブツリーでない)場合は描画されているとみなします。
-
inline styleを、targetのCSS宣言ブロック(style属性に対応)取得結果とします。 targetがstyle属性を持たない場合は、inline styleを新しい空のCSS宣言ブロック(オーナーノードはtarget)とします。
-
targeted propertiesを、animationに関連付けられているすべてのアニメーション効果のうち、targetを効果ターゲットとするものの、物理ロングハンドプロパティのターゲットプロパティのセットとする。
-
各プロパティpropertyについて:
-
partialEffectStackをtarget上のpropertyの効果スタックのコピーとします。
-
animationの置換状態がremovedなら、animationに関連付けられているすべてのアニメーション効果のうち、targetを効果ターゲットとし、propertyをターゲットプロパティに含むものをpartialEffectStackに追加します。
-
partialEffectStackから、animationより高い合成順序を持つアニメーションに関連付けられているアニメーション効果を削除します。
-
effect valueを、partialEffectStackについてpropertyの結果を計算し(targetの算出スタイルを使用)、その結果とします(§ 5.4.3 効果スタックの結果の計算参照)。
-
CSS宣言を設定するで、propertyにeffect valueをinline styleに設定します。
-
-
style属性を更新するでinline styleを更新します。
-
6.4.1. AnimationPlayState
列挙型
enum {
AnimationPlayState ,
"idle" ,
"running" ,
"paused" };
"finished"
6.4.2. AnimationReplaceState
列挙型
enum {
AnimationReplaceState ,
"active" ,
"removed" };
"persisted"
6.5.
AnimationEffect
インターフェース
アニメーション効果は
Web Animations APIでは抽象AnimationEffect
インターフェースで表現されます。
[Exposed =Window ]interface {
AnimationEffect EffectTiming getTiming ();ComputedEffectTiming getComputedTiming ();undefined updateTiming (optional OptionalEffectTiming timing = {}); };
any onupdate (double? progress,
double currentIteration, Animatable? target, any
underlyingValue)
を公開し、アニメーション効果がタイミングモデルとは独立して駆動できるようにする可能性があります。 getTiming()
-
このアニメーション効果に指定されたタイミングプロパティを返します。
返される
EffectTiming
オブジェクトのメンバーとタイミングモデルのプロパティの対応は、EffectTiming
インターフェースを参照してください。 getComputedTiming()
-
このアニメーション効果の計算済みタイミングプロパティを返します。
getTiming()
やgetComputedTiming()
で返されるオブジェクトの属性には共通するものもありますが、値は以下のように異なります:-
duration
-getTiming()
は文字列auto
を返す場合がありますが、getComputedTiming()
は、反復期間の計算値に対応する数値を返さなければなりません。詳細はduration
メンバーの説明を参照。この現行標準では、
auto
値は単にゼロに置き換えられることを意味します。 -
fill
- 同様に、getTiming()
は文字列auto
を返す場合がありますが、getComputedTiming()
は、タイミング計算に使われる具体的なFillModeを返さなければなりません。詳細はfill
メンバーの説明を参照。この現行標準では、
auto
値は単にnone
のFillModeに置き換えられます。
注: 他のタイミングメンバーも将来的に
auto
のような値が拡張される可能性があります。タイミング計算を行う際は、許容値の範囲や型が変更された場合の互換性を避けるため、可能な限りgetComputedTiming()
を利用することが推奨されます。返される値の違いに加え、
getTiming()
と比較して、getComputedTiming()
は、ComputedEffectTiming
辞書で定義される追加のタイミング情報も返します。 -
updateTiming(timing)
-
このアニメーション効果の指定タイミングプロパティを更新します。
timing
パラメータをinputとして、アニメーション効果のタイミングプロパティを更新する手順を実行します。optional
OptionalEffectTiming
timing
remove()
メソッドは、効果を親グループやアニメーションから除去するために使える。現行標準レベル1に残し、単にアニメーションからアニメーション効果を除去するものとして定義すべきか? [Issue #2082]
6.5.1.
EffectTiming
およびOptionalEffectTiming
辞書
EffectTiming
辞書は、AnimationEffect
のタイミングプロパティを表します。
OptionalEffectTiming
辞書は、EffectTiming
辞書のバリエーションで、一部のメンバーが存在しないことを許容します。
これはupdateTiming()
メソッドで、AnimationEffect
インターフェースのタイミングプロパティをデルタ更新する際に使用されます。
アニメーション効果のタイミングプロパティの差分更新に用います。
dictionary {
EffectTiming double delay = 0;double endDelay = 0;FillMode fill = "auto";double iterationStart = 0.0;unrestricted double iterations = 1.0; (unrestricted double or DOMString )duration = "auto";PlaybackDirection direction = "normal";DOMString easing = "linear"; };dictionary {
OptionalEffectTiming double delay ;double endDelay ;FillMode fill ;double iterationStart ;unrestricted double iterations ; (unrestricted double or DOMString )duration ;PlaybackDirection direction ;DOMString easing ; };
delay
, 型 double、デフォルト値0
endDelay
, 型 double、デフォルト値0
fill
, 型 FillMode、デフォルト値"auto"
-
塗りモード(fill mode)。アニメーション効果がアクティブ区間外でどのように振る舞うか定義します。
タイミング計算時、特別な文字列値
auto
はタイミングモデルが認識する以下の塗りモードに展開されます:§ 4.6 塗りの挙動で述べられている通り、作者が無限に塗り続けるアニメーションの使用は推奨しません。 iterationStart
, 型 double、デフォルト値0.0
-
アニメーション効果の反復開始プロパティ。0以上の有限実数で、アニメーション効果がどの反復インデックスからどの進行度で始まるかを表します。
例えば0.5なら、アニメーション効果は最初の反復の途中から始まります。1.2なら2回目の反復の20%から始まることになります。
iterations
の値はiterationStart
に加算される扱いとなり、iterationStart
が"0.5"でiterations
が"2"の場合、2回繰り返しますが開始・終了ともに反復区間の途中からとなります。iterationStart
が1以上の値は、反復合成操作がaccumulateの場合、または現在の反復インデックスが重要な場合にのみ有用です。 iterations
, 型 unrestricted double、デフォルト値1.0
-
アニメーション効果の反復回数プロパティ。0以上の実数(正の無限大も含む)で、アニメーション効果を何回繰り返すかを表します。
+Infinity
を設定すると、アニメーション効果は無限に繰り返されます(効果の持続時間が0の場合はすぐに終了します)。 duration
, 型(unrestricted double or DOMString)
、デフォルト値"auto"
-
反復期間。0以上の実数(正の無限大も含む)で、アニメーション効果の1回の反復に要する時間を表します。
この現行標準では、文字列値
auto
はタイミングモデルの計算では0として扱われ、duration
メンバーをgetComputedTiming()
で取得した場合も0になります。 作者がauto
を指定した場合、duration
メンバーをgetTiming()
で取得した場合はauto
を返す必要があります。これは将来の互換性措置であり、将来の現行標準ではグループ効果によって
auto
値が子効果の持続時間も含めて展開されることが予想されます。 direction
, 型 PlaybackDirection、デフォルト値"normal"
easing
, 型 DOMString、デフォルト値"linear"
-
タイミング関数(easing function)。時間をスケールしてイージング効果を生成します。
文字列の構文は<easing-function> 生成規則([CSS-EASING-1])で定義されています。
6.5.2.
FillMode
列挙型
enum {
FillMode ,
"none" ,
"forwards" ,
"backwards" ,
"both" };
"auto"
none
-
塗りなし。
forwards
-
前方塗り。
backwards
-
後方塗り。
both
-
前方・後方両方塗り。
auto
-
塗りなし。 今後の現行標準レベルで他種類のアニメーション効果に対して異なる動作になる場合があります。
6.5.3.
PlaybackDirection
列挙型
enum {
PlaybackDirection ,
"normal" ,
"reverse" ,
"alternate" };
"alternate-reverse"
normal
-
すべての反復は指定通りに再生されます。
reverse
-
すべての反復は指定された順序と逆方向に再生されます。
alternate
-
偶数回の反復は指定通り、奇数回の反復は逆方向に再生されます。
alternate-reverse
-
偶数回の反復は逆方向、奇数回の反復は指定通りに再生されます。
6.5.4.
AnimationEffect
のタイミングの更新
アニメーション効果のタイミングプロパティを更新するには、effectに対して、
EffectTiming
またはOptionalEffectTiming
オブジェクトinputを使い、以下の手順を実行します:
-
inputの
iterationStart
メンバーが存在し、0未満の場合は、TypeErrorをthrowして、この手順を中止します。注: TypeErrorを使う理由は、将来的にWebIDLの[EnforceRange]アノテーションが浮動小数点値にも適用できるようになった場合に、挙動を合わせるためです。
-
inputの
iterations
メンバーが存在し、 かつ0未満またはNaN
の場合は、TypeErrorをthrowして、この手順を中止します。 -
inputの
duration
メンバーが存在し、 かつ0未満またはNaN
の場合は、TypeErrorをthrowして、この手順を中止します。 -
inputの
easing
メンバーが存在し、かつ<easing-function> 生成規則でパースできない場合は、TypeErrorをthrowして、この手順を中止します。 -
inputで存在する各メンバーを、以下の対応でeffectのタイミングプロパティに割り当てます:
6.5.5. ComputedEffectTiming
辞書
タイミングモデルで計算されたタイミングプロパティはComputedEffectTiming
辞書オブジェクトで公開されます。
dictionary :
ComputedEffectTiming EffectTiming {unrestricted double endTime ;unrestricted double activeDuration ;double ?localTime ;double ?progress ;unrestricted double ?currentIteration ; };
endTime
, 型 unrestricted double-
アニメーション効果の終了時刻。ゼロローカル時刻(つまりこのアニメーション効果がアニメーションに関連付けられている場合はアニメーションの開始時刻)からのミリ秒で表されます。 これはアニメーション効果のアクティブ区間の終了+終了遅延に対応します。
activeDuration
, 型 unrestricted doublelocalTime
, 型 double、null許容-
このアニメーション効果がアニメーションに関連付けられていない場合は
null
となります。 progress
, 型 double、null許容currentIteration
, 型 unrestricted double、null許容-
現在の反復インデックス。最初の反復はゼロから始まります。
通常は正の整数ですが、持続時間ゼロかつ無限回繰り返すアニメーションの場合は値が正のInfinityになります。
6.6.
KeyframeEffect
インターフェース
キーフレーム効果は
KeyframeEffect
インターフェースで表現されます。
[Exposed =Window ]interface :
KeyframeEffect AnimationEffect {constructor (Element ?target ,object ?keyframes ,optional (unrestricted double or KeyframeEffectOptions )options = {});constructor (KeyframeEffect source );attribute Element ?target ;attribute CSSOMString ?pseudoElement ;attribute CompositeOperation composite ;sequence <object >getKeyframes ();undefined setKeyframes (object ?); };
keyframes
KeyframeEffect (target, keyframes, options)
-
以下の手順で新しい
KeyframeEffect
オブジェクトを作成します:-
新しい
KeyframeEffect
オブジェクトeffectを作成します。 -
effectのターゲット要素をtargetに設定します。
-
ターゲット疑似セレクタを、以下の最初に一致する条件の結果で設定します。
- もしoptionsが
KeyframeEffectOptions
オブジェクトで、pseudoElement
プロパティを持つ場合 -
ターゲット疑似セレクタを
pseudoElement
プロパティの値で設定します。このプロパティを設定する際は、インターフェースの
pseudoElement
セッターで定義されたエラーハンドリングが適用されます。 セッターで例外が必要な場合、この手順も同じ例外をthrowし、それ以降の手順を中止します。 - それ以外の場合
-
ターゲット疑似セレクタを
null
に設定します。
- もしoptionsが
-
timing inputを、以下の最初に一致する条件の結果とします。
- もしoptionsが
KeyframeEffectOptions
オブジェクトの場合 -
timing inputをoptionsとします。
- それ以外(optionsが
double
の場合) -
timing inputを、すべてのメンバーがデフォルト値で設定された新しい
EffectTiming
オブジェクトで、duration
をoptionsに設定します。
- もしoptionsが
-
effectのアニメーション効果のタイミングプロパティを更新する手順をtiming inputで呼び出します。
その手順で例外が発生した場合は、その例外を伝播させてこの手順を中止します。
-
optionsが
KeyframeEffectOptions
オブジェクトの場合、effectのcomposite
プロパティにoptionsの対応する値を設定します。このプロパティを設定する際は、
KeyframeEffect
インターフェース上の対応するセッターのエラーハンドリングが適用されます。 optionsで指定された値に対してセッターが例外を必要とする場合は、この手順も同じ例外をthrowし、それ以降の手順を中止します。 -
keyframesを入力として
setKeyframes()
手順を実行し、キーフレーム集合を初期化します。
Element
? target-
ターゲット要素。 特定の要素を対象としないアニメーションの場合は
null
を指定できます。 object? keyframes
-
使用するキーフレーム集合。 この引数のフォーマットと処理は§ 6.6.3 キーフレーム引数の処理で定義されています。
optional
KeyframeEffectOptions
options-
エフェクトの反復期間を指定する数値、またはエフェクトのタイミングや挙動を指定するプロパティ集合。
このコンストラクタの使用例は§ 6.6.1 新しいKeyframeEffectオブジェクトの作成で示されています。
-
KeyframeEffect (source)
-
以下の手順で、
source
と同じプロパティを持つ新しいKeyframeEffect
オブジェクトを作成します:-
新しい
KeyframeEffect
オブジェクトeffectを作成します。 -
effectの下記プロパティをsourceの対応する値で設定します:
注:
KeyframeEffect(target, keyframes, options)
コンストラクタと異なり、例外を再throwする必要はありません。sourceに指定されたタイミングプロパティは有効だとみなされるためです。
KeyframeEffect
source-
新しいキーフレーム効果を定義するプロパティをコピーする元のキーフレーム効果。
-
target
, 型 Element、null許容-
このオブジェクトによってアニメーションされるターゲット要素(
Element
なら効果ターゲット、疑似要素なら発生元要素)。 音声APIでサウンド生成など、特定要素を対象としないアニメーションの場合はnull
となります。 pseudoElement
, 型 CSSOMString、null許容-
ターゲット疑似セレクタ。 効果ターゲットがない場合や、効果ターゲットが要素(疑似要素でない)の場合は
null
。 効果ターゲットが疑似要素の場合、この値は疑似要素セレクタ(例:::before
)となります。設定時は、アニメーション効果のターゲット疑似セレクタに指定値を設定しますが、以下の例外を適用します:
-
値が
null
でなく、かつ無効な<pseudo-element-selector>の場合、ユーザーエージェントはDOMException
(エラー名SyntaxError
)をthrowし、アニメーション効果のターゲット疑似セレクタは変更しません。注: この文脈での「無効」は、無効セレクタ([SELECTORS-4])の定義に従い、構文的に無効な疑似要素や、ユーザーエージェントがサポートしない疑似要素も無効とみなします。
-
レガシーSelectors Level 2のシングルコロンセレクタ(':before', ':after', ':first-letter', ':first-line')が指定された場合、ターゲット疑似セレクタは対応する二重コロンセレクタ(例:'::before')に設定されます。
-
composite
, 型 CompositeOperation-
このキーフレーム効果を効果スタックと合成する際に使用する合成操作。CompositeOperation列挙型値で指定されます。
sequence<object> getKeyframes()
-
この効果を構成するキーフレームとその算出キーフレームオフセットを返します。
この節は非規範的ですこのメソッドの結果は以下の形式のオブジェクト列です:
dictionary ComputedKeyframe { // ... プロパティ値のペア ... // 例:DOMString propertyNamedouble ?offset =null ;double computedOffset ;DOMString easing = "linear";CompositeOperationOrAuto composite = "auto"; };各メンバーの意味と値は以下の通りです:
offset
-
キーフレームオフセット。キーフレームの0.0以上1.0以下の数値、または
null
。キーフレームが隣接キーフレーム間で自動的に間隔調整される場合は
null
となります。 computedOffset
-
このキーフレームの算出キーフレームオフセット。欠損キーフレームオフセットの算出手順で計算されます。
offset
とは異なり、computedOffset
は常にnullになりません。 easing
-
このキーフレームから次のキーフレームまでの進行度を変換するためのタイミング関数。
composite
-
このキーフレームで指定された値を基底値と合成する際に使用するキーフレーム固有の合成操作。
キーフレームは部分的にオープンな辞書型でWebIDLで表現できないため、このメソッドの返却値生成手順は以下のように記述されます:
-
resultを空のオブジェクト列とする。
-
keyframesを以下のいずれかとする:
-
このキーフレーム効果が
CSSAnimation
に関連付けられ、キーフレームがsetKeyframes()
の呼び出しで置き換えられていない場合、キーフレーム効果の算出キーフレーム。 -
それ以外の場合、このキーフレーム効果のキーフレームに欠損キーフレームオフセットの算出手順を適用した結果。
注: CSSアニメーション用には算出キーフレームを返します。CSSで指定されたキーフレームはすべて辞書で表現できるわけではないためです。
-
-
keyframes内の各keyframeについて以下を行う:
-
以下の定義で辞書オブジェクトoutput keyframeを初期化:
dictionary
{BaseComputedKeyframe double ?
=offset null ;double
;computedOffset DOMString
= "linear";easing CompositeOperationOrAuto
= "auto"; };composite -
output keyframeの
offset
,computedOffset
,easing
,composite
をkeyframeのキーフレームオフセット、 算出キーフレームオフセット、 キーフレーム固有のタイミング関数、 キーフレーム固有の合成操作で設定します。 -
keyframeの各アニメーションプロパティ値のペアdeclarationについて以下を行う:
-
property nameを、declarationのプロパティ名にアニメーションプロパティ名からIDL属性名への変換アルゴリズムを適用した結果とする。
-
IDL valueを、declarationのプロパティ値をCSS値のシリアライズアルゴリズムに渡して得られる結果とする。
-
valueを、IDL valueをECMAScriptのString値へ変換した結果とする。
-
output keyframeに対しproperty nameでvalueを書き込み可能・列挙可能・設定可能としてfalseで定義する。
-
-
output keyframeをresultに追加する。
-
-
resultを返す。
void setKeyframes(object? keyframes)
-
この効果を構成するキーフレーム集合を置き換えます。
object? keyframes
-
キーフレーム集合の書式と処理は§ 6.6.3 キーフレーム引数の処理で定義されています。
この効果のキーフレーム集合は、キーフレーム引数の処理手順の結果で置き換えられます。 その手順で例外がthrowされた場合は、効果のキーフレームは変更されません。
6.6.1. 新しいKeyframeEffect
オブジェクトの作成
KeyframeEffect
コンストラクタは、新しいKeyframeEffect
オブジェクトを作成するための様々なアプローチを提供します。
最も単純な例として、KeyframeEffect
オブジェクトでelem
の"left"プロパティを3秒かけて100pxに変更する場合、以下のように作成できます:
第2引数(キーフレームのリスト)は、複数のプロパティを指定することもできます。(§ 6.6.3 キーフレーム引数の処理参照)
// 複数のプロパティを同時に指定 var effectA= new KeyframeEffect( elem, { left: '100px' , top: '300px' }, 3000 ); // 複数のキーフレームを指定 var effectB= new KeyframeEffect( elem, [ { left: '100px' }, { left: '300px' } ], 3000 );
第3引数(アニメーションのタイミング)は、上記のようにミリ秒単位の反復期間を表す数値でもよいですが、開始遅延などさらにタイミングプロパティを指定する場合は、以下のようにEffectTiming
オブジェクトを使うことができます:
durationが指定されていない場合は、0が使用されます。 プロパティを補間せずに単に設定するだけのアニメーションも以下のように作成できます:
§ 4.6 塗りの挙動で述べられているように、このような無限塗りのアニメーションの使用は推奨されません。
作成したKeyframeEffect
は、Animation
に追加して再生できます。
ただし、単純な効果であればElement.animate
ショートカットの方が便利で、これらの手順を自動で行ってくれます。例えば:
6.6.2. プロパティ名とIDL名
アニメーションプロパティ名からIDL属性名への変換 アルゴリズム(property用)は以下の通りです:
-
propertyが
に従う場合、 propertyを返す。 -
propertyがCSSのfloat プロパティの場合、 文字列"cssFloat"を返す。
-
propertyがCSSのoffset プロパティの場合、 文字列"cssOffset"を返す。
-
それ以外の場合、propertyにCSSプロパティからIDL属性への変換アルゴリズム([CSSOM])を適用した結果を返す。
IDL属性名からアニメーションプロパティ名への変換 アルゴリズム(attribute用)は以下の通りです:
-
attributeが
に従う場合、 attributeを返す。 -
attributeが文字列"cssFloat"の場合、CSSのfloatプロパティを表すアニメーションプロパティを返す。
-
attributeが文字列"cssOffset"の場合、CSSのoffsetプロパティを表すアニメーションプロパティを返す。
-
それ以外の場合、attributeにIDL属性からCSSプロパティへの変換アルゴリズム([CSSOM])を適用した結果を返す。
6.6.3.
keyframes
引数の処理
以下のメソッドはすべて、引数としてキーフレーム集合を受け付けます:
-
setKeyframes()
メソッド(KeyframeEffect
インターフェース) -
animate()
メソッド(Animatable
インターフェースミックスイン)
この引数は下記2つの形式のいずれかで指定できます。例:
// 下記2つの式は同じ結果になります: elem. animate([ { color: 'blue' }, { color: 'green' }, { color: 'red' }, { color: 'yellow' } ], 2000 ); elem. animate({ color: [ 'blue' , 'green' , 'red' , 'yellow' ] }, 2000 ); // 複数プロパティアニメーションの場合も、下記2つの式は等価です: elem. animate([ { color: 'blue' , left: '0px' }, { color: 'green' , left: '-20px' }, { color: 'red' , left: '100px' }, { color: 'yellow' , left: '50px' } ], 2000 ); elem. animate({ color: [ 'blue' , 'green' , 'red' , 'yellow' ], left: [ '0px' , '-20px' , '100px' , '50px' ] }, 2000 ); // ちなみに、下記3つの式はすべて等価です: elem. animate([ { color: 'red' } ], 1000 ); elem. animate({ color: [ 'red' ] }, 1000 ); elem. animate({ color: 'red' }, 1000 );
1つ目(配列形式)はキーフレームの配列で、各キーフレームは各アニメーションプロパティにつき最大1つの値を指定できます。 2つ目(オブジェクト形式)は各アニメーションプロパティに1つまたは値の配列を指定できます。
配列形式が正規形であり、getKeyframes()
メソッドで返される形式です。
キーフレームオフセットはどちらの形式でも指定可能です。例:
// オフセットを指定しない場合、自動的に最初のキーフレームは0、中間は0.65、最後は1となります。 // elem. animate([ { color: 'blue' }, { color: 'green' , offset: 0.5 }, { color: 'red' }, { color: 'yellow' , offset: 0.8 }, { color: 'pink' } ], 2000 ); // 下記も同じ結果になります。最後の値は指定不要で、自動的に'null'扱いとなり、上記と同様に自動割り当てされます。 elem. animate({ color: [ 'blue' , 'green' , 'red' , 'yellow' , 'pink' ], offset: [ null , 0.5 , null , 0.8 ] }, 2000 );
同様に、タイミング関数やキーフレーム固有の合成操作もどちらの形式でも指定できます。配列形式では各キーフレームごとに異なる値を指定でき、オブジェクト形式では値リストが必要に応じて繰り返され、各キーフレームに値が割り当てられます。
// タイミング関数はキーフレーム間に適用されるため、最後のキーフレームに指定しても無視されます。 elem. animate([ { color: 'blue' , easing: 'ease-in' }, { color: 'green' , easing: 'ease-out' }, { color: 'yellow' } ], 2000 ); // 下記も同じ結果になります。 elem. animate({ color: [ 'blue' , 'green' , 'yellow' ], easing: [ 'ease-in' , 'ease-out' ] }, 2000 ); // 繰り返し動作を使えば、全キーフレームに同じ値を割り当てるのも簡単です: elem. animate({ color: [ 'blue' , 'green' , 'yellow' ], easing: 'ease-in-out' }, 2000 );
どちらの形式でもeasing
プロパティはキーフレーム固有のタイミング関数を設定することに注意してください。
この設定は、KeyframeEffectOptions
またはKeyframeAnimationOptions
オブジェクトを使ってanimate()
メソッド(Animatable
インターフェースミックスイン)で指定する、タイミング関数とは独立しています。全体の反復期間に適用されるタイミング関数は別です。
次の例では、2つの記述は異なる結果になります。
// ここでは 'ease-in-out' が各色値の間に適用されます。 elem. animate({ color: [ 'blue' , 'green' , 'yellow' ], easing: 'ease-in-out' }, 2000 ); // 一方、こちらは 'ease-in-out' がアニメーション全体('blue'から'yellow'まで)に適用されます。 elem. animate({ color: [ 'blue' , 'green' , 'yellow' ] }, { duration: 2000 , easing: 'ease-in-out' });
keyframes
引数の型は部分的にオープンな辞書型に依存するため、WebIDLでは表現できません。
概念的には、この引数の型は以下のWebIDL風定義に等しいものです:
dictionary Keyframe { // ... プロパティ値のペア ... // 例:DOMString propertyNamedouble ?offset =null ;DOMString easing = "linear";CompositeOperationOrAuto composite = "auto"; };dictionary PropertyIndexedKeyframes { // ... プロパティ値や値リストのペア ... // 例:(DOMString or sequence<DOMString>) propertyName (double ?or sequence <double ?>)offset = []; (DOMString or sequence <DOMString >)easing = []; (CompositeOperationOrAuto or sequence <CompositeOperationOrAuto >)composite = []; };typedef (sequence <Keyframe >or PropertyIndexedKeyframes )KeyframeArgument ;
各引数の意味と許容値は以下の通りです:
- offset
-
キーフレームオフセット。キーフレームの0.0~1.0の数値または
null
。null
は、キーフレームが隣接キーフレーム間で自動的に間隔調整されることを示します。範囲[0.0, 1.0]外のoffset指定はTypeErrorをthrowします。
offsetを指定するキーフレームは昇順で並べなければなりません。ただし隣接・同値のoffsetは許容されます。
- easing
-
タイミング関数。このキーフレームから次のキーフレームまでの進行度を変換します。
この文字列の構文・エラーハンドリングは
easing
属性(EffectTiming
インターフェース)と同一です。 - composite
-
キーフレーム固有の合成操作。このキーフレームで指定した値を基底値と合成します。
この型はWebIDLで表現できないため、処理は後述のプローズで定義されています。
各メソッドでkeyframes
引数を受け取る場合、keyframes引数の処理手順を入力に実行し、その結果を保持します。
まず2つの補助的定義を示します。
completion recordの確認(result)は、resultがECMAScript操作のcompletion recordである場合、以下の手順と同等です:
-
resultがabrupt completionなら、resultの[[value]]フィールドに含まれる例外をthrowしてこの手順を中止します。
-
resultをresultの[[value]]フィールドの値で置き換えます。
キーフレーム類似オブジェクトの処理手順は、2つの引数を取ります:
-
ECMAScriptオブジェクトkeyframe input
-
boolean値allow lists
そして、以下の手順でallow listsがfalseならプロパティ名→DOMString値のマップ、trueならプロパティ名→DOMString値列のマップを返します:
-
keyframe inputをECMAScript値から辞書型への変換手順([WEBIDL])に渡して実行します。辞書型はallow listsの値で次のように決まります:
- trueのとき
-
以下の辞書型:
dictionary
{ (BasePropertyIndexedKeyframe double ?or sequence <double ?>)
= []; (offset DOMString or sequence <DOMString >)
= []; (easing CompositeOperationOrAuto or sequence <CompositeOperationOrAuto >)
= []; };composite - falseのとき
-
以下の辞書型:
dictionary
{BaseKeyframe double ?
=offset null ;DOMString
= "linear";easing CompositeOperationOrAuto
= "auto"; };composite
この手順の結果をkeyframe outputとして保持します。
-
animatable propertiesリストを以下の手順で作成します:
-
animatable propertiesを、実装でアニメーション可能なプロパティ名(ロングハンドを持つショートハンドも含む)リストとする。
-
animatable properties内の各プロパティ名をアニメーションプロパティ名からIDL属性名への変換アルゴリズムでIDL属性名に変換する。
-
-
input propertiesを、keyframe inputに対してEnumerableOwnNames操作で取得する。
-
animation properties新リストを作成し、input propertiesとanimatable properties両方に含まれるプロパティ、またはinput propertiesにあり
に従うものを含める。 -
animation propertiesをUnicodeコードポイント順で昇順ソートする。
-
animation properties内の各property nameについて:
-
raw valueを、keyframe inputに対して[[Get]]で取得する。
-
raw valueのcompletion recordの確認を行う。
-
raw valueをDOMStringまたはDOMString列property valuesへ変換:
- allow listsがtrueの場合
-
property valuesをraw valueからIDL型
(DOMString or sequence<DOMString>)
にECMAScript値からIDL値への変換手順([WEBIDL])で変換する。単一DOMStringの場合、値1件のDOMString列に置き換える。
- それ以外
-
property valuesをraw valueからDOMStringにECMAScript値からDOMStringへの変換手順([WEBIDL])で変換する。
-
normalized property nameを、property nameにIDL属性名からアニメーションプロパティ名への変換アルゴリズム適用結果とする。
-
keyframe outputにnormalized property nameのプロパティでproperty valuesを値として追加する。
-
-
keyframe outputを返す。
keyframes引数の処理手順は、nullableなECMAScriptオブジェクトobjectを入力に、以下でキーフレーム列を返します:
-
objectがnullなら、空のキーフレーム列を返す。
-
processed keyframesを空のキーフレーム列とする。
-
methodをGetMethod(object, @@iterator)で取得する。
-
methodのcompletion recordの確認を行う。
-
以下の最初に一致する条件に対応する手順を実行する:
- methodがundefinedでない場合
-
-
iterをGetIterator(object, method)で取得。
-
iterのcompletion recordの確認を行う。
-
繰り返し:
-
nextをIteratorStep(iter)で取得。
-
nextのcompletion recordの確認を行う。
-
nextがfalseならこのループを中止する。
-
nextItemをIteratorValue(next)で取得。
-
nextItemのcompletion recordの確認を行う。
-
Type(nextItem)がUndefined, Null, Object以外なら、TypeErrorをthrowして以降を中止する。
-
キーフレーム類似オブジェクトの処理手順をnextItemに対しallow lists = falseで実行し、その結果をprocessed keyframesに追加する。
-
-
- それ以外
-
-
property-indexed keyframeをキーフレーム類似オブジェクトの処理手順でobjectにallow lists = trueで実行した結果とする。
-
property-indexed keyframeの各メンバーmについて:
-
キーをproperty nameとする。
-
property nameが"composite"、"easing"、"offset"ならこのループの残りをスキップし次へ。
-
値をproperty valuesとする。
-
property keyframesを空のキーフレーム列とする。
-
property values内の各値vについて:
-
kをキーフレームで、キーフレームオフセットがnullなものとして新規作成。
-
property name→vのプロパティ値ペアをkに追加。
-
kをproperty keyframesに追加。
-
-
欠損キーフレームオフセットの算出手順をproperty keyframesに適用。
-
property keyframes内のキーフレームをprocessed keyframesに追加。
-
-
processed keyframesを各キーフレームの算出キーフレームオフセットで昇順ソート。
-
processed keyframesで隣接するキーフレームの算出キーフレームオフセットが等しい場合は統合。
-
offsetsを、property-indexed keyframeの"offset"メンバー型により次のように設定:
sequence<double?>
の場合-
"offset"そのもの。
double?
の場合-
長さ1のシーケンスで、値は"offset"のみ(«
offset
»)。
-
offsetsの各値を、processed keyframesで対応する位置のキーフレームオフセットに割り当てる。どちらかの末尾まで。
-
easingsを、property-indexed keyframeの"easing"メンバー型により次のように設定:
sequence<DOMString>
の場合-
"easing"そのもの。
DOMString
の場合-
長さ1のシーケンスで、値は"easing"のみ(« "easing" »)。
-
easingsが空なら、長さ1で値"linear"(« "linear" »)にする。
-
easingsがprocessed keyframesより少なければ、先頭から繰り返して同数にする。
-
easingsがprocessed keyframesより多ければ、余剰分をunused easingsとして保持。
-
easingsの各値を、対応する位置のキーフレームの"easing"プロパティに割り当てる。
-
property-indexed keyframeの"composite"メンバーが空でない場合:
-
composite modesを"composite"メンバーから
CompositeOperationOrAuto
値のシーケンスとして作成。単一値なら長さ1でその値のみ。 -
composite modesがprocessed keyframesより少なければ、先頭から繰り返して同数にする。
-
auto
以外の値を、対応する位置のキーフレーム固有の合成操作に割り当てる。
-
-
-
processed keyframesがオフセットでゆるくソートされていなければ、TypeErrorをthrowして以降を中止する。
-
processed keyframes内でキーフレームのキーフレームオフセットが非nullかつ0未満または1超過があれば、TypeErrorをthrowして以降を中止する。
-
processed keyframes内の各frameについて:
-
各プロパティ値ペアについて、プロパティで定められた構文で値をパースする。
構文的に無効ならペアを破棄。診断機能を持つユーザーエージェントは適切な警告を出すことが推奨される。
-
frameのタイミング関数を、frameの"easing"プロパティをCSS構文(
easing
メンバー、EffectTiming
辞書で定義)でパースした結果とする。パース失敗ならTypeErrorをthrowしてこの手順を中止する。
注: 上記2手順でCSSパーサーを使うため、CSSコメントやエスケープは許容されるが、パース成功時は値に保持されない。
注: "easing"プロパティのパース失敗時は、objectから全プロパティを読み終えた後に必ずTypeErrorをthrowすること。そうしないと挙動がobservableになり、将来WebIDLで部分的にオープンな辞書型がサポートされた場合と一致しなくなる。
-
-
unused easings内の各値を、
easing
メンバー(EffectTiming
インターフェース)で定義されたCSS構文でパースし、失敗したらTypeErrorをthrowしてこの手順を中止する。この最終ステップは、次のすべてのケースで一貫した挙動(TypeErrorがthrowされる)を保証するために必要です:
elem
. animate({ easing: 'invalid' }); elem. animate({ easing: [ 'invalid' ] }); elem. animate([{ easing: 'invalid' }]);
6.6.4. KeyframeEffectOptions
辞書
KeyframeEffect(target, keyframes,
options)
コンストラクタに追加パラメータとして KeyframeEffectOptions
オブジェクトを渡すことができます。
dictionary :
KeyframeEffectOptions EffectTiming {CompositeOperation composite = "replace";CSSOMString ?pseudoElement =null ; };
composite
, 型 CompositeOperation、デフォルト値"replace"
-
このアニメーションを効果スタックと合成する際に使用する合成操作。CompositeOperation列挙型値で指定されます。
auto
のキーフレーム固有の合成操作を指定した全てのキーフレームに適用されます。 pseudoElement
, 型 CSSOMString、null許容、デフォルト値null
6.7.
CompositeOperation
およびCompositeOperationOrAuto
列挙型
キーフレーム効果の合成動作の値はCompositeOperation列挙型で表されます。
enum {
CompositeOperation "replace" ,"add" ,"accumulate" };
replace
add
accumulate
-
accumulate合成操作に対応し、アニメーション効果は累積で基底値と合成されます。
キーフレームの合成動作で使える値はCompositeOperation
列挙型値に加え、auto
が追加されます。
enum {
CompositeOperationOrAuto "replace" ,"add" ,"accumulate" ,"auto" };
6.8.
Animatable
インターフェースミックスイン
KeyframeEffect
オブジェクトのターゲットとなる可能性があるオブジェクトは、
Animatable
インターフェースミックスインを実装します。
interface mixin {
Animatable Animation animate (object ?keyframes ,optional (unrestricted double or KeyframeAnimationOptions )options = {});sequence <Animation >getAnimations (optional GetAnimationsOptions options = {}); };dictionary :
KeyframeAnimationOptions KeyframeEffectOptions {DOMString id = "";AnimationTimeline ?timeline ; };dictionary {
GetAnimationsOptions boolean subtree =false ; };
Animation animate(keyframes, options)
-
以下の手順を実行します:
-
targetをこのメソッドが呼び出されたオブジェクトとする。
-
targetの関連Realmで、新しい
KeyframeEffect
オブジェクトeffectを、KeyframeEffect(target, keyframes, options)
コンストラクタと同じ手順で、targetをtarget引数、keyframesとoptionsを渡して構築する。この手順で例外が発生した場合は、その例外を伝播させてこの手順を中止する。
-
optionsが
KeyframeAnimationOptions
オブジェクトの場合、timelineはoptionsのtimeline
メンバーか、なければこのメソッドを呼び出した要素のデフォルトドキュメントタイムライン(ノードドキュメント)とする。 -
targetの関連Realmで、新しい
Animation
オブジェクトanimationを、Animation()
コンストラクタと同じ手順でeffectとtimelineを渡して構築する。 -
optionsが
KeyframeAnimationOptions
オブジェクトの場合、optionsのid
メンバーの値をanimationのid
属性に代入する。 -
animationに対してauto-rewindフラグtrueでアニメーションの再生手順を実行する。
-
animationを返す。
この節は非規範的です下記のコード断片:
var animation= elem. animate({ opacity: 0 }, 2000 ); は概ね下記と等価です:
var effect= new KeyframeEffect( elem, { opacity: 0 }, 2000 ); var animation= new Animation( effect, elem. ownerDocument. timeline); animation. play(); keyframes
-
使用するキーフレーム。 この値は
KeyframeEffect(target, keyframes, options)
コンストラクタのkeyframes引数に渡され、その解釈はそのコンストラクタの定義通りです。 options
-
作成される
KeyframeEffect
およびAnimation
のタイミング・アニメーションオプションです。
-
sequence<Animation> getAnimations(options)
-
このオブジェクトの関連アニメーションの集合を返します。また、
options
パラメータが渡され、subtree
がtrueに設定されている場合は、 このオブジェクトに対するサブツリーの関連アニメーションの集合を返します。返却リストは、§ 5.4.2 効果スタックで説明される合成順に、効果に関連付けられたアニメーションでソートされます。
このメソッド呼び出しはスタイル変更イベントをターゲット要素に発火します。 そのため、返却リストはアニメーション関連のスタイルプロパティの未処理変更など、保留中のスタイル変更適用後の状態を反映します。
options
-
getAnimations()
で返されるアニメーション集合を制御するパラメータ。
6.9.
Document
インターフェースへの拡張
以下の拡張は、Documentインターフェース([DOM]で定義)に追加されます。
partial interface Document {readonly attribute DocumentTimeline timeline ; };
timeline
, 型 DocumentTimeline、読み取り専用-
DocumentTimelineオブジェクト。デフォルトドキュメントタイムラインを表します。
6.10. DocumentOrShadowRoot
インターフェースミックスインへの拡張
以下の拡張は、DocumentOrShadowRootインターフェースミックスイン([DOM]で定義)に追加されます。
partial interface mixin DocumentOrShadowRoot {sequence <Animation >getAnimations (); };
sequence<Animation> getAnimations()
-
このメソッドを呼び出したドキュメントまたはシャドウルートに対するサブツリーの関連アニメーション集合を返します。
返却リストは、§ 5.4.2 効果スタックで説明される合成順に、効果に関連付けられたアニメーションでソートされます。
このメソッド呼び出しはドキュメントに対しスタイル変更イベントを発火します。 そのため、返却リストはアニメーション関連スタイルプロパティの未処理変更など、保留中のスタイル変更適用後の状態を反映します。
6.11.
Element
インターフェースへの拡張
DOM要素はアニメーションのターゲットとなる可能性があるため、Elementインターフェース([DOM])は次のように拡張されます:
Element includes Animatable ;
これにより、次のような使い方が可能になります。
6.12. AnimationPlaybackEvent
インターフェース
アニメーション再生イベントは、AnimationPlaybackEvent
インターフェースで表現されます。
[Exposed =Window ]interface :
AnimationPlaybackEvent Event {constructor (DOMString ,
type optional AnimationPlaybackEventInit = {});
eventInitDict readonly attribute double ?currentTime ;readonly attribute double ?timelineTime ; };dictionary :
AnimationPlaybackEventInit EventInit {double ?currentTime =null ;double ?timelineTime =null ; };
AnimationPlaybackEvent(type, eventInitDict)
-
AnimationPlaybackEventオブジェクトを、イベントの構築現行標準で定義された手順に従い構築します([DOM])。
currentTime
, 型 double、null許容、デフォルト値null
-
currentTime属性の説明を参照。
timelineTime
, 型 double、null許容、デフォルト値null
-
timelineTime属性の説明を参照。
6.13. モデルのライブネス
モデルのいずれかの部分に変更が加えられると、タイミングモデル全体が更新され、それに依存するスタイルも更新されます。
特に記載がない限り、 この現行標準のプログラミングインターフェース節で定義されたインターフェースの メソッド・コンストラクタの呼び出しや、 メンバーの取得・設定を行っても、 スタイル変更イベントは発生しません。
注: この現行標準を拡張する他の現行標準は、スタイル変更イベントの要件を、イベントが発生するような状況を導入して精緻化することが期待されます。 例えば、 この現行標準のインターフェースがCSSマークアップで定義された アニメーションを表す場合、 多くのメソッドが指定されたスタイルへの変更を反映するために スタイル変更イベントを発生させる必要があります。
上記要件および現行標準の他の規範的要件に基づき、以下の不変条件が観察できます:
- Web Animationsモデルに加えた変更は即座に反映される
-
例えば、
KeyframeEffect
が関連付けられたAnimation
をプログラミングインターフェース経由でシーク(§ 4.4.4 アニメーションの現在時刻の設定参照)した場合、 アニメーションのstartTime
を取得するとモデルの更新状態が即座に反映されます。 - アニメーションで影響を受けるプロパティの算出スタイルを取得すると、最新のアニメーション状態が返る
-
例えば、要素の使用スタイルを 新しい
Animation
を適用後すぐに取得した場合、 新しいアニメーションの結果も値に反映されます。 - 同じタスク内の変更は同期され、変更セット全体がまとめて描画される
-
モデルへの変更が即座に反映されることと、ECMAScriptのrun-to-completionセマンティクスが組み合わさって、 例えばスタイルの変更だけが単独で描画され、アニメーションが適用されないような状況は決して起こらないはずです。
// Element.animate 非対応ブラウザのためのフェードアウトのフォールバック // elem. style. opacity= '0' ; elem. animate([ { opacity: 1 }, { opacity: 0 } ], 500 ); 注: ただし上記例では、ユーザーエージェントによっては上記変更が全く反映されていないフレームを描画する場合があります。 これは例えば、描画が別プロセスで行われ、上記タスク完了直後にスケジュールされていて、変更がプロセスに伝達される前にレンダリングされる場合に起こり得ます。
currentTime
属性で取得されるドキュメントタイムラインの値は、タスク内で変化しない-
タイムラインが、アニメーション更新とイベント送信手順の実行ごとに 現在時刻を更新する要件があるため、 同じスクリプトブロック内で長いコードを実行する間に
currentTime
を2回取得しても、 下記例のように同じ値が返ります。 requestAnimationFrame
コールバックに渡される時刻はdocument.timeline.currentTime
と等しい-
HTMLのイベントループ処理モデルで、 アニメーション更新とイベント送信手順が アニメーションフレームコールバックの実行前に 実行されること、そしてそのコールバックに渡される時刻は両手順とも同じnowタイムスタンプが使われることから、 デフォルトドキュメントタイムラインの 現在時刻は
requestAnimationFrame
に渡される時刻と一致するはずです。 - このプログラミングインターフェースのメソッド呼び出しは通常トランジションを発生させない
-
次の例を考えます:
// トランジション開始点のセットアップ div. style. opacity= '1' ; getComputedStyle( div). opacity; // トランジション終了点のセットアップ div. style. transition= 'opacity 1s' ; div. style. opacity= '0' ; // アニメーションを発火 div. animate({ opacity: [ 0.5 , 1 ] }, 500 ); // トランジション終了待ち -- 下記は決して呼ばれない! div. addEventListener( 'transitionend' , () => { console. log( 'transitionend' ); }); この場合、
animate()
を呼び出してもスタイル変更イベントは発生しません。 その結果、保留中のスタイル変更は新しいアニメーションによるスタイル変更と同時に処理されます。 アニメーションスタイルが 変更前スタイルや変更後スタイルを上書きするため、 トランジションは生成されず、 transitionendイベントのイベントハンドラは決して呼ばれません。
7. メディアフラグメントとの統合
Media Fragments現行標準[MEDIA-FRAGS]は、メディアリソースの時間的範囲を指定する手段を定義しています。 メディアフラグメントの適用は、指定されたリソースのMIMEタイプに依存します。 SVG MIMEタイプのリソース[SVG11]では、時間パラメータの適用は Animation Elements現行標準で定義されています。
注: メディアフラグメントはリソースのMIMEタイプに基づいて動作するよう定義されています。 そのため、Web Animationsコンテンツが使用されるすべての場面で時間的指定がサポートされるとは限りません。
8. ページ表示との連携
HTMLはユーザーエージェントがユーザーエージェント定義の状態を セッション履歴エントリと共に保存できることを許可しており、ユーザーがページ間を移動する際に ページの以前の状態(スクロール位置など[HTML])を復元できます。
参照ドキュメントがアンロード・遷移された際にメディア要素を一時停止・再開するユーザーエージェントは、 Web Animationsコンテンツを含むドキュメントにも一貫した扱いを適用することが推奨されます。 もし提供される場合、この動作は、壁時計時間を追跡するタイムラインすべての時刻値を調整することで達成すべきです。
これは、
時刻値が navigationStart
基準で、
requestAnimationFrame
が document.timeline.currentTime
と同じ時刻を使うことと矛盾しないか? [Issue
#2083]
9. 実装要件
9.1. 時刻値の精度
時刻値の内部表現は実装依存ですが、ユーザーエージェントは入力時刻値をマイクロ秒精度で表現できることが推奨されます。これにより、ミリ秒を名目上表す時刻値0.001と0.0を区別できるようになります。
9.2. 適合性基準
この現行標準はアニメーションの抽象モデルを定義しているため、スクリプティング非対応のユーザーエージェントには、テスト可能な表面がないため適合性基準はありません。
ただし、スクリプティング非対応のユーザーエージェントがこの現行標準に基づく追加技術を実装する場合は、本現行標準で定義された内容が追加技術の適合性基準の一部となります。
適合するスクリプト対応Web Animationsユーザーエージェントとは、§ 6 プログラミングインターフェースで定義されたAPIを実装するユーザーエージェントです。
10. 謝辞
Steve Block、Michael Giuffrida、Ryan Seys、Eric Willigersの本現行標準への貢献に感謝します。
また、提案されたスムーズタイミング関数の数式について助言をいただいたMichiel "Pomax" Kamermansにも感謝します(この機能は後続の現行標準に延期されています)。
放送用アニメーション制作のプロセスと技術を編集者に親切に紹介してくださり、寛大なご協力とご辛抱をいただいたSouthern Star Animationの皆様に深く感謝いたします。
11. 前回公開以降の変更点
以下は2022年9月8日ワーキングドラフト以降の変更点です:
-
再生速度の設定手順を更新し、非単調タイムラインで再生速度が反転した場合に開始時刻を維持し、開始時刻位置を入れ替えるようにしました。
-
関連アニメーションの定義を他仕様で再利用できるように分離しました。
-
現在のアニメーション効果の定義を更新し、非アイドル状態かつ非増加タイムラインに関連付けられていれば現在とみなすようにしました。
-
§ 4.6 塗りの挙動セクションのコード例を修正しました。
changelogで詳細履歴を確認できます。
付録A:既存プロパティのアニメーション型
通常、プロパティのアニメーション型は定義とともに記載されています。 しかし、古い仕様や成熟度の高い仕様で定義されたプロパティには アニメーション型情報が記載されていない場合があります。 そのようなプロパティは、以下の例外を除き、すべて算出値によるアニメーション型とみなします。
font-weightのアニメーション
font-weightプロパティ値(レベル4以前)は次のように合成されます:
-
補間は100単位の離散ステップで行われます。 補間は実数空間で、<number>同様に行われ、最も近い100の倍数に丸められます。 100の倍数のちょうど中間の場合は正の無限大方向に丸めます。
-
加算は、font-weight値について Vresult = Va + Vb
注: この定義は[CSS-FONTS-4]で廃止されており、font-weight値が100の倍数である必要はなくなりました。 その場合、アニメーション型は単に算出値によるとなります。
visibilityのアニメーション
visibilityプロパティについて、visibleは離散的なステップで補間されます。 0~1の間のpの値はvisibleにマップされ、その他の値はより近い端点にマップされます。 どちらの値もvisibleでない場合は離散アニメーションとなります。
box-shadowおよびtext-shadowのアニメーション
box-shadowやtext-shadowプロパティのアニメーションは、合成の手順に従い、影リストの合成として以下のように処理されます:
リスト内の各シャドウ(noneは長さ0のリストとして扱う)は、算出値によるの挙動で各成分ごとに補間されます。 ただし、両方の入力シャドウがinsetか両方ともinsetでない場合は、補間後のシャドウもその属性を一致させなければなりません。 入力シャドウのペアのいずれかが一方のみinsetの場合は、影リスト全体が離散アニメーションとなります。 シャドウリストの長さが異なる場合は、短い方のリストの末尾に 色がtransparent、全長が0、inset属性(または非inset)が長い方に合わせられたシャドウをパディングします。
2つの影リスト Vaと Vbの加算は、リストの連結として定義され、Vresultは Vaを拡張したものにVbを追加したものになります。
2つの影リストの累積は上記補間ルールに従い、各成分ごとに型に応じて加算を行うか、inset属性が一致しない場合は離散アニメーションにフォールバックします。