単純な2Dプリコンポの中身を、現在のコンポへコピーして展開します。
選択レイヤーのsourceを直接参照し、レイヤー名の変更や同名素材で別のコンポを探してしまう問題を避けます。
2026年10月14日、Windows 11 Pro(10.0.26200)・After Effects 26.5(Build 89)で掲載コードを実行したところ、コピー後の重なり順が変わりました。以下はその不具合を修正し、3枚の順序と取り消しを確認したコードです。以前のコードを保存している場合は、全文を置き換えてください。
改訂コードは、コピー前後のレイヤーIDを比較して追加された1枚を特定します。レイヤーIDを取得できないバージョンでは停止します。実機検証済みのバージョンはAE 26.5です。
同じサイズ・変形なしの練習から始める
960×540、24fps、3秒のコンポを2つ作ります。
素材コンポにエフェクト・親子・式・音声なしの2D平面を3枚置き、赤・緑・青のように重なり順が分かる配置にします。
素材コンポを展開先へ入れ、開始0秒、IN0秒、OUT3秒、伸縮100%とします。
位置480,270、アンカー480,270、スケール100%、回転0、不透明度100%、親なし、通常合成を維持します。
| 対象 | 練習の条件 | 適用範囲 |
|---|---|---|
| 外側のレイヤー | 変形・キー・式・親・マスク・効果なし | 同サイズ・同fps・同ピクセル比 |
| 内部のレイヤー | 2D・親なし・通常合成 | 式・音声・効果・マットなし |
| 時間 | 外側の開始0/全尺/伸縮100% | 時間差・リマップを再現するコードではない |
調整レイヤー、3D、連続ラスタライズ、タイムリマップ、トラックマット、外側の変形アニメーションを含む例は対象外です。
別の親や変換を追加した作品を、このコードで同じ表示へ戻せるとは扱いません。
選択レイヤーのsourceから展開するコード
別名保存した練習プロジェクトで、展開したいプリコンポレイヤーを1枚だけ選びます。
次のコードをExpandSimplePrecomp.jsxとして保存し、「ファイル→スクリプト→スクリプトファイルを実行」から実行します。
(function () {
var target = app.project.activeItem;
function reject(text) { alert(text); return false; }
function near(a, b) { return Math.abs(a - b) < 0.00001; }
function hasExpression(group) {
if (!group) { return false; }
if (group.canSetExpression && group.expressionEnabled) { return true; }
for (var k = 1; k <= group.numProperties; k++) {
if (hasExpression(group.property(k))) { return true; }
}
return false;
}
if (!(target instanceof CompItem) || target.selectedLayers.length !== 1) {
reject("開いたコンポでプリコンポレイヤーを1枚選択してください。"); return;
}
var original = target.selectedLayers[0];
if (typeof original.id !== "number") {
reject("この改訂コードにはレイヤーIDを取得できるAEが必要です。"); return;
}
var source = original.source; // レイヤー名やプロジェクト内の同名検索を使わない
if (!(source instanceof CompItem) || source === target || source.numLayers < 1) {
reject("中身のあるプリコンポを選択してください。"); return;
}
if (source.width !== target.width || source.height !== target.height ||
source.pixelAspect !== target.pixelAspect || !near(source.frameDuration, target.frameDuration)) {
reject("素材コンポと展開先のサイズ・ピクセル比・fpsを揃えてください。"); return;
}
var tr = original.property("ADBE Transform Group");
var position = tr.property("ADBE Position");
var anchor = tr.property("ADBE Anchor Point");
var scale = tr.property("ADBE Scale");
var rotation = tr.property("ADBE Rotate Z");
var opacity = tr.property("ADBE Opacity");
if (original.locked || !original.enabled || original.parent || original.threeDLayer ||
original.collapseTransformation || original.timeRemapEnabled || original.stretch !== 100 ||
!near(original.startTime, 0) || !near(original.inPoint, 0) || !near(original.outPoint, source.duration) ||
original.adjustmentLayer || original.guideLayer || original.solo || original.hasTrackMatte ||
original.isTrackMatte || original.blendingMode !== BlendingMode.NORMAL ||
original.property("ADBE Mask Parade").numProperties || original.property("ADBE Effect Parade").numProperties ||
position.dimensionsSeparated || position.numKeys || anchor.numKeys || scale.numKeys ||
rotation.numKeys || opacity.numKeys || hasExpression(original) || hasExpression(tr) ||
!near(position.value[0], target.width / 2) || !near(position.value[1], target.height / 2) ||
!near(anchor.value[0], source.width / 2) || !near(anchor.value[1], source.height / 2) ||
!near(scale.value[0], 100) || !near(scale.value[1], 100) || !near(rotation.value, 0) || !near(opacity.value, 100)) {
reject("対象外の変形・時間変更・親子・合成・エフェクトがあります。元のプリコンポを維持してください。"); return;
}
var i;
for (i = 1; i <= source.numLayers; i++) {
var layer = source.layer(i);
if (!(layer instanceof AVLayer) || layer.hasAudio || layer.parent || layer.threeDLayer || layer.adjustmentLayer ||
layer.guideLayer || layer.solo || layer.hasTrackMatte || layer.isTrackMatte ||
layer.timeRemapEnabled || layer.blendingMode !== BlendingMode.NORMAL ||
layer.property("ADBE Effect Parade").numProperties || hasExpression(layer) ||
hasExpression(layer.property("ADBE Transform Group")) || hasExpression(layer.property("ADBE Text Properties"))) {
reject("中のレイヤーにも2D・親なし・通常合成・式/エフェクト/マットなしの制約があります。"); return;
}
}
var copies = [];
app.beginUndoGroup("単純2Dプリコンポの中身を展開");
try {
// 1枚コピーするたびに元プリコンポの直前へ移す。
// 内部の上から順に処理すると、配置後も同じ順になる。
for (i = 1; i <= source.numLayers; i++) {
var previousIds = {};
var j;
for (j = 1; j <= target.numLayers; j++) {
previousIds["id" + target.layer(j).id] = true;
}
source.layer(i).copyToComp(target);
var copied = null;
for (j = 1; j <= target.numLayers; j++) {
if (!previousIds["id" + target.layer(j).id]) {
if (copied !== null) { throw new Error("追加レイヤーを特定できません。"); }
copied = target.layer(j);
}
}
if (copied === null) { throw new Error("追加レイヤーが見つかりません。"); }
copied.moveBefore(original);
copies.push(copied);
}
original.enabled = false; // 元プリコンポは削除せず映像だけOFF
alert("展開したレイヤー:" + copies.length + "枚。元プリコンポは映像OFFで残しました。");
} catch (error) {
alert(error.toString() + "\n途中のコピーを残しています。編集→取り消しで今回分を戻してください。");
} finally { app.endUndoGroup(); }
}());
コピー直後のlayer(1)が追加レイヤーだと決めつけず、コピー前にはなかったIDを探します。見つかった1枚を元プリコンポの直前へ移し、内部の上のレイヤーから順に繰り返すことで、元の重なり順を保ちます。
追加されたレイヤーを1枚に特定できない場合は、途中で停止します。表示される案内に従い、再実行する前に取り消してください。
元のプリコンポは削除せず、成功後に映像だけOFFにします。
内部の素材コンポや、展開先の既存レイヤーを削除する処理はありません。
Windowsで掲載コードを実行した結果
960×540px・24fps・3秒・ピクセル比1のコンポを2つ用意しました。素材コンポの上からRed、Green、Blueの300×240px平面を置き、位置はそれぞれ[380, 220]、[480, 270]、[580, 320]にしました。展開先にはRenamedPrecompという別名にしたプリコンポと、Backgroundの2枚だけを置きました。エフェクト・式・音声・キーは使っていません。
修正前のコードでは、展開後がGreen、Red、Blueの順になり、重なった領域の見た目も変わりました。コピーされる位置を先頭と仮定せず、追加レイヤーをIDで特定する改訂コードに変更して再検証しました。
| 確認項目 | 実機結果 |
|---|---|
| コピー後の順序 | Red → Green → Blue → RenamedPrecomp → Background |
| 元レイヤー | RenamedPrecompは削除されず、映像スイッチだけOFF。素材コンポの3枚も保持 |
| 描画比較 | 0秒、1秒、2秒23フレームをPNGで比較。重なり順は一致。RGBA各チャンネルの最大差は3時点とも1/255で、完全な画素一致ではない |
| 取り消し | Ctrl+Zを1回で実行前の2枚に戻り、元プリコンポの映像がON。元レイヤーと背景のIDも保持 |
| 対象外の外側スケール110% | 停止メッセージを表示。2枚のままでコピーなし |
| 素材コンポの幅だけ800px | サイズ等を揃えるよう案内。2枚のままでコピーなし |

