見出し画像

After Effectsを利用したjsアニメーション(Lottieではない)

なぜやろうと思ったか

サイトを制作する際にモーションをつけることが多い。
ただ、実装ベースで考えると、どうしても同じようなモーションになってしまう。
なので、手付けのアニメーションを実装へ落とし込んで、より手間暇かかった感じのアニメーションができないかと思ったから。

また、単純に連番のアニメーションにするのではなく、デバイステキストなどを使用して、運用もしやすいアニメーションが考えられないか?ということも考えたから。

Lottieじゃダメなの?

だめ。
Lottieはsvgアニメーションやcanvasとしてのアニメーションを実現するもので、今回自分がやりたかったのは、デバイステキストにアニメーションを適用させるということだったから。

何はともあれ、AfterEffectsでこんなアニメーションを作ってみた

先に今回実装したものの結果
今回実装するものでは以下のようなものが出来上がる

https://t2421.github.io/aftereffects-web/example/001/index.html
https://t2421.github.io/aftereffects-web/example/001/index2.html

AfterEffectsからjsでアニメーションするために

1. ドキュメントを探す
2. AfterEffectsでアニメーションしたオブジェクトのプロパティをjsxから取得する
3. 1で取得したプロパティをjsonとして出力
4. 2で出力したjsonをjsで読み込み1フレームずつ再生する

1.ドキュメントを探す
Adobe

基本的に情報が古い。

After Effects Developer Center にある「After Effects Scripting Guide」を参照してください。

とか書いてあるくせに、色々とリンクをたどるとすでにそのページは存在していないことがわかる。。

日本語のドキュメント
日本語でここまで説明してくれるドキュメントはないので貴重

コンポジションの中身をほぼすべてプロパティとして出力する
この記事からはjsonファイルへの出力方法を参考にした。

AEscriptのサンプルがたくさん

2.AfterEffectsでアニメーションしたオブジェクトのプロパティをjsxから取得する

A. Extend Script Toolkit (ESTK)のインストール
B. ESTKでプログラムを作成しAfterEffectsで実行する
C. レイヤーを指定してプロパティを取得する
D. アンカーポイントの情報を使って位置情報を補正する

A.Extend Script Toolkit (ESTK)のインストール

Adobe Creative Cloud のデスクトップアプリ、設定から「古いアプリを表示」を選択しないと出てこない。。(もうこんなことするなってことなのかな。。)

画像1

B.ESTKでプログラムを作成しAfterEffectsで実行する

プルダウンからAdobe After Effectsを選択すると現在開いているAfterEffectsでプログラムを実行してくれる。

画像2

C.レイヤーを指定してプロパティを取得する

レイヤーを取得して位置情報を得る

var myLayer = app.project.item(1).layer(1);
var refPosition= myLayer.transform.position;

ここからいきなりつまづいた。

色々なサイトでは

myLayer.transform.position[0] //x座標
myLayer.transform.position[1] //y座標

のように値が取得できるとあったが、undefinedが返ってくる。

調べていくと以下の関数があるみたいなので試しに使ってみると取得することができた

var xy = refPosition.valueAtTime(time, true); //[x,y]の配列で返ってくる

今回はwebで使うことを想定しており、1フレームごとの値を取得したいので、こんな感じで1フレームあたりの秒数をカウントアップしていくことで対応した。

var fps = 60;
var secByFrame = 1/60; //1フレームごとの秒数
var finishSec = 3;// アニメーション終了の秒数

for(var time = 0;time<finishSec;time+=secByFrame){
   var xy = refPosition.valueAtTime(time, true);
   positions.push(xy);
}

基本的には回転もスケールも同じように取得することができる

D.アンカーポイントの情報を使って位置情報を補正する

AfterEffectsではアンカーポイントを変更すると、位置の座標もそれに応じて変化してしまう。

一方、cssのtransform-originを変更しても位置情報に変化がない。

そのため、AfterEffectsで取得したpositionをそのまま使うのではなく、アンカーポイントの移動によるずれを調整してあげる

//after Effects上で使用しているオブジェクトの大きさ
var objectBase = {
 width:100,
 height:100
}
var anchors = [];

//中略

var adjustPosition = [];
var startAnchor = anchors[0];

for(var i = 0;i<positions.length;i++){
   var xy = [positions[i][0]-startPosition[0],positions[i][1]-startPosition[1]];
   var anchorXY = [anchors[i][0] - startAnchor[0],anchors[i][1] - startAnchor[1]];//初期のアンカーからどれくらい動いたか
   var adjustXY = [xy[0]-anchorXY[0]/100*objectBase.width,xy[1]-anchorXY[1]/100*objectBase.height];//アンカーの動いた分調整してあげる
   adjustPosition.push(adjustXY)
}

3. 2で取得したプロパティをjsonとして出力

var file = File.saveDialog("保存するファイル名を入れてください");
if(file){
 var str = "var motion = "+JSON.stringify(outputObject);
 file.open("w");
 file.encoding = "UTF-8";
 file.lineFeed = "Unix";
 file.write(str);
 file.close();
 alert("jsonを出力しました。");
}

4.出力したjsonをjsで読み込み1フレームずつ再生する

基本的には配列を回して読み込むだけだが、AfterEffectsで作成したベースのオブジェクトと、アニメーションを適用するオブジェクトの比率を考慮して位置情報を適用する。

webでの幅が50、aeでの幅が100なら 位置情報 * (50/100)という計算をしてtranslateを適用する。

そのようにすることで、アニメーションの見た目がAfterEffectsに近くなる

まとめ

ここまで実装してみたが、明らかに面倒臭い。とても面倒臭い。
また、以下のように色々な懸念点もある。

- AfterEffectsのレイヤー構造が複雑な時に対応できない
- 3Dの回転の見え方がAfterEffectsとwebで違う。(カメラ的な話?)
- 思いっきり実装を意識してAfterEffectsのアニメーションを作っているので今のままだと分業することができない

デバイステキストに手付けのアニメーションのパラメータを適用するという目的は果たすことができたが、実装の工数は大きい。また、かなり実装を意識してモーションを作る必要があるため、モーションをつける人とプログラムを実装する人が一緒というケースじゃないとうまくいかないだろうと思う。

いいなと思ったら応援しよう!