エクスプレッション言語



JavaScript 1.2 に基づく After Effects エクスプレッション言語には、一連の組み込みオブジェクトの拡張セットが追加されています。After Effects では、コアとなる標準 JavaScript 1.2 言語を使用しており、Web ブラウザ専用の拡張は使用していません。After Effects には、レイヤー、コンポジション、フッテージ、カメラなどの独自の拡張オブジェクトセットが組み込まれており、After Effects のプロジェクトのほとんどの値を取得できます。

エクスプレッション言語はスクリプト言語を基にしていますが、スクリプトとエクスプレッションには若干の違いがあります。その違いとは、スクリプトがアプリケーションに指示を伝えるのに対し、エクスプレッションはプロパティの設定内容を表す点です。

JavaScript についての詳細は、JavaScript のリファレンスマニュアルを参照してください。

エクスプレッションを作成する場合は、以下の点に注意してください。

  • エクスプレッションの値は、最後に評価されたステートメントの値です。

  • JavaScript は大文字と小文字を区別する言語です。

  • ステートメントや行の区切りにはセミコロンが必要です。

  • 単語間の空白文字は無視されます(文字列に含まれる空白文字を除く)。

JavaScript では、オブジェクトに格納されている値をプロパティと呼んでいますが、After Effects ではタイムラインパネルで定義されているレイヤーコンポーネントを「プロパティ」と呼んでいます。このため、After Effects では JavaScript プロパティを「メソッド」または「属性」と呼んでいます。一般に、「メソッド」と「属性」の違いは、メソッドは通常、出力値(戻り値)を作成するのに対し、属性は出力値(戻り値)を特定するのに既存の値を参照することです。メソッドにはメソッド名の後にかっこで囲まれているメソッドの入力引数があるので、メソッドと属性は簡単に区別できます。

オブジェクト」は、別のオブジェクト、属性、およびメソッドを含めることのできるアイテムです。コンポジション、レイヤーおよびフッテージアイテムは、オブジェクトの一例です。コンポジション、レイヤーおよびフッテージアイテムは「グローバルオブジェクト」で、上位レベルのオブジェクトを参照せずにコンテキストで参照できます。

属性とメソッドへのアクセス

レイヤープロパティの属性やメソッドにアクセスするには、エクスプレッション言語を使用します。値にアクセスするには、一連のオブジェクト参照をピリオド(.)演算子で区切って指定します。エフェクトプロパティ、マスクまたはテキストアニメータを参照する場合など、他のレベルのレイヤーのオブジェクトを参照するように指定するには、かっこ( )を使用します。例えば、Layer A の「不透明度」プロパティを Layer B のブラー(ガウス)エフェクトにリンクするには、Layer A の「不透明度」プロパティのエクスプレッションフィールドに次のエクスプレッションを入力します。

  thisComp.layer("Layer B").effect("Gaussian Blur")("Blurriness")

このエクスプレッションは、左から右に向かって上位レベルから特定のプロパティへのオブジェクトを表しています。

  • 使用しているグローバルオブジェクトは、現在のコンポジション thisComp を参照しています。

  • コンポジション内の特定のレイヤーオブジェクトは、「layer("Layer B")」という名前で参照されます。

  • レイヤー内の特定のエフェクトオブジェクトは、「effect("Gaussian Blur")」という名前で参照されます。

  • エフェクト内の特定のエフェクトプロパティは、「("Blurriness")」という名前で参照されます。

多次元プロパティの n 番目のコンポーネントは、エフェクトコントロールポイントの y コンポーネントのように、次のように末尾に [n] を付加します。

  thisComp.layer("Layer B").effect("Advanced Lightning")("Origin")[1]

エクスプレッションの初期設定オブジェクトは、エクスプレッションを記述するプロパティで、その後ろにエクスプレッションを含むレイヤーが続きます。したがって、プロパティを指定する必要はありません。例えば、レイヤーの「位置」プロパティについて記述したウィグルのエクスプレッションは次のいずれかになります。

  wiggle(5, 10) 
  position.wiggle(5, 10)

