AEのエクスプレッションセレクター入門
イントロダクション

AEのテキストアニメーターは、エクスプレッションセレクターを活用することで表現の幅が広がる。
この記事では、簡単な例をもとにエクスプレッションセレクターの入門的な説明を行う。
質問や分かりにくい表現があったら、https://x.com/__aaa_5sまでなんでもお気軽にお知らせください!喜びます!
エクスプレッションセレクター入門
エクスプレッションセレクターを使うさいに理解しておきたいのは、(1)3つの変数textIndex・textTotal・selectorValueと、(2)エクスプレッションの実行のされ方、(3)(4)selectorValueの特性である。順番に説明する。
まず、(1)(2)について、以下の例1-1をもとに説明を進める。


例1-1では、ABCDという白い文字のテキストレイヤーに対して、Animator 1というテキストアニメーターを適用している。Animator 1内では、塗りプロパティ(Fill Color)に赤色を指定し、エクスプレッションセレクターをかけている。エクスプレッションは以下の通り。
selectorValue = textIndex / textTotal * 100
(1) 3つの変数
上記のエクスプレッションにも使われているように、エクスプレッションセレクターには、textIndex、textTotal、selectorValueの3つの変数がある。
これらを説明する。
textIndexは、それぞれの文字に前から順番に与えらえれる数値である。例1-1では、AのtextIndexは1、Bのは2、Cのは3、Dのは4である。
(0スタートではないのでご注意!)
textTotalは、文字の合計数である。例1-1では、ABCDの合計4文字なので、textTotalは4である。
selectorValueは、それぞれの文字に対するプロパティの影響値である。0なら0%、100なら100%、指定したプロパティが影響する。
例1-1のselectorValueを見てみよう。(天下り的な説明になるが)エクスプレッションの計算結果、AはselectorValueが25になり、白から25%赤に近づく。BはselectorValueが50になり、50%赤になる。DはselectorValueが100になり、100%赤になる。
なお、他のセレクター(範囲セレクターなど)も、selectorValueを操作するものだといっていいだろう。
(2) エクスプレッションの実行され方
これらの3つの変数を用いてエクスプレッションを書くわけだが、エクスプレッションの実行され方ついて留意しておきたいことがある。それは、エクスプレッションは、各文字に対して独立して計算されるということだ。
どういうことか。例1-1において、実際に各文字に対して行われる計算を再現してみよう。
Aでは、textIndex=1、textTotal=4だから、これらの値をselectorValue = textIndex / textTotal * 100に代入すると、selectorValue = 1 / 4 * 100 = 25になる。
Bでは、textIndex=2、textTotal=4だから、これらの値をselectorValue = textIndex / textTotal * 100に代入すると、selectorValue = 2 / 4 * 100 = 50になる。
Cでは、textIndex=3、textTotal=4なので、selectorValue=75になる。
Dでは、textIndex=4、textTotal=4なので、selectorValue=100になる。
結果をまとめると、AのselectorValue=25、BのselectorValue=50、CのselectorValue=75、DのselectorValue=100になる。
このように、エクスプレッションは各文字に対して独立に計算される。説明を図にまとめた。

(3) selectorValueは継承される
さて、簡単のために説明を避けたselectorValueの性質を説明する。それは、selectorValueはセレクター間・セレクター内で継承されるということである。
セレクター間での継承
先の例1-1にExpression Selector 2を追加した例1-2により説明する。


例1-2は、例1-1とほぼ同じ見た目だが、赤さが半分である。
例1-2に追加されたExpression Selector 2のエクスプレッションを見てみよう。
selectorValue = selectorValue / 2
上記のエクスプレッションはselectorValueが2つあって混乱するかもしれない。これは次のように読める。まず、Expression Selector 1で計算された前のselectorValue(右のほうのselectorValue)を2で割る。そして、それを新しいselectorValue(左のほうのselectorValue)に代入する。
例1-1と同様に、実際にそれぞれの文字に対するExpression Selector 2の計算過程を再現してみよう。
Aでは、Expression Selector 1の計算結果、selectorValueは25になっていた。Expression Selector 2では、selectorValue / 2 = 25/2で、新しいselectorValueが12.5になる。
Bでは、Expression Selector 1の計算結果、selectorValueは50になっていた。selectorValue / 2 = 50/2 で、新しいselectorValueは25になる。
Cは75/2=37.5、Dは100/2=50が新しいselectorValueになる。
なお、他のセレクター(範囲セレクターなど)からもselectorValueを継承する。実際には他のセレクターから受け取る場合のほうが多いだろう。
手描きの図で恐縮だが、以上の継承の性質をまとめた。

セレクター内での継承
上の例1-2では、セレクターの間でのselectorValueの継承を見た。なお、セレクター内でもselectorValueは継承される。
その性質を確認するために、例1-2のExpression Selector 2を以下のように書き換えてみよう。
selectorValue = selectorValue / 2
selectorValue = selectorValue / 4
こうすると、文字の赤さは総合して1/8になる。
文字Aでの計算過程を再現する。まず、1行目では、前のExpression Selector 1でのselectorValue=25を持ってきて、それを2で割るので、新しいselectorValueが12.5になる。注意したいのが2行目だ。2行目では、1行目で計算された新しいselectorValue=12.5が継承されて、それを4で割るので、最終的なselectorValueは3.125になる。
※なお、次のような解釈は間違っている。
「変数selectorValueは読み取るときには常に前のセレクターのselectorValueを参照するので、2行目でも、Expression Selector 1でのselectorValue=25が参照される。それを4で割るので、最終的なselectorValueは6.25になる。」
(4) selectorValueは配列
(3)に加えて、もう1つ説明を避けていたselectorValueの性質を紹介する。実は、selectorValueは3つの「要素」を持つ「配列」である。さきほどまで「AのselectorValueは25である」といった表現をしていたが、正確には、AのselectorValueは[25, 25, 25]という3つの要素を持つ配列である。
「配列」・「要素」という用語について説明する。配列とは、複数の要素をもっている変数のことである。たとえば、AEにおいて位置は配列であり、3つの要素、すなわちX座標、Y座標、Z座標を持っている。X座標が5、Y座標が-10、Z座標が9.4とすると、その位置は[5, -10, 9.4]と表せる。
なお、注意したいのが、配列の要素の数え方は0からスタートするということである。したがって、上の位置の例ならば、X座標は1個目の要素ではなく、0個目の要素である。Y座標が1個目の要素である。
本筋に戻ろう。selectorValueは配列であり、その中の各要素は、プロパティーの各要素の効き方に対応する。これだけだと意味が分からないと思うので、例2を用いて説明する。


