ロゴに作ったマスクを1枚ずつ別レイヤーへ分離し、復元スライダーで散らした位置から元の形へ戻します。
ここでは2Dの練習コンポを使い、FFXファイルを必要としない方法を説明します。
実機検証日:2026年10月14日。Windows 11 Pro(OSビルド26200)・After Effects 26.5(26.5×89、Build 89)、JavaScriptエンジンで確認しました。
本文の分離スクリプト、位置と回転の式をAE上で実行し、3枚のマスクの分離、取り消し、復元0・50・100の結果を確認しました。
検証には自作の3色画像を使いました。旧FFXや複雑なロゴ全般の再現を確認したものではありません。
重ならない固定マスクを準備する
960×540の練習コンポに、自作ロゴの静止画像を1枚置きます。
親なしの2Dレイヤー、通常合成、音声・エフェクト・トラックマットなしで練習します。
素材を2〜3個の部分に分けるマスクを作り、各マスクを加算・反転なし・不透明度100%・ぼかし0・拡張0にします。
マスク同士を重ねず、必要なロゴ領域を覆います。
マスクパスにキーフレームや式を付けません。
重なる半透明のマスクを分離すると重なり部分の合成が変わるため、この練習には使いません。
マスクごとの複製を作るスクリプト
先にプロジェクトを別名で保存し、素材レイヤーを1枚だけ選択します。
次のコードをUTF-8のMasksToParts.jsxとして保存し、「ファイル→スクリプト→スクリプトファイルを実行」から実行します。
(function () {
var comp = app.project.activeItem;
if (!(comp instanceof CompItem) || comp.selectedLayers.length !== 1) {
alert("練習コンポで素材レイヤーを1枚選択してください。"); return;
}
var original = comp.selectedLayers[0];
var masks = original.property("ADBE Mask Parade");
if (!(original instanceof AVLayer) || original.hasAudio || original.threeDLayer || original.parent ||
!original.enabled || original.locked || original.hasTrackMatte || original.isTrackMatte ||
original.adjustmentLayer || original.blendingMode !== BlendingMode.NORMAL ||
original.property("ADBE Effect Parade").numProperties || !masks ||
masks.numProperties < 2 || masks.numProperties > 20) {
alert("親なし2D素材・通常合成・エフェクト/マットなし・マスク2〜20枚が対象です。"); return;
}
var count = masks.numProperties, i, j;
for (i = 1; i <= count; i++) {
var mask = masks.property(i);
var maskPath = mask.property("ADBE Mask Shape");
if (maskPath.numKeys || maskPath.expressionEnabled) {
alert("この例はキーフレームと式のない固定マスクを対象にします。"); return;
}
if (mask.maskMode !== MaskMode.ADD || mask.inverted ||
mask.property("ADBE Mask Opacity").value !== 100 ||
mask.property("ADBE Mask Feather").value[0] !== 0 ||
mask.property("ADBE Mask Feather").value[1] !== 0 ||
mask.property("ADBE Mask Offset").value !== 0) {
alert("各マスクを加算・反転なし・不透明度100・ぼかし0・拡張0にしてください。"); return;
}
}
for (i = 1; i <= comp.numLayers; i++) {
if (/^MASK_\d+$/.test(comp.layer(i).name)) {
alert("既存のMASK_番号レイヤーがあります。別の練習コンポで実行してください。"); return;
}
}
app.beginUndoGroup("マスクごとに素材を複製");
try {
for (i = 1; i <= count; i++) {
var copy = original.duplicate();
copy.name = "MASK_" + i;
copy.moveBefore(original);
var copyMasks = copy.property("ADBE Mask Parade");
// 今回作った複製の不要マスクだけを削除。元素材は変更しない。
for (j = count; j >= 1; j--) { if (j !== i) { copyMasks.property(j).remove(); } }
}
original.enabled = false; // 元レイヤーを残して映像だけOFF
} catch (error) {
alert(error.toString() + "\n途中の複製を残しています。編集→取り消しで今回分を戻してください。");
} finally { app.endUndoGroup(); }
}());
| 入力 | 結果 | 確認する点 |
|---|---|---|
| マスク3枚 | MASK_1〜MASK_3を追加 | 各複製のマスクは1枚 |
| 元の素材 | 削除せず映像OFFで保持 | 元のマスク3枚は維持 |
| 既存MASK_番号あり | 追加せず停止 | 別の練習コンポで試す |
復元スライダーで位置と回転を戻す
ヌルを1枚作ってTRANSFORMと命名し、スライダー制御を3つ追加して「復元」「距離」「シード」と命名します。
値を順に0、300、10へ設定します。
MASK_1〜MASK_3の「位置」のストップウォッチをAltクリック(MacはOptionクリック)し、次の式を貼ります。
次の回転式は2Dレイヤーの「回転」へ貼ります。
var control = thisComp.layer("TRANSFORM");
var progress = clamp(control.effect("復元")(1).value, 0, 100);
var distance = Math.max(0, control.effect("距離")(1).value);
var match = /^MASK_(\d+)$/.exec(thisLayer.name);
var part = match ? parseInt(match[1], 10) : 0;
seedRandom(control.effect("シード")(1).value + part, true);
var angle = random(0, Math.PI * 2);
var offset = distance * (1 - progress / 100);
[value[0] + Math.cos(angle) * offset, value[1] + Math.sin(angle) * offset];
var control = thisComp.layer("TRANSFORM");
var progress = clamp(control.effect("復元")(1).value, 0, 100);
var match = /^MASK_(\d+)$/.exec(thisLayer.name);
var part = match ? parseInt(match[1], 10) : 0;
seedRandom(control.effect("シード")(1).value + part, true);
value + random(-30, 30) * (1 - progress / 100);
| 入力 | 計算上の結果 | 確認する点 |
|---|---|---|
| 復元0/距離300 | 基準位置から300px離れる | 方向は各パーツの乱数 |
| 復元50/距離300 | 基準位置から150px離れる | 回転の追加量も半分 |
| 復元100 | 基準位置と元の回転へ戻る | 各レイヤーのvalueを保持 |
復元を0秒で0、1秒で100にキーフレーム設定します。
シードは乱数列を変える値で、乱数の下限ではありません。
この式は固定した乱数方向を使い、旧式のindexと速度で終了値が0になる計算を使いません。
レイヤー名のMASK_番号を維持し、3D切替やウィグルはこの例に加えません。
Windows実機で確認した分離と復元
960×540・30fps・3秒のコンポジションに、赤・緑・青を横に並べた300×180pxのPNGを置きました。位置は[480,270]、回転0度。各色を覆う100×180pxの長方形マスクを3枚作り、加算・反転なし・不透明度100・ぼかし0・拡張0・キーなしにしました。親・エフェクト・トラックマットもありません。
本文のスクリプトを実行すると、MASK_1・MASK_2・MASK_3が追加され、各複製のマスクは1枚でした。元のOriginalは映像OFFで残り、3枚のマスクを保持しました。分離直後の描画と分離前の描画をPNGで比較すると、今回の画像では全ピクセルが一致しました。
分離直後にCtrl+Zを1回押すと、Originalの1枚だけになり、映像ON・マスク3枚へ戻りました。その後に再度分離し、TRANSFORMと3つのスライダーを作って本文の位置・回転式を適用しました。
距離300・シード10では、復元0で3枚とも基準位置から300px、復元50で150px、復元100で0pxでした。復元0の追加回転はMASK_1が約−25.4472度、MASK_2が1.0643度、MASK_3が6.2479度。復元50では半分、100ではすべて0度へ戻り、式エラーはありませんでした。これらの乱数値は今回のレイヤーでの結果です。