エクスプレッションを作成するレイヤーとプロパティの外からレイヤーとプロパティを取得する場合は、レイヤーとプロパティを指定する必要があります。例えば、Layer B の「不透明度」プロパティを Layer A の「回転」プロパティにリンクするエクスプレッションは次のようになります。

  thisComp.layer("Layer A").rotation
同様の例を見るには、ピックウイップを使ってレイヤープロパティを別のレイヤープロパティとリンクし、それによって生成されるエクスプレッションを参照してください。

Jeff Almasol が、redefinery の Web サイトで、エクスプレッション内で任意のプロパティを参照する方法を指定できるスクリプトを公開しています。

配列と多次元プロパティ

配列は、配列とは順序付けられた一連の数値を格納できる種類のオブジェクトです。配列は、次の例のように、コンマで区切られ、かっこで囲まれた数字のリストとして表されます。

  [10, 23]

変数に配列オブジェクトを割り当てれば、配列値を容易に参照することができます。例えば、次のようになります。

  myArray = [10, 23]

配列オブジェクトの次元は、配列内の要素の数のことです。myArray は 2 次元です。After Effects のプロパティの次元は、保持している引数の数に応じて異なります。エクスプレッション言語では、プロパティの値は単一の値(数値オブジェクト)または配列(配列オブジェクト)のいずれかです。

次の表に、プロパティとその次元の例を示します。

次元

プロパティ

1

回転 °

不透明度%

2

スケール [X=幅, Y=高さ]

位置 [X, Y]

アンカーポイント [X, Y]

オーディオレベル [左, 右]

3

スケール [幅, 高さ, 深度]

3D 位置 [X, Y, Z]

3D アンカーポイント [X, Y, Z]

方向 [x, y, z]

4

カラー [赤, 緑, 青, アルファ]

配列オブジェクトの個々の要素にアクセスするには、目的の要素を示すインデックス番号とかっこを使用します。配列オブジェクトの要素には 0 から始まるインデックスが割り当てられます。前述の例では、myArray[0]10 で、myArray[1]23 です。

以下の 2 つのエクスプレッションは等価です。

  [myArray[0], 5] 
  [10, 5]

「位置」プロパティ配列のインデックスは次のとおりです。

  • position[0] は位置の X 座標です。

  • position[1] は位置の Y 座標です。

  • position[2] は位置の Z 座標です。

カラーは、4 次元の配列 [, , , アルファ] で表されます。8 bpc または 16 bpc の色深度のプロジェクトでは、カラー配列の各値が 0(黒)~ 1(白)になります。例えば、の場合は 0(色なし)~ 1(赤)です。したがって、[0,0,0,0] は黒で透明、[1,1,1,1] は白で完全に不透明です。色深度が 32 bpc のプロジェクトでは、0 未満や 1 を越える値を指定することもできます。

配列オブジェクト内で、次元のコンポーネントの最高値より大きなインデックスを使用すると、エラーになります。例えば、myArray[2] ではエラーが発生しますが、position[2] では、位置の Z 座標が返されます。

After Effects エクスプレッション言語に含まれる多くのプロパティやメソッドでは、配列オブジェクトを引数として取ったり、戻り値として返したりします。例えば、thisLayer.position は、レイヤーが 2D か 3D かに応じて、2 次元または 3 次元の配列になります。

位置のアニメーションの Y の値を維持しながら X の値を 9 に固定するエクスプレッションは、次のようになります。

  y = position[1]; 
  [9,y]

さらに簡潔に記述すると次のようになります。

  [9, position[1]]

これは重要なポイントなので、もう 1 つ例を見てみます。Layer A から取得した X 位置と Layer B から取得した Y 位置を組み合わせる場合は、次のように記述できます。

  x = thisComp.layer("Layer A").position[0];  
  y = thisComp.layer("Layer B").position[1];  
  [x,y]

2D プロパティまたは 3D プロパティの配列の値を 1 つだけ参照するエクスプレッションを作成することができます。初期設定では、特に指定がない限り、最初の値が使われます。例えば、Layer A の「スケール」プロパティから Layer B の「スケール」プロパティにピックウィップをドラッグすると、次のエクスプレッションが表示されます。

  thisComp.layer("Layer B").scale[0]

