AfterEffects シェイプレイヤーのコンテンツ内プロパティのインデックスを活用する。　その２　（前回の投稿の続き）

#前回より使いやすくアップデート

今回のオブジェクトはアルファマットで使いたかったので、複数のレイヤーを作成するると、またプリコンポジションしてって面倒になりそうだったので、シェイプレイヤーに長方形のプロパティーを追加していく必要がありました。

サイズなども一括で変更出来る様に、スクリプトも書いています。

リピーターでも可能ですが、個々にサイズを変更したかったので、この方法を取ってみました。

##使い方は簡単
シェイプレイヤーにスライダーを２つ追加しており
①marginはオブジェクト同士の間隔です。
②line_maxは横一列に並べるオブジェクトの数になります。
③プロパティ内の位置に今回のエクスプレッションを記述

あとはシェイプレイヤーのプロパティ長方形を複製していくだけで綺麗に並んでいきます。
前回とは違い一列の数をスライダーで決めたらあとは無限に行を増やしていってくれます。

完成品はこちら

![ezgif.com-video-to-gif (1).gif](https://qiita-image-store.s3.amazonaws.com/0/178061/c91b2060-09f9-f47a-8eb4-3857efc57dc8.gif)

#エクスプレッションのコードはこちらになります。

```js

// インデックス
var indexNum = thisProperty.propertyGroup(1).propertyIndex;
// スライダー定数
var sliderNum = effect( "line_max" )( "スライダー" );
// マージン
var margin = effect( "margin" )( "スライダー" );

// インデックス / スライダー定数　⇒ 小数点を切り上げる ( 例：1.2 → 2  |  0.9 → 1 )
// yの値を制御するための変数
var ceilNum = Math.ceil( indexNum / sliderNum );

// インデックス / スライダー定数 の余り ( 例：3 / 5 → 3　|　7 / 5 → 2  )
// xの値を制御するための変数
var modNum = indexNum % sliderNum;

// 左端の座標
if( modNum == 1 ) {
    x=0;
}
// その他の座標
else if( modNum != 0 ) {
    x=margin * ( modNum - 1 );
}
// 右端の座標
else {
    x=margin * ( sliderNum - 1 );
}
y=margin * ( ceilNum - 1 );
[x,y]
```

#解説

```js
var ceilNum = Math.ceil( indexNum / sliderNum );
//yの値を制御するための変数
// インデックス / スライダー定数　⇒ 小数点を切り上げる ( 例：1.2 → 2  |  0.9 → 1 )
```

長方形パス１で説明します。
長方形のパスのインデックス番号（１）をline_maxスライダー（５）を割っています。
割った数字にmath.ceilで小数点を切り上げています。
なので長方形パス１は
indexNum (1)
なので　1/5＝0.2
0.2をmath.ceilで1を返しています。
これで長方形パス５までは１を返してくれます。


```js
var modNum = indexNum % sliderNum;
 // xの値を制御するための変数
// インデックス / スライダー定数 の余り ( 例：3 / 5 → 3　|　7 / 5 → 2  )
```

長方形パス１のインデックス（１）をline_maxスライダー（５）の余りになります。

line maxの値が５であれば
長方形パス１インデックス1＝１
長方形パス２インデックス２＝２
長方形パス３インデックス３＝３
長方形パス４インデックス４＝４
長方形パス５インデックス５＝0
長方形パス６インデックス６＝１
長方形パス７インデックス７＝２
長方形パス８インデックス８＝３
長方形パス６インデックス９＝４
長方形パス７インデックス１０＝０
という風に１～4までを返してくれます。

これを用いて長方形パスの位置をエクスプレッションで指定してあげます。
まず考え方が
①左端の座標
②それ以外の座標
③右端の座標
と考えます。

##まずは左端の座標

```js
if( modNum == 1 ) {
    x=0;
}

```
長方形パス１インデックス1＝１
長方形パス２インデックス２＝２
長方形パス３インデックス３＝３
長方形パス４インデックス４＝４
長方形パス５インデックス５＝０
長方形パス６インデックス６＝１
長方形パス７インデックス７＝２
長方形パス８インデックス８＝３

なのでmod Numが１のオブジェクトつまり
line_maxが５なので
長方形パスのインデックスが(1) (6) (11) (16) (21)の物だけが
ｘ＝0；のポジションに来るようになりました。

##次にそれ以外の座標

```js
// その他の座標
else if( modNum != 0 ) {
    x=margin * ( modNum - 1 );
}
```

長方形パス２だとすると
（modNum(2)-1）＝１です。それにmarginをかけています。
長方形パス３だとすると
（modNum(３)-1）＝２ですね。
これでインデックス毎にポジションが右にずれていきます。

##次に右端の設定です。

```js
else {
    x=margin * ( sliderNum - 1 );
}
```
そのままですね。

##最後にYの座標に

```js
y=margin * ( ceilNum - 1 );
```
line_maxが５なので
長方形パスインデックスが１～５までceilNumで１を返してくれます。
長方形パスインデックスが６～１０までceilNumで２を返してくれます。
長方形パスインデックスが１１～１５までceilNumで３を返してくれます。

これで行数が変わっていきます。

#さらに一括編集スクリプトを作成

長方形のサイズを変更とサイズをアニメーションさせる為のキーフレームを設定。
キーフレームにはグラフエディタも適用させています。
角丸もうまい具合に調整

```javascript
//選択アイテムをselItemとする
var selItem = app.project.activeItem;
//選択レイヤーをselLayとする
var selLay = selItem.selectedLayers[0];
//プロパティグループの総数を取得
var propNum = selLay.property("ADBE Root Vectors Group").numProperties;
//コンテンツ⇒長方形パス〇⇒サイズにアクセス
var vectorSize = app.project.activeItem.selectedLayers[0].property("ADBE Root Vectors Group").property("ADBE Vector Shape - Rect").property("ADBE Vector Rect Size");
//フレームレートを取得
var getFrame = app.project.activeItem.frameRate;

//////////カスタム項目//////////
//長方形パスのサイズ設定
var pathSize = 300;
//設定するキーフレームの長さ設定（フレーム数で計算）
var keyFtime=15;
/////////////////////////////


for ( i=1; i < propNum; i++){

//////////キーフレーム乱数設定項目//////////
    var setKeyF=app.project.activeItem.selectedLayers[0].property("ADBE Root Vectors Group").property(i).property("ADBE Vector Rect Size");
    var secMin = 0;
    var  secMax = 5;
    var setKey = Math.floor (( Math.random() * (secMax + 1 - secMin) ) +secMin )  ;
    //長方形パスのサイズとキーフレーム設定
    var vectorSizeSet = setKeyF.setValuesAtTimes([setKey/getFrame,(setKey+keyFtime)/getFrame],[[0,0],[pathSize,pathSize]]);
////////////////////////////////////////

//////////角丸半径設定項目//////////
    var expText  =  'content("長方形パス 1").size[0]/10;'
    var setRound=app.project.activeItem.selectedLayers[0].property("ADBE Root Vectors Group").property(i).property("ADBE Vector Rect Roundness").expression=expText;
/////////////////////////////////

//////////グラフエディター接線の設定//////////

var setGraph=setKeyF.setInterpolationTypeAtKey(1,KeyframeInterpolationType.HOLD,KeyframeInterpolationType.BEZIER);
var InPoint1 = new KeyframeEase(0,50);
var OutPoint1 = new KeyframeEase(0,50);
vectorSize.setTemporalEaseAtKey(1,[InPoint1,InPoint1],[OutPoint1,OutPoint1]);
vectorSize.setTemporalEaseAtKey(2,[InPoint1,InPoint1],[OutPoint1,OutPoint1]);

/////////////////////////////////////////

}
```

![ezgif.com-video-to-gif (2).gif](https://qiita-image-store.s3.amazonaws.com/0/178061/f4ad59ea-5e46-d470-bc43-1022343762e9.gif)




#やりたかった事が一つまた解決！！
改めて本当にスクリプトはもちろんの事エクスプレッションも便利ですよね。
仕事の場合、編集の変更依頼を簡単にしてくるけど、これをキーフレームなどでやってたらたまりませんね。
変更の可能性がありそうな場合こういった感じで作っておけば便利ですよねー！

今回はそこまで活用する機会がなさそうですが、作成しながらすごく勉強になりました。

#Special Thanks
今回はわからない事もあったので、映像関係ではないのですが、SEの仕事をしている友達のWisっちに協力の元作成致しました。
本当にありがとうございました。

#2018/6/18　追記更新

これの三角形のバージョンも作成する機会があったので、追記しておきます。
ポジションのエクスプレッション
三角形の外半径だけリンクをし直してください。
これでコンポジション以上になったら２段目、三段目となります。
ただ動作確認したところ、すごく重いので、一列作ったらレイヤーをコピーしてポジションを調整して埋め尽くした方が良さそうです。

```jsx
wd = thisComp.width;
myNum = thisProperty.propertyGroup(1).propertyGroup(1).propertyIndex;;
hankei =effect("外半径")("スライダー");
a=(Math.sqrt(3)*2)*(hankei/2);//辺の長さ
h=Math.sqrt(3)/2*a;//高さ
nowx =a*myNum ;
var ceilNum = Math.ceil( nowx/(wd+a*2));

src = thisLayer;
box = src.sourceRectAtTime(time -src.inPoint);

maxIn = Math.floor((wd+a*2)/a);
modNum = myNum %maxIn ;

[a*modNum,h*(ceilNum-1)]
```

![bandicam 2018-06-18 13-16-19-959.jpg](https://qiita-image-store.s3.amazonaws.com/0/178061/f7907069-867c-5d75-461a-2e496db2dca7.jpeg)