この検証で確認したのは、上記の静止した2D平面3枚です。モーションブラー、レイヤースタイル、素材コンポの範囲外に出る描画、複雑な作品の一致や他バージョンでの動作は確認していません。作品へ適用する場合も、元プロジェクトを別名保存してから前後を比較してください。
展開前後の画像と順序を確認する
展開前の0秒・1秒・最後の表示フレームを保存し、展開後に同じ時刻と重なり順を比較します。
展開先の他レイヤーがコンポ内の番号を参照していないかも確認します。
この処理でレイヤー番号は増減します。
展開先にindexやlayer(番号)を使う式がある場合は、練習で参照を見直し、表示が変わったら元のプリコンポへ戻します。
モーションブラーやレイヤースタイル、素材コンポの範囲外部分などは、上の3枚の実測結果だけで描画一致を判断できません。
条件を満たしただけで作品全体の描画一致を保証しません。
以下の2枚は2026年10月13日の別の練習コンポです。今回の改訂コードを検証した画面は、上のRed・Green・Blueの例です。
この画面は、記事の練習(960×540、24 fps、平面3枚)とは別のコンポです。
タイムラインは25 fpsでした。
展開前は、レイヤーが「OriginalPrecomp17830」と背景の2枚でした。
プリコンポの中身は、オレンジの四角と、「PRECOMP」の文字でした。