この場合、初期設定では、「スケール」プロパティの最初の値である幅の値が使用されます。幅の代わりに高さを使用する場合は、プロパティ名ではなく 2 番目の値に直接ピックウイップをドラッグするか、エクスプレッションを次のように変更します。

  thisComp.layer("Layer B").scale[1]

また、Layer B の「スケール」プロパティから Layer A の「回転」プロパティにピックウイップをドラッグすると、自動的に変数が作成されて 「回転」プロパティの 1 次元の値が割り当てられ、その変数が「スケール」プロパティの両方の次元に使用されます。

  temp = thisComp.layer(1).transform.rotation; 
  [temp, temp]

ベクトル

After Effects では、多くのプロパティおよびメソッドがベクトルを返します。配列が空間におけるポイントまたは方向を表す場合、After Effects ではそれを「ベクトル」と呼びます。例えば、position はベクトルを返す、というように表現します。

ただし、audioLevels のような関数は 2 次元の値(左と右のチャンネルのレベル)を返しますが、これはポイントや方向を表しているわけではないので、「ベクトルを返す」とは言いません。After Effects の関数の中にはベクトル引数を取るものがありますが、このような関数が便利なのは渡される値が方向を表している場合のみです。例えば、cross(vec1, vec2) では、入力ベクトルに対して垂直な第 3 のベクトルを計算します。これは、vec1vec が空間内の方向を表している場合は便利ですが、2 組の任意の数値の組み合わせを表している場合は特に意味がありません。

インデックスとラベル

After Effects のレイヤー、エフェクト、マスク要素のインデックスは、1 から始まります。例えば、タイムラインパネルの最初のレイヤーは layer(1) です。

特に理由がない限り、レイヤー、エフェクト、マスクのラベルには番号ではなく、名前を使用してください。番号を使用すると、これらのオブジェクトを移動した場合や、After Effects のアップデートまたはアップグレード時に引数が変更された場合に区別しずらくなり、エラーの原因となりかねません。名前を使用する場合は、必ず半角の二重引用符("")で囲みます。例えば、次に示す最初のエクスプレッションの方が 2 番目のエクスプレッションよりわかりやすく、また最初のエクスプレッションはエフェクトの順序を変更しても機能します。

  effect("Colorama").param("Get Phase From")  
  effect(1).param(2)

エクスプレッション時間

エクスプレッション内の時間は、レイヤー時間ではなく、秒単位のコンポジション時間です。エクスプレッションの初期設定の時間は、エクスプレッションが評価されるコンポジションの現在の時間です。次のエクスプレッションでは、両方ともコンポジションの初期設定の時間が使用され、同じ値が返されます。

  thisComp.layer(1).position 
  thisComp.layer(1).position.valueAtTime(time)

相対時間を使用するには、time 引数に相対値を追加します。例えば、現在の時間の 5 秒前の位置の値を取得するには、次のエクスプレッションを使用します。

  thisComp.layer(1).position.valueAtTime(time-5)

ネスト化されたコンポジションに含まれるプロパティが参照する初期設定の時間は、リマップされた時間ではなく、コンポジションの元の初期設定の時間です。ただし、プロパティの取得に source 関数を使用する場合は、リマップされた時間が使用されます。

例えば、包含コンポジション内のレイヤーのソースがネスト化されたコンポジションで、包含コンポジション内でタイムリマップされているとします。この場合、次のエクスプレッションで、ネスト化されたコンポジション内にあるレイヤーの位置の値を取得すると、コンポジションの初期設定時間の位置の値が返されます。

  comp("nested composition").layer(1).position

次のように、ネスト化されたコンポジションレイヤー 1 の source にアクセスすると、タイムリマップされた後の位置の値が返されます。

  thisComp.layer("nested composition").source.layer(1).position
注意: エクスプレッションで特定の時間を指定すると、タイムリマップされた時間は無視されます。

エクスプレッションはフレーム単位ではなく、秒単位で時間どおりに動作するため、フレームで動作するよう Time Conversion のメソッドを使用して時間値の変換が必要になる場合があります(Time Conversion のメソッドを参照)。