使用方法
- 将以下代码保存为:
Sprite Sheet Animator.jsx - 放到以下文件夹之一:
...\Adobe After Effects\Support Files\Scripts\ , 或带界面的版本:...\Scripts\ScriptUI Panels\ - 重新启动 AE, 在 AE 顶部菜单,
File → Scripts → Sprite Sheet Animator.jsx 或 Window → Sprite Sheet Animator(若放在 Panels 文件夹) - 在 Project 面板里 选中你的 Sprite Sheet 图片, 输入
Columns, Rows, FPS , 点击 Create Animation, AE 会自动生成一个完整可播放的 Sprite 动画!
(function spriteSheetAnimator() {
try {
if (app.project === null) {
alert("请先打开一个 AE 项目。");
return;
}
var win = new Window("palette", "Sprite Sheet Animator", undefined);
win.orientation = "column";
win.alignChildren = "left";
var grp1 = win.add("group");
grp1.add("statictext", undefined, "Columns:");
var colInput = grp1.add("edittext", undefined, "10");
colInput.characters = 5;
var grp2 = win.add("group");
grp2.add("statictext", undefined, "Rows:");
var rowInput = grp2.add("edittext", undefined, "3");
rowInput.characters = 5;
var grp3 = win.add("group");
grp3.add("statictext", undefined, "FPS:");
var fpsInput = grp3.add("edittext", undefined, "12");
fpsInput.characters = 5;
var btn = win.add("button", undefined, "Create Animation");
btn.onClick = function () {
var cols = parseInt(colInput.text, 10);
var rows = parseInt(rowInput.text, 10);
var fps = parseInt(fpsInput.text, 10);
if (isNaN(cols) || isNaN(rows) || cols < 1 || rows < 1) {
alert("Columns / Rows 必须 >=1");
return;
}
if (!(app.project.selection && app.project.selection.length > 0)) {
alert("请在 Project 面板选择一张 Sprite Sheet 图片");
return;
}
var item = app.project.selection[0];
if (typeof FootageItem !== "undefined" && !(item instanceof FootageItem)) {
alert("请选择图像素材(image footage)。");
return;
}
if (typeof item.width === "undefined" || typeof item.height === "undefined") {
alert("所选项目不是有效的位图素材。");
return;
}
app.beginUndoGroup("Sprite Sheet Animation");
var frameWidth = Math.round(item.width / cols);
var frameHeight = Math.round(item.height / rows);
var totalFrames = cols * rows;
var duration = Math.max(1, totalFrames / fps);
var compName = item.name + "_SpriteAnim";
var comp = app.project.items.addComp(compName, frameWidth, frameHeight, 1, duration, fps);
var layer = comp.layers.add(item);
layer.property("Scale").setValue([100, 100]);
layer.property("Anchor Point").setValue([0,0]);
var expr =
"cols = " + cols + ";\n" +
"rows = " + rows + ";\n" +
"fps = " + fps + ";\n" +
"frameIndex = Math.floor(time * fps) % (cols * rows);\n" +
"col = frameIndex % cols;\n" +
"row = Math.floor(frameIndex / cols);\n" +
"w = thisLayer.source.width / cols;\n" +
"h = thisLayer.source.height / rows;\n" +
"[-col * w, -row * h];";
layer.property("Position").expression = expr;
var mask = layer.Masks.addProperty("ADBE Mask Atom");
var shape = new Shape();
shape.vertices = [[0,0],[frameWidth,0],[frameWidth,frameHeight],[0,frameHeight]];
shape.inTangents = [[0,0],[0,0],[0,0],[0,0]];
shape.outTangents = [[0,0],[0,0],[0,0],[0,0]];
shape.closed = true;
mask.maskShape = shape;
mask.maskMode = "Add";
app.endUndoGroup();
alert("Sprite Animation 已创建:\n" + compName + "\n帧大小: " + frameWidth + "×" + frameHeight + "\n总帧数: " + totalFrames + "\nFPS: " + fps);
};
win.center();
win.show();
} catch (e) {
alert("脚本执行出错:\n" + e.toString());
}
})();