エクスプレッション

アナログ時計でエクスプレッションの考え方を学ぶ

エクスプレッションという「計算式で導くアニメーション」を、アナログ時計をプログラムで表現することで、学んでみましょう。

今回学べること

今回は時計のルールについて計算式での再確認と、小数点以下を切り捨てる関数「Math.floor()」についてサンプルを交えて学んでいきます。

時計のルールの確認

  • 秒針は60秒間で1周する
  • つまり1秒間では60/360(=6°)進む
  • 長針は60秒*60目盛り(=3600秒)で1周する
  • 短針は60秒*60目盛り*12目盛り(=43,200秒)で1周する

これで時計の針のルールが言葉で説明できました。あとはエクスプレッションに変換していくだけです。

言葉の式を変換する

では秒針からいってみましょう。エクスプレッションで時間を扱うtimeが用意されています。

timeはコンポジション内の時間が秒で返ってきます。現在の時間が1秒なら「1」と返ってきます。これで時間に合わせて刻一刻と変わるアニメーションを扱ってみます。

  • 秒針は60秒間で1周する
  • つまり1秒間では60/360(=6)°

なので、1秒の時に「6°」に回転すればいいので、秒針の角度にエクスプレッションを記述します。

// 秒針の回転
time*6;

これで時計の秒針と同じ回転速度が得られました。

続けて長針、短針もいってみましょう。

  • 長針は60秒*60目盛り(=3600秒)で1周する
// 長針の角度
time/3600;
  • 短針は60秒*60目盛り*12目盛り(=43,200秒)で1周する
// 短針の角度
time/43200;

と、比較的簡単に時計アニメーションが作れました。

秒針の角度を基準にする

ここから少し踏み込んで、時間通りではなくキーフレームで秒針を回転させるアニメーションも作ってみましょう。

そうなると長針、短針の角度を時間ではなく秒針の回転を基準に設定する必要があります。

  • 長針は秒針が60周で360°進む
  • つまり秒針の角度/60°
  • 短針は長針が12周で360°進む
  • つまり長針の角度/12°

ということで秒針の角度エクスプレッションは必要ないので削除し、長針の角度のエクスプレッションから秒針の角度を、また短針の角度のエクスプレッションから長針の角度を参照するため、下記のように変更します。秒針のレイヤー名を「秒針」に、長針のレイヤー名を「長針」へ変更してください。

その後、長針の角度のエクスプレッションを

// 長針の角度
thisComp.layer("秒針").rotation/60;

と変更し、短針の角度のエクスプレッションを

// 短針の角度
thisComp.layer("長針").rotation/12;

へ変更すれば完成です。

秒針を回転させて確認してみましょう。秒針が60回転で1時になれば成功です。

秒針をカクつかせる

ここまで作ったアニメーションでは秒針が滑らかに動いていますが、カチコチと秒の目盛り分のみ動かしたい場合もあるでしょう。

言葉の式を考える

つまり1.0秒、2.0秒で角度を動かし、その間は針を止めたいのです。

言葉で言えば「秒数の小数点以下を切り捨てたい」のですね。ちょうどいい関数「Math.floor()」があります。

ちなみに、小数点以下を処理する関数として代表的な3つを紹介しておきます。

Math.ceil()小数点以下切り上げ
Math.floor()小数点以下切り捨て
Math.round()小数点以下四捨五入
Math.floor(1.1);
Math.floor(1.9);

上記2つは小数点以下が切り捨てられ、どちらも「1」となります。

エクスプレッションに変換する

秒針の角度に記述するエクスプレッションは、下記の通りです。

// timeで回転させたい場合
Math.floor(time)*6;

// キーフレームでグリグリ動かしたい場合
Math.floor(value/6)*6;

まずはtimeの小数点以下を切り捨てることで、滑らかに動かなくすることができました。Math.floor()により、0.9秒までが「0」、1.0~1.9秒までが「1」と、カクカクした動きが実現できましたね。

対してキーフレームで動かす場合は、「6°ごと」に針を回転させたいので、0~5.9までが小数点以下になる計算式があれば、Math.floor()で切り捨てられます。

それが「Math.floor(value/6)」です。

エクスプレッションで「value」と記述すると、「現在エクスプレッションを記述しているプロパティの値」という意味になりますので、角度のエクスプレッションで「value」は角度、位置のエクスプレッションでは位置として「[x,y]」を指定することになります。

よって、「Math.floor(value/6)」は0°~5.9°が「0」、6.0°~11.9°が「1」となりますので、秒針の1目盛り=一周360°を60で割った「6°」になるよう、×6して、

「Math.floor(value/6)*6」

で同じ様にカクカクとした秒針の動きを角度の値で実現できます。

Math.floor() → 位置への応用

他にも位置に

[Math.floor(value[0]/50)*50,Math.floor(value[1]/50)*50];

としてタテヨコ50px刻みに動かすなど、値を滑らかに動かしたくない場合は、「Math.floor()」で小数点以下の値を切り捨てる方法が様々なシーンで応用できます。

位置を50px刻みに制限した例

選択レイヤーサイズのマスクをシェイプで描くスクリプト「addShapeMask@rect.jsx」前のページ

エクスプレッションtimeで点滅とその他の演算子を知る次のページ

ピックアップ記事

  1. なぜ?After Effectsの操作を「スクリプト」で効率化
  2. フリーランスの開業届提出は開業freeeでとにかく簡単に
  3. なぜ?After Effectsのレイヤーをエクスプレッションで効率化

関連記事

  1. エクスプレッション

    レイヤーを自動で拡大・縮小させるエクスプレッション

    選択レイヤーのインポイントからアウトポイントにかけて、指定した%サイズ…

  2. エクスプレッション

    なぜ?After Effectsのレイヤーをエクスプレッションで効率化

    「なにかの動きに連動する」アニメーションを作るには、キーフレームで頑張…

  3. エクスプレッション

    エクスプレッションで一括制御+疑似親子+ミラーリング

    エクスプレッションを使えば、他のレイヤーのプロパティを参照することが…

  4. エクスプレッション

    2つのレイヤー間に均等配置させるエクスプレッション

    2つのレイヤーを「root」と「goal」として、その間に挟まれたレイ…

  5. エクスプレッション

    エクスプレッションtimeで点滅とその他の演算子を知る

    エクスプレッション「time」の深堀りを足がかりに、プログラミングの奥…

  6. エクスプレッション

    エクスプレッションでグリッド上に均等配置する

    複数のレイヤーをグリッド状に整列させるエクスプレッションを仕込むスクリ…

コメント

  1. この記事へのコメントはありません。

  1. この記事へのトラックバックはありません。

CAPTCHA