距離は各パーツの基準位置からの移動量で、画面内へ収める制約ではありません。上の復元0の画面では赤と緑が画面外にはみ出しました。全体を見せたい場合は距離を小さくして再確認します。

復元100では3枚とも位置[480,270]・回転0度になり、分離前と復元後のPNGは全ピクセルが一致しました。復元を0秒で0、1秒で100のキーにすると、0.5秒の値は50でした。長方形の境界を整数座標に置いた今回の結果であり、曲線・斜めの境界や半透明素材でも継ぎ目が完全に一致する保証ではありません。
既存のMASK_番号レイヤーがある状態で元レイヤーを再選択して実行すると、警告を表示して停止し、レイヤーは5枚のままで増えませんでした。今回はこの重複防止を確認しています。2〜20枚すべての枚数、異常条件の全組み合わせ、旧FFX・3D・別のAEバージョンは未検証です。
分離後の確認と戻し方
復元100でロゴの形が元の素材と一致するか、各パーツを1枚ずつSolo表示して確認します。
継ぎ目、半透明、ぼかし、マスクの重なりによる見え方は実際の素材で確認します。
式エラーではTRANSFORMの名前と3つのスライダー名、貼付先、2D設定を確認します。
分離処理の途中で止まった場合は再実行せず「編集→取り消し」で今回分を戻します。
式を貼った後の操作は追加の取り消し履歴になるため、分離直後の保存コピーも残します。
元レイヤーの映像をONに戻すときは、複製したパーツの映像をOFFにして二重表示を避けます。
旧プリセットと参考画像
旧手順はLogoTransform(control)NameTRANSFORM.ffxとLogoTransform(Logo).ffxを前提にしています。
手元にないFFXをコードだけで再現したとは扱わず、今回の2D例と分けて参照します。
旧マスク分離の参考:Video CopilotのFracture Design。
配布物の現行内容・入手可否と3D動作は今回確認していません。
次の画像は旧手順の参考画像で、今回改訂コードの実行画面ではありません。

仕様の参照:マスクプロパティの参照、Adobeの乱数・式の仕様。
素材の整理は単純なプリコンポの展開、コンポ自体を増やすときはコンポの複製を使います。
関連記事と旧配布資料
関連記事は目的に応じて使い分けます。
旧配布コードと、このページの改訂コードは同じものではありません。





