スクリプト

パスに沿ってレイヤーを均等配置するスクリプト「masktoPosPathAlign.jsx」

標準機能で直線上に整列はできますが、自由に描いたパス上に整列はできません。これをスクリプトで実現します。

[概要]

全選択レイヤーをパスに沿って配置するスクリプト。

[使い方]

  1. 平面レイヤーを作成しマスクでパスを描く
  2. 上記パスのレイヤーを含め配置したいレイヤーを全選択
  3. スクリプトを適用

[オプション]

  • 続けて開く「進行方向へ自動回転」の有無をアラートで選択可能
  • レイヤーの天井がパスの進行方向へ向くように角度を設定可能

[解説]

function posPathAlign(){
    var actCmp=app.project.activeItem;
    var selAll = actCmp.selectedLayers;

    ////////////////////////pathL抽出

    for(i=0;i<selAll.length;i++){//パス感知
        if( isSolidLayer(selAll[i]) ){
            var pathL=selAll[i];
            var posM=pathL.position.value;
            selAll.splice(i, 1);
            break;
        }
    }

    ////////////////////////pathLマスクをモーションパスに
    try {
        var shape = pathL.mask(1).maskPath.value;
        var verts = shape.vertices;//頂点[x,y],[x,y]配列
        var outTan = shape.outTangents;
        var inTan = shape.inTangents;
        var numVerts = verts.length;//頂点数

        if (shape.closed) {
            verts.push(verts[0]);
            inTan.push(inTan[0]);
            outTan.push(outTan[0]);
            numVerts++;
        }

        for(i=0;i<numVerts;i++){
            inTan[i][2] = outTan[i][2] = 0;
            verts[i][2]=0;
        }

        for(i=0;i<numVerts;i++){//キーフレーム準備
            pathL.position.setValueAtTime(i, verts[i]);
        }

        for (var idx, i=0; i < numVerts; i++){
            idx = pathL.position.nearestKeyIndex(i);
            pathL.position.setSpatialTangentsAtKey(idx, inTan[i], outTan[i]);
        }

        for (var idx, i=0; i < numVerts-1; i++){
            idx = pathL.position.nearestKeyIndex(i);
            pathL.position.setRovingAtKey(idx, true);
        }

    //////////////////////モーションパス上に子アイテム並べ

            var firstKeyTime=pathL.position.keyTime(1);
            var lastKeyTime=pathL.position.keyTime(pathL.position.numKeys);
            var keyDuration=lastKeyTime-firstKeyTime;
            var qty=selAll.length-1;
            var newV=[],newVR=[];
            
        for(i=0;i<selAll.length;i++){
            newV.push(pathL.position.valueAtTime( (keyDuration/(selAll.length-1))*(i) +firstKeyTime,true));
            newVR.push(pathL.position.valueAtTime( ((keyDuration/(selAll.length-1))*(i) +firstKeyTime)+(1/(30)),true));
            selAll[i].position.setValue(newV[i]);
        }

            var autoAngle=confirm("進行方向へ自動回転");//自動角度

        if(autoAngle==true){
            for(i=0;i<selAll.length-1;i++){
                var target=newVR[i]-newV[i];
                var angle=Math.atan2(target[1],target[0]);
                selAll[i].zRotation.setValue(angle * 180 / Math.PI+90);
            }
        }

        selAll[selAll.length-1].zRotation.setValue(selAll[selAll.length-2].zRotation.value);
        
        for(var i=pathL.position.numKeys;i>0;i--){
            pathL.position.removeKey(i);
        }
        pathL.position.setValue(posM);
    } catch(e) {
        alert("マスクパスが見つかりません");
    }
}//function posPathAlign

function isSolidLayer(theLayer){
    if(theLayer instanceof AVLayer){
         if(theLayer.adjustmentLayer == false && theLayer.nullLayer == false && theLayer.source.mainSource instanceof SolidSource){
            return true;
         }
     }
     return false;
}

app.beginUndoGroup("masktoPosPathAlign");
    posPathAlign();
app.endUndoGroup();

内部処理としてはマスクを一旦位置のモーションパス(キーフレーム)に変換して、レイヤーの数で割った均等なタイミング(timeAtValue)時の位置に配置していきます。

必要なら進行方向に向かって自動回転させます。

自動回転は「次のレイヤー位置」だとパスよりデコボコするため
カーブに忠実になるよう「モーションパス時の1フレーム後」の方向へ回転させています。

※整列順序は「レイヤー選択順」のため、自身のレイヤーの重ね方を確認し、パスの方向へ沿わせたいレイヤーを順に選択するよう注意します。

※整列の基準となるパスは、平面レイヤーのマスクパスに限られます。また、コンポジションと同じサイズの平面レイヤーでないと、整列したレイヤーの位置ズレを起こしますので、コンポジションとサイズの異なる平面レイヤーをプロジェクトウィンドウから配置することは推奨しません。

整列したレイヤーを目的の位置までスライドさせれば済みますが、既存の平面レイヤーとサイズの異なるコンポジションでこのスクリプトを使用したい場合、マスクのためだけでも平面レイヤーを新規作成してスクリプト適用を推奨します。

ダウンロード

アイソメトリックビューを簡易的に実現するスクリプト「isometricCamera.jsx」前のページ

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

ピックアップ記事

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

関連記事

  1. スクリプト

    選択順にレーザー線を追加するスクリプト「fakePlexus.jsx」

    記事「レーザーの線で繋ぐエクスプレッション」をスクリプト化。…

  2. スクリプト

    使用フォント一覧をテキストファイル出力するスクリプト「exportFontName.jsx」

    実行すると、開いているaepファイルと同じフォルダに、使用フォント一…

  3. スクリプト

    レイヤーを自動で拡大・縮小させるスクリプト[auto]scaleAnimator.jsx

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

  4. スクリプト

    使用エフェクト一覧をテキストファイル出力するスクリプト「exportFxName.jsx」

    実行すると、開いているaepファイルと同じフォルダに、使用エフェクト…

  5. スクリプト

    aep内全フッテージのファイルパス一覧をテキストファイル出力するスクリプト「exportFootag…

    実行すると、開いているaepファイルと同じフォルダに、aepに読み込…

コメント

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

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

CAPTCHA