Spine插件上传
This commit is contained in:
1 parent
9802af7369
commit
2c7afbfd54
2 files changed
+671
No files matched your search
@@ -0,0 +1,195 @@
|
||||
|
||||
// This script exports photoshop layers as individual images.
|
||||
// It also write a JSON file that can be imported into Spine
|
||||
// where the images will be displayed in the same positions.
|
||||
|
||||
// Settings.
|
||||
var ignoreHiddenLayers = true;
|
||||
var savePNGs = true;
|
||||
var saveJSON = true;
|
||||
var scaleFactor = 1;
|
||||
showDialog();
|
||||
|
||||
function main () {
|
||||
// Output dir.
|
||||
var dir = app.activeDocument.path + "/images/";
|
||||
|
||||
new Folder(dir).create();
|
||||
|
||||
var name = decodeURI(app.activeDocument.name);
|
||||
name = name.substring(0, name.indexOf("."));
|
||||
|
||||
app.activeDocument.duplicate();
|
||||
|
||||
// Collect original layer visibility and hide all layers.
|
||||
var layers = [];
|
||||
getLayers(app.activeDocument, layers);
|
||||
|
||||
var layerCount = layers.length;
|
||||
var layerVisibility = {};
|
||||
|
||||
for (var i = layerCount - 1; i >= 0; i--) {
|
||||
var layer = layers[i];
|
||||
layerVisibility[layer] = layer.visible;
|
||||
layer.visible = false;
|
||||
}
|
||||
|
||||
// Save JSON.
|
||||
if (saveJSON || savePNGs) {
|
||||
var json = "{\"bones\":[{\"name\":\"root\"}],\"slots\":[\n";
|
||||
for (var i = layerCount - 1; i >= 0; i--) {
|
||||
var layer = layers[i];
|
||||
|
||||
if (ignoreHiddenLayers && !layerVisibility[layer]) continue;
|
||||
|
||||
json += "{\"name\":\"" + trim(layer.name) + "\",\"bone\":\"root\",\"attachment\":\"" + trim(layer.name) + "\"},\n";
|
||||
}
|
||||
json += "],\"skins\":{\"default\":{\n";
|
||||
for (var i = layerCount - 1; i >= 0; i--) {
|
||||
var layer = layers[i];
|
||||
|
||||
if (ignoreHiddenLayers && !layerVisibility[layer]) continue;
|
||||
|
||||
var x = app.activeDocument.width.as("px") * scaleFactor;
|
||||
var y = app.activeDocument.height.as("px") * scaleFactor;
|
||||
|
||||
layer.visible = true;
|
||||
if (!layer.isBackgroundLayer)
|
||||
app.activeDocument.trim(TrimType.TRANSPARENT, false, true, true, false);
|
||||
x -= app.activeDocument.width.as("px") * scaleFactor;
|
||||
y -= app.activeDocument.height.as("px") * scaleFactor;
|
||||
if (!layer.isBackgroundLayer)
|
||||
app.activeDocument.trim(TrimType.TRANSPARENT, true, false, false, true);
|
||||
var width = app.activeDocument.width.as("px") * scaleFactor;
|
||||
var height = app.activeDocument.height.as("px") * scaleFactor;
|
||||
|
||||
// Save image.
|
||||
if (savePNGs) {
|
||||
if (scaleFactor != 1) scaleImage();
|
||||
|
||||
var file = File(dir + "/" + trim(layer.name));
|
||||
if (file.exists) file.remove();
|
||||
activeDocument.saveAs(file, new PNGSaveOptions(), true, Extension.LOWERCASE);
|
||||
|
||||
if (scaleFactor != 1) stepHistoryBack();
|
||||
}
|
||||
|
||||
if (!layer.isBackgroundLayer) {
|
||||
stepHistoryBack();
|
||||
stepHistoryBack();
|
||||
}
|
||||
layer.visible = false;
|
||||
|
||||
x += Math.round(width) / 2;
|
||||
y += Math.round(height) / 2;
|
||||
json += "\"" + trim(layer.name) + "\":{\"" + trim(layer.name) + "\":{\"x\":" + x + ",\"y\":" + y+ ",\"width\":" + Math.round(width) + ",\"height\":" + Math.round(height) + "}},\n";
|
||||
}
|
||||
json += "}}, \"animations\": { \"animation\": {} }}";
|
||||
|
||||
if (saveJSON) {
|
||||
// Write file.
|
||||
var file = new File(dir + name + ".json");
|
||||
file.remove();
|
||||
file.open("a");
|
||||
file.lineFeed = "\n";
|
||||
file.write(json);
|
||||
file.close();
|
||||
}
|
||||
}
|
||||
|
||||
activeDocument.close(SaveOptions.DONOTSAVECHANGES);
|
||||
}
|
||||
|
||||
// Unfinished!
|
||||
function hasLayerSets (layerset) {
|
||||
layerset = layerset.layerSets;
|
||||
for (var i = 0; i < layerset.length; i++)
|
||||
if (layerset[i].layerSets.length > 0) hasLayerSets(layerset[i]);
|
||||
}
|
||||
|
||||
function scaleImage() {
|
||||
var imageSize = app.activeDocument.width.as("px");
|
||||
app.activeDocument.resizeImage(UnitValue(imageSize * scaleFactor, "px"), undefined, 72, ResampleMethod.BICUBICSHARPER);
|
||||
}
|
||||
|
||||
function stepHistoryBack () {
|
||||
var desc = new ActionDescriptor();
|
||||
var ref = new ActionReference();
|
||||
ref.putEnumerated( charIDToTypeID( "HstS" ), charIDToTypeID( "Ordn" ), charIDToTypeID( "Prvs" ));
|
||||
desc.putReference(charIDToTypeID( "null" ), ref);
|
||||
executeAction( charIDToTypeID( "slct" ), desc, DialogModes.NO );
|
||||
}
|
||||
|
||||
function getLayers (layer, collect) {
|
||||
if (!layer.layers || layer.layers.length == 0) return layer;
|
||||
for (var i = 0, n = layer.layers.length; i < n; i++) {
|
||||
// For checking if its an adjustment layer, but it also excludes
|
||||
// LayerSets so we need to find the different types needed.
|
||||
//if (layer.layers[i].kind == LayerKind.NORMAL) {
|
||||
var child = getLayers(layer.layers[i], collect)
|
||||
if (child) collect.push(child);
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
function trim (value) {
|
||||
return value.replace(/^\s+|\s+$/g, "");
|
||||
}
|
||||
|
||||
function hasFilePath() {
|
||||
var ref = new ActionReference();
|
||||
ref.putEnumerated( charIDToTypeID("Dcmn"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );
|
||||
return executeActionGet(ref).hasKey(stringIDToTypeID('fileReference'));
|
||||
}
|
||||
|
||||
function showDialog () {
|
||||
if (!hasFilePath()) {
|
||||
alert("File path not found.\nYou need to save the document before continuing.");
|
||||
return;
|
||||
}
|
||||
|
||||
var dialog = new Window("dialog", "Export Layers");
|
||||
|
||||
dialog.savePNGs = dialog.add("checkbox", undefined, "Save PNGs");
|
||||
dialog.savePNGs.value = savePNGs;
|
||||
dialog.savePNGs.alignment = "left";
|
||||
|
||||
dialog.saveJSON = dialog.add("checkbox", undefined, "Save JSON");
|
||||
dialog.saveJSON.alignment = "left";
|
||||
dialog.saveJSON.value = saveJSON;
|
||||
|
||||
dialog.ignoreHiddenLayers = dialog.add("checkbox", undefined, "Ignore hidden layers");
|
||||
dialog.ignoreHiddenLayers.alignment = "left";
|
||||
dialog.ignoreHiddenLayers.value = ignoreHiddenLayers;
|
||||
|
||||
var scaleGroup = dialog.add("panel", [0, 0, 180, 50], "Image Scale");
|
||||
var scaleText = scaleGroup.add("edittext", [10,10,40,30], scaleFactor * 100);
|
||||
scaleGroup.add("statictext", [45, 12, 100, 20], "%");
|
||||
var scaleSlider = scaleGroup.add("slider", [60, 10,165,20], scaleFactor * 100, 1, 100);
|
||||
scaleText.onChanging = function() {
|
||||
scaleSlider.value = scaleText.text;
|
||||
if (scaleText.text < 1 || scaleText.text > 100) {
|
||||
alert("Valid numbers are 1-100.");
|
||||
scaleText.text = scaleFactor * 100;
|
||||
scaleSlider.value = scaleFactor * 100;
|
||||
}
|
||||
};
|
||||
scaleSlider.onChanging = function() { scaleText.text = Math.round(scaleSlider.value); };
|
||||
|
||||
var confirmGroup = dialog.add("group", [0, 0, 180, 50]);
|
||||
var runButton = confirmGroup.add("button", [10, 10, 80, 35], "Ok");
|
||||
var cancelButton = confirmGroup.add("button", [90, 10, 170, 35], "Cancel");
|
||||
cancelButton.onClick = function() { this.parent.close(0); return; };
|
||||
runButton.onClick = function() {
|
||||
savePNGs = dialog.savePNGs.value;
|
||||
saveJSON = dialog.saveJSON.value;
|
||||
ignoreHiddenLayers = dialog.ignoreHiddenLayers.value;
|
||||
scaleFactor = scaleSlider.value / 100;
|
||||
main();
|
||||
this.parent.close(0);
|
||||
};
|
||||
|
||||
dialog.orientation = "column";
|
||||
dialog.center();
|
||||
dialog.show();
|
||||
}
|
||||
Reference in new issue
Block a user