展開後は、レイヤーが上から「Expanded_InnerBox17830」「Expanded_InnerText17830」「OriginalPrecomp17830」「[Background17830]」の4枚になりました。
「OriginalPrecomp17830」は削除されず、目のアイコンが消えた映像OFFの状態で残っていました。
ビューアーの見た目は、展開前と同じでした。

展開後のレイヤー名には「Expanded_」が付いています。
記事のコードには、レイヤー名を変える処理はありません。
停止メッセージと戻し方
名前が違ってもsourceがコンポなら参照できます。
停止した場合は、選択1枚、サイズ・fps、外側のアンカーと位置、親子・式・効果・時間設定を順に確認します。
コピー途中で例外が出た場合は元レイヤーを表示したまま停止し、途中のコピーを残します。
再実行せず「編集→取り消し」で今回分を戻し、レイヤー数と元の表示を確認します。
古いAEでは効果付きcopyToCompの取り消しに関する問題も記録されているため、この練習では内部の効果を除外します。
実機で戻せないときは保存した別名プロジェクトを開きます。
仕様の参照:Layer.copyToCompと配置操作、AVLayer.sourceと時間・合成設定、Adobeのスクリプト実行方法。
元コンポを複製してから練習する場合はコンポの複製と共有素材、ロゴを分割したい場合はマスク単位のレイヤー分離を参照します。
関連記事と旧配布資料
関連記事は目的に応じて使い分けます。
旧配布コードと、このページの改訂コードは同じものではありません。





