Files
tools/Mac工具/Yeomai-Toolbox-CEP/jsx/scripts/1.图层工具/烘焙图层样式.jsx
T
2026-08-20 18:43:02 +08:00

216 lines
7.2 KiB
React
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#target photoshop
/*
Photoshop Bake Layer Style 1.5 (PS 2026 兼容版)
功能:
1. 校验:当前是否选中了图层;
2. 校验:当前图层是否包含可转换的图层样式;
3. 显示确认窗口;
4. 确认后复制当前图层作为工作副本;
5. 隐藏原图层,将其保留为备份;
6. 在工作副本上执行"图层 > 图层样式 > 创建图层";
7. 若命令失败,自动回滚到脚本执行前的状态。
*/
(function () {
var DIALOG_TITLE = "创建图层样式";
var DIALOG_MESSAGE = "是否烘焙图层样式到单独图层?";
if (app.documents.length === 0) {
alert("请先打开文档并选择一个带有图层样式的图层。", DIALOG_TITLE, true);
return;
}
// ========== 校验 1:当前是否选中了图层 ==========
function hasSelectedLayer() {
try {
var ref = new ActionReference();
ref.putProperty(stringIDToTypeID("property"), stringIDToTypeID("targetLayers"));
ref.putEnumerated(stringIDToTypeID("document"), stringIDToTypeID("ordinal"), stringIDToTypeID("targetEnum"));
var desc = executeActionGet(ref);
if (desc.hasKey(stringIDToTypeID("targetLayers"))) {
var list = desc.getList(stringIDToTypeID("targetLayers"));
return list.count > 0;
}
return false;
} catch (e) {
return false;
}
}
// ========== 校验 2:当前图层是否包含图层样式 ==========
function hasLayerStyle() {
try {
var ref = new ActionReference();
ref.putProperty(stringIDToTypeID("property"), stringIDToTypeID("layerEffects"));
ref.putEnumerated(stringIDToTypeID("layer"), stringIDToTypeID("ordinal"), stringIDToTypeID("targetEnum"));
var desc = executeActionGet(ref);
if (!desc.hasKey(stringIDToTypeID("layerEffects"))) {
return false;
}
// layerEffects 键存在不代表有样式,需检查内部是否有实际效果
var fxDesc = desc.getObjectValue(stringIDToTypeID("layerEffects"));
var effectKeys = [
"dropShadow",
"innerShadow",
"outerGlow",
"innerGlow",
"bevelEmboss",
"chromeFX",
"solidFill",
"gradientFill",
"patternFill",
"frameFX",
"frameFXStyle"
];
for (var i = 0; i < effectKeys.length; i++) {
if (fxDesc.hasKey(stringIDToTypeID(effectKeys[i]))) {
return true;
}
}
return false;
} catch (e) {
return false;
}
}
// ========== 执行前置校验(缺一不可) ==========
if (!hasSelectedLayer()) {
alert("当前未选中任何图层,请先选择一个图层后再执行。", DIALOG_TITLE, true);
return;
}
if (!hasLayerStyle()) {
alert("当前图层没有图层样式,无法烘焙。\n请先为图层添加样式(如投影、描边、外发光等)。", DIALOG_TITLE, true);
return;
}
// ========== 确认对话框 ==========
var dialog = new Window("dialog", DIALOG_TITLE);
dialog.orientation = "column";
dialog.alignChildren = ["fill", "center"];
dialog.spacing = 16;
dialog.margins = 20;
var message = dialog.add("statictext", undefined, DIALOG_MESSAGE);
message.alignment = "center";
var buttonGroup = dialog.add("group");
buttonGroup.orientation = "row";
buttonGroup.alignment = "right";
buttonGroup.spacing = 10;
buttonGroup.add("button", undefined, "取消", { name: "cancel" });
var confirmButton = buttonGroup.add(
"button",
undefined,
"确认",
{ name: "ok" }
);
dialog.defaultElement = confirmButton;
dialog.center();
if (dialog.show() !== 1) {
return;
}
// ========== 核心执行逻辑(已验证可运行) ==========
var documentReference = app.activeDocument;
var originalLayer = documentReference.activeLayer;
var originalName = originalLayer.name;
var initialHistoryState = documentReference.activeHistoryState;
try {
var workingLayer = originalLayer.duplicate();
originalLayer.visible = false;
workingLayer.name = originalName + "_烘焙";
workingLayer.visible = true;
selectLayerExclusively(documentReference, workingLayer);
createLayersFromLayerStyle();
} catch (error) {
try {
documentReference.activeHistoryState = initialHistoryState;
} catch (rollbackError) {
try {
originalLayer.visible = true;
documentReference.activeLayer = originalLayer;
} catch (restoreError) {
// 保留最初的 Photoshop 错误信息。
}
}
var details = error.message;
if (error.number !== undefined) {
details += "\n错误编号:" + error.number;
}
if (error.line !== undefined) {
details += "\n脚本行号:" + error.line;
}
alert(
"创建图层样式失败。\n\n" +
details +
"\n\n请确认当前图层包含可转换的图层样式。",
DIALOG_TITLE,
true
);
}
function selectLayerExclusively(documentReference, layerReference) {
try {
var descriptor = new ActionDescriptor();
var reference = new ActionReference();
reference.putIdentifier(
stringIDToTypeID("layer"),
layerReference.id
);
descriptor.putReference(
stringIDToTypeID("null"),
reference
);
descriptor.putBoolean(
stringIDToTypeID("makeVisible"),
false
);
executeAction(
stringIDToTypeID("select"),
descriptor,
DialogModes.NO
);
} catch (selectError) {
documentReference.activeLayer = layerReference;
}
}
function createLayersFromLayerStyle() {
// 使用 ScriptingListener 录制的标准代码:
// 用 Mk (Make) 命令,将当前图层的 Lefx (Layer Effects) 属性创建为新图层。
var idMk = charIDToTypeID("Mk ");
var desc = new ActionDescriptor();
var idnull = charIDToTypeID("null");
var ref1 = new ActionReference();
var idLyr = charIDToTypeID("Lyr ");
ref1.putClass(idLyr);
desc.putReference(idnull, ref1);
var idUsng = charIDToTypeID("Usng");
var ref2 = new ActionReference();
var idPrpr = charIDToTypeID("Prpr");
var idLefx = charIDToTypeID("Lefx");
ref2.putProperty(idPrpr, idLefx);
var idLyr2 = charIDToTypeID("Lyr ");
var idOrdn = charIDToTypeID("Ordn");
var idTrgt = charIDToTypeID("Trgt");
ref2.putEnumerated(idLyr2, idOrdn, idTrgt);
desc.putReference(idUsng, ref2);
executeAction(idMk, desc, DialogModes.NO);
}
})();