【エクスプレッション】シェイプレイヤーで線状の軌跡を自動作成 その2

『パスのトリミング』を使って自由にイーズできる軌跡を作成します。その1と違い、1つの動きごとにシェイプレイヤーを増やす仕様です。

STEP
適当なシェイプパスレイヤーを作る。

ペンツールで画面上をちょんと突いて、シェイプパスレイヤーを作ります。ここで作成されたパスは使わないのでどこにポイントがあっても大丈夫です。ただし、ポイントを消してしまうとパスプロパティごと消えるので、ポイントは残しておいてください。

STEP
ロトベジェにする。

パスプロパティ(『パス』ではなくその上の『パス 1』のほう)を右クリックでロトベジェにします。

STEP
シェイプレイヤーにエフェクト『レイヤー制御』を適用。

『レイヤー制御』の『レイヤー』ドロップダウンメニューで、軌跡を作りたいレイヤーを選択しておきます。

STEP
シェイプレイヤーのレイヤー頭を、軌跡にしたいキーフレーム頭に合わせる。

「シェイプレイヤーのレイヤー頭の時間から見ていって、軌跡用レイヤーの移動が終わったならばそこまでを全体の軌跡とする」という下記エクスプレッションの仕様のためです。

STEP
下記エクスプレッションをシェイプレイヤーの『パス』に適用。
var mInP = thisLayer.inPoint;
var mLyr = effect("レイヤー制御")("レイヤー");
var mTgtAp = mLyr.anchorPoint;

var mTgtPt = mLyr.toComp( mTgtAp , mInP );
for( var mCntr = 1 ; mCntr < 10000 ; mCntr++ ){
	var mNexPt = mLyr.toComp( mTgtAp , mInP + framesToTime( mCntr ) );
	if( mTgtPt.toString() === mNexPt.toString() ){
		break;
	}else{
		mTgtPt = mNexPt;
	}
}

if( mCntr > 1 ){
	var mTgtNexT = mInP + framesToTime( mCntr - 1 );
		
	//間のフレーム数を出す。
	//インジケータ時間が、全パス表示される前の場合。
	if( mInP <= time && time <= mTgtNexT ){
		var mValNum = timeToFrames( time - mInP );
	//全パス表示されている時間の場合。
	}else{
		var mValNum = timeToFrames( mTgtNexT - mInP );
	}

	var mVtxs = [];
	//ヌルの時間位置をバーテックスとして入れ込んでいく。
	for( var i = 0 ; i < mValNum ; i++ ){
		var mTimeTmp = mInP + framesToTime(i);
		mVtxs.push( fromComp( mLyr.toComp( mTgtAp , mTimeTmp )));
	}

	//最後に現在の位置を入れる。
	mVtxs.push( fromComp( mLyr.toComp( mTgtAp , time )));

	createPath( mVtxs, [],[], false );
}else{
	value;
}
STEP
シェイプレイヤーに『パスのトリミング』を適用、収束具合を調整する。

上記エクスプレッションまでで、すでに軌跡は自動出現します。なので『パスのトリミング』で行うのは『開始』『終了』のどちらかを使っての『収束』だけでOKです。どちらかを100%固定、どちらかを0~100%のキーフレームにし、キーフレームの開始時間はシェイプレイヤー頭から数フレーム遅らせるのがコツです。

*『開始』もしくは『終了』の最後のキーフレーム位置でシェイプレイヤーのケツを切っておけば、「どこからどこまでに軌跡がかかっているか」が分かり、のちのプロジェクトデータ確認の際などに便利です。

線の太さはいつも通り『線幅』で調整します。

使いどころ

パスのトリミングを使っての軌跡作りは、クオリティが一段上がる使えるテクニックの一つです。しかし、いちいちオブジェクトをパスに沿わせねばならず、動きが制限されてしまうのがネックでめんどうですね。そんなときにお使いください。

*仕様上、軌跡を増やしたい場合はシェイプレイヤーも増やさねばならないです。が、延々と軌跡が出続けるモーショングラフィックスもあまりないので、実用上は問題ないかなというところです。

*カメラにも対応しています。しかし、カメラが動きながら軌跡が描かれる場合、その動きも含めての軌跡となってしまうことに注意してください。イメージとしては「カメラが動いて他のオブジェクトも追従しているのに、軌跡だけはその場にとどまっている」という感じです。

*fromComp()の変換メソッドを使用していますが、これはシェイプのトランスフォームに対応していないので、シェイプのトランスフォームはデフォルトのままにしておいてください。

解説

かんたんに解説しますと、

  • まずはシェイプレイヤーの頭の時間から見ていって、軌跡用レイヤーの移動が止まったらそこまでを『軌跡全体が現れるまでの期間』とする。最大10000フレーム後方までしかチェックしていないが、実用上問題なしとする。
  • 記事その1にも書いたとおり、軌跡の作成コンセプトは『ある範囲の1フレームずつの移動位置を全て取得して、それをつなげてパスに変換する』ということ。
  • 移動位置については親子レイヤーやカメラにも対応するように、アンカーポイントを座標変換したものを位置として扱う。収集にはfor文を使う。
  • 実はtoComp()は第2引数に時間を入れることが可能。なのでこのエクスプレッションに限らず、本来valueAtTime()で座標を取得する予定だった箇所にtoComp()を加える必要がでてきた場合、valueAtTime()を使う必要がなくなる。
  • 集めた移動位置の座標はグローバル座標で、作りたいシェイプパスはレイヤー座標なので、fromComp()を使って全て座標変換してからcreatePath()に入れる。
  • 位置の座標はグローバル座標と書いたが、これはアンカーポイント(レイヤー座標)から得ている。つまり、軌跡レイヤーのレイヤー座標をグローバル座標にして、また別の、シェイプレイヤーのレイヤー座標にしている。そのため、記述上はfromComp( 軌跡レイヤー.toComp( 軌跡レイヤーのレイヤー座標 )という変換の入れ子になっている。
  • シェイプレイヤー頭の時間からオブジェクトが移動しきるまでの間は、徐々に軌跡が現れるようにする。移動しきったらずっと固定で軌跡が残るようにする。これで、パスのトリミングを使って収束をコントロールできるようになる。

という感じです。

座標変換メソッドはややこしいんですが、一度理解すると強力な武器となります。ぜひとも『toCompメソッドはなぜややこしい?』などでご確認ください!

よかったらシェアしてね!
  • URLをコピーしました!