スネークケースのプロパティ
- After Effects ユーザガイド
- ベータ版のリリース
- はじめに
- Workspaces
- プロジェクトとコンポジション
- フッテージの読み込み
- テキストとグラフィック
- テキスト
- モーショングラフィック
- 描画、ペイント、パス
- レイヤー、マーカー、カメラ
- アニメーション、キーフレーム、モーショントラッキング、キーイング
- アニメーション
- キーフレーム
- モーショントラッキング
- キーイング
- 透明度と合成
- カラーの調整
- エフェクトおよびアニメーションプリセット
- エクスプレッションと自動化
- イマーシブビデオ、VR、3D
- After Effects での VR 環境の作成
- イマーシブビデオエフェクトの適用
- VR/360 度ビデオの合成ツール
- 高度 3D レンダラー
- 3D モデルを読み込んでコンポジションに追加
- Creative Cloud ライブラリからの 3D モデルの読み込み
- 画像ベースの照明
- 3D モデルからのライトとカメラの抽出およびアニメーション化
- 3D カメラの移動のトラッキング
- シャドウを落とすおよび受ける
- 埋め込まれた 3D モデルアニメーション
- シャドウキャッチャー
- 3D 深度データ抽出
- 3D レイヤーのマテリアルプロパティの変更
- 3D デザインスペースでの作業
- 3D 変形ギズモ
- 3D アニメーションによるその他の操作
- Mercury 3D エンジンを使用した、3D デザインへのリアルタイムのプレビュー変更
- グラフィックへのレスポンシブデザインの追加
- ビューとプレビュー
- レンダリングと書き出し
- その他のアプリケーションの使用
- 共同作業:Frame.io と Team Projects
- メモリ、ストレージおよびパフォーマンス
- ナレッジベース
このドキュメントでは、After Effects 16.0 の JavaScript エクスプレッションエンジンと以前の ExtendScript エクスプレッションエンジンのエクスプレッション言語の構文の違いについて説明します。
JavaScript エクスプレッションエンジンのエクスプレッションの改善方法について学習したり、After Effects の以前のリリース用に記述したエクスプレッションが JavaScript エクスプレッションエンジンの評価で失敗した際に発生したエラーを修正する場合に、このドキュメントを参照してください。
After Effects のエクスプレッション言語は、JavaScript(ECMAScript の実装)に基づいています。After Effects 16.0 の JavaScript エクスプレッションエンジンは、ECMAScript 2018 に基づいています。以前の ExtendScript エクスプレッションエンジンは、ECMAScript 3(1999)に基づいています(Adobe ExtendScript は、After Effects およびその他の Adobe アプリケーションのスクリプトに使用される言語でもあります)。
後述の例や、JavaScript および以前の ExtendScript の両方のエクスプレッションエンジンで機能するエクスプレッションの作成方法のガイダンスに従うことができます。
JavaScript と以前の ExtendScript のエクスプレッションエンジンの構文の主な違いを次に示します。
- 最新の JavaScript 構文:ECMAScript 5 から ECMAScript 2018 の JavaScript に新しい構文およびメソッドが追加され、JavaScript エクスプレッションエンジンを使用する際にエクスプレッションで使用できます。また、JavaScript エクスプレッションエンジンを使用する際のエクスプレッション構文にいくつかの小さな改善が加えられています。主な違いを次に示します。
- 互換性のない以前の構文:一部の以前の構文は、JavaScript エクスプレッションエンジンと互換性がありません。これらの例外を、機能しない構文を JavaScript エンジンと互換性のあるものにするために必要な変更と共に、ここに記載します。主な違いを次に示します。
- if...else 構文の違い
- if および else を括弧なしで同じ行にできない
- エクスプレッションを関数宣言で終了できない
- this() 省略形構文は許可されず、代わりに thisLayer() が使用される
- ソーステキストプロパティの文字への配列インデックスアクセスには .value が必要
- スネークケースのプロパティおよびメソッドは許可されない
- eval() メソッドとバイナリエンコードされた(.jsxbin)エクスプレッションの使用
- $.(ドル)オブジェクトの制限付きサポート
- ...reflect.properties、...reflect.methods および toSource() のサポートなし
- .jsx エクスプレッションライブラリおよび eval() の構文要件:.jsx エクスプレッション関数ライブラリ内でエクスプレッションを使用する場合、または eval()、thisLayer. および thisProperty. 内からエクスプレッションが呼び出される場合、明示的にプレフィックスを付けて、配列の演算操作をベクトル演算に置き換える必要があります。主な違いを次に示します。
最新の JavaScript 構文:エクスプレッション言語に対しておこなわれた改善
エクスプレッションで ECMAScript 2018 の JavaScript 構文を使用できる
ECMAScript 3 以降、JavaScript 言語に多くの追加がおこなわれています。文字列、配列およびオブジェクトと共に使用する、よりコンパクトで読み取り可能な新しいメソッドがあります。また、変数や関数、デフォルトパラメーター、スプレッド演算子などを宣言するための新しい方法もあります。これらの変更は、JavaScript 言語に対する一般的なものなので、このドキュメントでは扱いません。多くの構文の追加に関する学習リソースへのリンクを次に示します。
- JavaScript ES5 ガイド(以前の ECMAScript 5)
- 新しい Array メソッド
- 新しい Object メソッド
- JSON.stringify() および JSON.parse()
JavaScript について学習するための、その他の詳細な推奨リソース:
ソーステキストから他のプロパティにリンクする場合に .value が不要に
ソーステキストプロパティから他のプロパティ値を参照する場合、以前の ExtendScript エンジンでは、.value をプロパティの末尾に追加する必要があります。JavaScript エンジンは、.propertyIndex や .name などの他の属性が明示的に使用されない限り、デフォルトでプロパティの値を表示します。
例えば、次のようになります。
thisComp.layer(“Solid 1”).transform.position // 以前のエンジンでは、ソーステキストプロパティに適用されると、“[object Property]” と評価されます。 // JavaScript エンジンでは、ソーステキストプロパティに適用されると、レイヤー「Solid 1」の Position プロパティの値に評価されます。
posterizeTime(0) のプロパティ値のフリーズ
After Effects 16.0 では、posterizeTime(0) は、コンポジションの時間 0 でプロパティ値をフリーズします。これは、JavaScript と以前の ExtendScript エンジンの両方に適用されます。
これは下位互換ではなく、16.0 より前のバージョンの After Effects で予期しない結果になる可能性があります。
互換性のない以前の構文
以前の ExtendScript エクスプレッションエンジンからのほとんどすべてのエクスプレッション構文は、JavaScript エクスプレッションエンジンと上位互換性があります。ただし、一部の以前の構文は、JavaScript エクスプレッションエンジンと互換性がありません。これは、最新の JavaScript での構文の変更による場合があります。他には、旧バージョンの構文や古い構文が削除された場合もあります。機能しない構文および機能する構文の例を次に示します。
これらの構文の違いのほとんどは、エクスプレッションを書き直すアプリケーションスクリプトで修正できます。
if...else 構文の違い
一般に、if...else ステートメントは、MDN ガイドラインに従って、常に改行および括弧と共に記述することをお勧めします。以前の ExtendScript エンジンは if...else ステートメントの厳密でない構文に対して耐性がありましたが、JavaScript エンジンは厳密です。正しくない if...else 構文は、JavaScript エンジンを使用した場合の評価に失敗します。
else を含まない if ステートメントで終わるエクスプレッションは許可されない
エクスプレッションが else ステートメントを含まない if ステートメントで終わる場合、JavaScript エンジンは、エラー「未定義の値がエクスプレッションで使用されています (配列の添え字が範囲外である可能性があります)」で、エクスプレッションの評価に失敗します。以前の ExtendScript エンジンでは、次のエクスプレッションは、time が 1 秒より大きい場合は 100 と評価され、その他の場合は 50 と評価されます。
var x = 50; if ( time > 1 ) { x = 100 } // ここでは “else” は記述されていませんが、暗黙的に示されています。
JavaScript エンジンでは、エクスプレッションの最後のステートメントの場合、ステートメントの else 部分が明示的に記述される必要があります。
var x = 50; if ( time > 1 ) { x = 100; } else { x; }
これは、JavaScript エンジンおよび以前の ExtendScript エンジンの両方で正しく評価されます。
if および else を括弧なしで同じ行にできない
単一の行の括弧のない if...else ステートメントは、以前の ExtendScript エンジンでは評価されますが、JavaScript エンジンでは、「構文エラー : 予期しないトークン else」または「未定義の値がエクスプレッションで使用されています (配列の添え字が範囲外である可能性があります)」というエラーで評価に失敗します。エラーは、コンテキストおよびプロパティタイプによって異なります。
以前の ExtendScript エンジンでは、次のエクスプレッションは、time が 1 秒より大きい場合は 100 と評価され、その他の場合は 50 と評価されます。
if ( time > 1 ) 100 else 50;
JavaScript エンジンでは、if...else ステートメントを評価するには、改行または括弧が必要です。単純な場合は、代わりに三項演算子が使用されることがあります。次の構文はいずれも JavaScript エンジンで使用できます。
// 解決策 A:“else” の前に改行を追加すると、どちらのエンジンでも正しく評価されるようになります。 if ( time > 1 ) 100 else 50; // 解決策 B:正しくブラケットを追加すると、どちらのエンジンでも正しく評価されるようになります。 if ( time > 1 ) { 100 } else { 50 }; // 解決策 C:if...else ステートメントの代わりに三項演算子を使用すると、どちらのエンジンでも正しく評価されます。 time > 1 ?100 : 50;
このすべてのソリューションは、JavaScript エンジンおよび以前の ExtendScript エンジンの両方で正しく評価されます。
エクスプレッションを関数宣言で終了できない
エクスプレッションが関数宣言で終了する場合、JavaScript エンジンは、エラー「タイプのオブジェクトが、Number、Array、または Property が必要な場所で見つかりました」で、エクスプレッションの評価に失敗します。JavaScript エンジンでは、評価された最後のアイテムは、宣言するのではなく、値を返す必要があります。
次の例は、以前のエンジンでは機能しますが、JavaScript エンジンでは機能しません。
timesTen( value ); // 関数が次のように宣言されている場合でも、以前のエンジンでこの行が評価されます。 function timesTen ( val ) { return val * 10 }
最後の行で(宣言の代わりに)関数が呼び出される場合、エクスプレッションは両方のエンジンで正しく評価されます。
function timesTen ( val ) { return val * 10 } timesTen( value ); // JavaScript エンジンでは、正しい値を返すために、宣言の下で関数を呼び出す必要があります。
this() 省略形構文は許可されず、代わりに thisLayer() が使用される
以前の ExtendScript エンジンでは、this は thisLayer の省略形として使用できました。JavaScript エンジンでは、これはグローバルオブジェクトを参照するので、代わりに thisLayer を使用する必要があります。JavaScript エンジンでこれを使用すると、通常、「これは関数ではありません」というエラーが表示されます。
次の以前の ExtendScript の例では、これを使用してソーステキストプロパティから Text Layer Position プロパティへのコンパクトリンクを作成します。
this(5)(2).value;
JavaScript エンジンでは、this は thisLayer に置き換える必要があります。
thisLayer(5)(2).value;
thisLayer の使用は、両方のエクスプレッションエンジンと互換性があります。
ソーステキストプロパティの文字への配列インデックスアクセスには .value が必要
以前の ExtendScript エクスプレッションエンジンでは、text プロパティの文字は、配列のような括弧表記でアクセスできました。
text.sourceText[0] //「ソーステキスト」プロパティのテキスト値の最初の文字を返します。
JavaScript エンジンでは、文字にアクセスするために .value を追加する必要があります。
text.sourceText.value[0] //「ソーステキスト」プロパティのテキスト値の最初の文字を返します。
この構文は、両方のエンジンと互換性があります。
スネークケースのプロパティおよびメソッドは許可されない
廃止されたスネークケースのプロパティおよびメソッド(キャメルケースの代わりにアンダースコアを使用して記述)は、JavaScript エンジンではサポートされません。両方のエンジンと互換性があるので、代わりにキャメルケースバージョンを使用する必要があります。次に、廃止されたスネークケースおよび対応するキャメルケースのリストを示します。
|
キャメルケースのプロパティ |
スネークケースのメソッド |
キャメルケースのメソッド |
---|---|---|---|
this_comp this_layer this_property color_depth has_parent in_point out_point start_time has_video has_audio audio_active anchor_point audio_levels time_remap casts_shadows light_transmission accepts_shadows accepts_lights frame_duration shutter_angle shutter_phase num_layers pixel_aspect point_of_interest depth_of_field focus_distance blur_level cone_angle cone_feather shadow_darkness shadow_diffusion active_camera |
thisComp thisLayer thisProperty colorDepth hasParent inPoint outPoint startTime hasVideo hasAudio audioActive anchorPoint audioLevels timeRemap castsShadows lightTransmission acceptsShadows acceptsLights frameDuration shutterAngle shutterPhase numLayers pixelAspect pointOfInterest depthOfField focusDistance blurLevel coneAngle coneFeather shadowDarkness shadowDiffusion activeCamera |
value_at_time() velocity_at_time() speed_at_time() nearest_key() posterize_time() look_at() seed_random() gauss_random() ease_in() ease_out() rgb_to_hsl() hsl_to_rgb() degrees_to_radians() radians_to_degrees() from_comp_to_surface() to_comp_vec() from_comp_vec() to_world_vec() from_world_vec() to_comp() from_comp() to_world() from_world() temporal_wiggle() loop_in_duration() loop_out_duration() loop_in() loop_out() |
valueAtTime() velocityAtTime() speedAtTime() nearestKey() posterizeTime() lookAt() seedRandom() gaussRandom() easeIn() easeOut() rgbToHsl() hslToRgb() degreesToRadians() radiansToDegrees() fromCompToSurface() toCompVec() fromCompVec() toWorldVec() fromWorldVec() toComp() fromComp() toWorld() fromWorld() temporalWiggle() loopInDuration() loopOutDuration() loopIn() loopOut() |
eval() メソッドとバイナリエンコードされた(.jsxbin)エクスプレッションの使用
ExtendScript バイナリ形式でエンコード(ExtendScript ToolKit CC からバイナリ .jsxbin ファイルで保存)されたエクスプレッションは、JavaScript エンジンではサポートされません。
エクスプレッションを難読化したい場合は、以前の ExtendScript エンジンを使用するか、ECMAScript 2018 と互換性のある別の難読化メソッドを使用します。一部の難読化メソッドは、両方のエクスプレッションエンジンと互換性がない可能性があります。
$.(ドル)オブジェクトの制限付きサポート
$.(ドル)オブジェクトメソッドおよびプロパティは、ExtendScript 専用で、JavaScript エンジンではほとんどサポートされません。次の表に、使用がサポートされない $.(ドル)オブジェクトとサポートされるオブジェクトを示します。
サポートされない $. |
サポートされる $. |
---|---|
$.fileName $.hiResTimes $.stack $.evalFile() $.list() $.setenv() $.getenv() $.appEncoding $.buildDate $.decimalPoint $.dictionary $.error $.flags $.includePath $.level $.line $.locale $.localize $.memCache $.os $.screens $.strict $.version |
$.build $.engineName(これは以前の ExtendScript エンジンではサポートされません) $.global |
...reflect.properties、...reflect.methods および toSource() のサポートなし
reflect.properties および reflect.methods は、JavaScript エンジンではサポートされません。JavaScript には同等のものがない、ExtendScript 専用のメソッドです。
JavaScript の toSource() は廃止され、標準化過程には含まれません。
前述のメソッドで提供されたものと同様の所定の After Effects プロパティについて、使用可能なプロパティおよびメソッドのリストを確認するには、次のソーステキストプロパティのエクスプレッションを使用して、目的のプロパティにリンクします(例えば、1 行目の thisProperty の代わりにピックウイップを使用します)。
let obj = thisProperty; // 「thisProperty」を目的のプロパティへのプロパティリンクに置き換えます。 let props = []; do { Object.getOwnPropertyNames(obj).forEach(prop => { if (props.indexOf(prop) === -1) { props.push(prop); } }); } while (obj = Object.getPrototypeOf(obj)); props.join(“\n”); // 使用可能なプロパティとメソッドの一覧を含んだ文字列の配列を返します。
このエクスプレッションは、以前の ExtendScript エンジンとは互換性がありません。ECMAScript 3 で使用できない構文およびメソッドを使用します。
JavaScript エンジンでの .jsx エクスプレッションライブラリおよび eval() の構文要件
.jsx エクスプレッション関数ライブラリ内でエクスプレッションを使用する場合、または eval() 内からエクスプレッションが呼び出される場合、特定の構文を修正する必要があります。
明示的な thisLayer. または thisProperty. プレフィックスを、レイヤーまたはプロパティで明示的に呼び出されないネイティブのメソッドまたは属性に追加する必要があります。このプレフィックスは、呼び出しているメソッドまたは属性がどのオブジェクトのものかを JavaScript エンジンに指示します。
Position のような配列の値の演算操作は、配列の各アイテムに作用させるために、ベクトル演算を使用するか、ループ関数を使用して計算する必要があります。position + [100,100] のようなオーバーロードされた演算操作は、評価されません。
JavaScript エンジンを使用する場合、エクスプレッションは、一部の以前の ExtendScript エクスプレッション構文を新しいエンジンで読み取れるようにするために、評価前に事前処理されます。ただし、これらの事前処理タスクは、.jsx エクスプレッション関数ライブラリからエクスプレッションを評価する場合、またはエクスプレッションが eval() 内で呼び出される場合は、実行されません。この場合、前述の構文の修正は手動でおこなう必要があります。これらすべての構文の修正は、以前の ExtendScript エンジンと下位互換性があるので、JavaScript エンジンで機能するように記述された .jsx エクスプレッションライブラリも、以前の ExtendScript エンジンで機能します。
パフォーマンスのヒント:事前処理がおこなわれないことにより、この構文および JavaScript エンジンを使用した .jsx ライブラリからの複雑なエクスプレッションの呼び出しは、同じエクスプレッションをプロパティで直接呼び出すのに比べて、パフォーマンスが向上したように見えることがあります。
thisLayer. または thisProperty. を使用するネイティブのメソッドおよび属性に明示的にプレフィックスを付ける
次の表に、プレフィックスが必要なメソッドおよび属性を示します。例えば、time が thisLayer.time と記述される必要があるのに対して、wiggle() は thisProperty.wiggle() と記述される必要があります。
これらのプレフィックスは、属性またはメソッドが他のレイヤーまたはプロパティでまだ明示的に呼び出されていない場合にのみ必要です。例えば、thisComp.layer(1).hasParent を呼び出す場合、thisLayer. は不要です(.hasParent が layer(1) で既に明示的に呼び出されているので)。
thisLayer. を必要とするメソッド |
thisLayer. を必要とする属性 |
thisProperty. を必要とするメソッド |
thisProperty. を必要とする属性 |
---|---|---|---|
comp() |
time |
valueAtTime() |
velocity |
演算操作のベクトル演算関数への置き換え
JavaScript と以前の ExtendScript エンジンのどちらも、position + [100,100] のような構文を使用すると、配列の演算操作をオーバーロードできますが、これは、.jsx エクスプレッション関数ライブラリ内または eval() 内のエクスプレッションでは機能しません。
Position、Scale などの配列プロパティで演算を実行するには、加算、減算、乗算、除算に、ベクトル演算と同等のものを使用する必要があります。また、ベクトル演算関数は、整数に対して機能するので、どちらかのデータタイプのプロパティで呼び出される可能性のある関数は、ベクトル演算関数を使用する必要があります。
ベクトル演算関数には、thisLayer. プレフィックスを使用する必要があります。
- 可算:thisLayer.add(vec1, vec2)
- 減算:thisLayer.sub(vec1, vec2)
- 乗算:thisLayer.mul(vec, amount)
- 除算:thisLayer.div(vec, amount)
次に、標準的な演算および更新されたベクトル演算を使用するエクスプレッションの例を示します。また、ベクトル演算エクスプレッションでは、必要に応じて、適切な thisLayer. または thisProperty. プレフィックスを使用します。
wiggle() と Position プロパティの値の違いを見つけるには:
// 標準的な演算: wiggle() - value; // ベクトル演算: thisLayer.sub( thisProperty.wiggle(), value );
linear() と同様に 2 つの値を補間するが、定義された最小および最大値を超えて範囲を拡張するには:
// 標準的な演算: value1 + ( ( t - tMin ) / ( tMax - tMin ) ) * ( value2 - value1 ); // ベクトル演算: thisLayer.add( value1, thisLayer.mul( thisLayer.div( thisLayer.sub( t, tMin ), thisLayer.sub( tMax, tMin ) ), thisLayer.sub( value2, value1 ) ) );
Position プロパティ内外をループするには:
// 標準的な演算: loopIn( “cycle” ) + loopOut( “cycle” ) - value; // ベクトル演算: thisLayerub( thisLayerdd( thisPropertyoopIn( “cycle“ ), thisPropertyoopOut( “cycle” ) ), value