例2を理解するにあたって、色がRGBの3つの要素で表せることに留意せよ。
ABCDという黒の文字(RGB(0, 0, 0))のテキストレイヤーに、Animator 1というテキストアニメーターを適用する。Animator 1内では、塗りプロパティに白色(RGB(1, 1, 1))を指定し、エクスプレッションセレクター(selectorValue=[0, 100, 0])をかけることで、ABCDのselectorValueに一律に[0, 100, 0]の値を代入する。
さきに述べたように、「selectorValueは配列であり、その中の各要素は、プロパティーの各要素の効き方に対応する。」この例の場合では、プロパティーは色であり、色の0要素目はR、1要素目はG、2要素目はBである。これらに、selectorValueの0・1・2要素目がそれぞれ対応している。したがって、selectorValue=[0, 100, 0]によって、元の黒色(0, 0, 0)から指定した白色(1, 1, 1)に向けて、1要素目のGだけ100%近づくが、0・2要素目のRとBは変化しない。この結果、文字の色は(0, 1, 0)、緑になる。
注意:selectorValueで条件式を作るさいは要素を取り出す
このようなselectorValueの配列の性質は、実際には考えなくてもよいケースが多い。例1-1、例1-2においても、selectorValueを1つの数値のように扱っていた。
ただし、そのようなケースにおいても、selectorValueが配列であることに関係する注意しておきたい点がある。それは、エクスプレッションセレクター中で、selectorValueを条件式に使うさいは、selectorValue配列から要素を取りだす必要があるということだ。なお、要素のN番目を取り出すには、selectorValue[N]と書く。
この注意点について、最初の例(例1-1)に、Expression Selector 3を追加した例1-3を用いて説明する。


例1-3では、例1-1(例1-2じゃないよ)に、Expression Selector 3を追加した。Expression Selector 1によって、AのselectorValueは25、Bのは50、Cのは75、Dのは100になるのは先に述べたが、厳密にはselectorValueは配列なので、Aは[25, 25, 25]、Bは[50, 50, 50]、Cは[75, 75, 75]、Dは[100, 100, 100]である。
Expression Selector 3のエクスプレッションを見てみよう。
selectorValue[0] < 51 ? selectorValue=100 : selectorValue=0
このエクスプレッションでは、3項演算子を使っている。3項演算子は、まず、?の前にある条件を評価する。その条件が当てはまる(true)なら:の左側にある式を実行し、当てはまらない(false)なら:の右側にある式を実行する。
3項演算子の使われ方を、このエクスプレッションで見てみよう。まず、前のselectorValueの最初の要素[0]の値が51未満かどうか(selectorValue[0] < 51)という条件を評価する。もしその条件があてはまるなら、新しいselectorValueに100(selectorValue=100)、条件があてはまらないなら、新しいselectorValueに0(selectorValue=0)を代入する。
ここでも、実際にそれぞれの文字に対する計算を再現してみよう。
Aは前のselectorValueは[25, 25, 25]である、その0番目の要素(はじめの要素)のselectorValue[0]は、25である。これは、51未満という条件を満たすので、新しいselectorValueとして100が代入される。これは、[100, 100, 100]を代入するの同じ結果になる。
Bは前のselectorValueは[50, 50, 50]で、selectorValue[0]は50である。これは、51未満という条件を満たすので、新しいselectorValueは100になる。
CのselectorValue[0]は75、DのselectorValue[0]は100だから、51未満という条件を満たさず、新しいselectorValueは0になる。
注目してほしいのが、selectorValue[0] < 51のように、配列のいずれかの要素を取り出して条件式を作っていることだ。要素を取り出さずに、配列をそのまま比較しようとしてselectorValue < 51のように記述しても、うまくいかない。また、同じ要素数の配列を比較しようとしてselectorValue < [51, 51, 51]のように記述しても、うまくいかない。理由は複雑だが、大まかに言って、JavaScriptの不等号・等号には、配列をそのまま比較する機能がなく、配列を文字やNaN(Not a Number)に変換してしまうからだ。とにかく、JavaScriptでは、配列をそのまま不等号や等号で比較してもうまくいかないということさえ理解しておけば何とかなる(はず)。
図にまとめた。

結論
当記事では、簡単な例を用いてエクスプレッションセレクターの仕組みを説明した。
次の記事では、これらの知識をもとに応用例を解説していく…と行きたいところだが、まずは、初心者でもフォローできるように、応用例で使われる関数などについて解説する。ある程度エクスプレッションができる人は、読み飛ばしてもらって構わない。
AEのエクスプレッションセレクター応用:初心者向け準備編|aaa_5s #note https://note.com/aaa_5s/n/n4fccaa766704?sub_rt=share_pw