From 2c7afbfd542825bcbec785bf755eb6957941f1f3 Mon Sep 17 00:00:00 2001 From: Abin Date: Thu, 4 Sep 2025 10:36:20 +0800 Subject: [PATCH] =?UTF-8?q?Spine=E6=8F=92=E4=BB=B6=E4=B8=8A=E4=BC=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Spine插件/LayersToPNG新版.jsx | 476 ++++++++++++++++++++++++++++++++++ Spine插件/LayersToPNG旧版.jsx | 195 ++++++++++++++ 2 files changed, 671 insertions(+) create mode 100644 Spine插件/LayersToPNG新版.jsx create mode 100644 Spine插件/LayersToPNG旧版.jsx diff --git a/Spine插件/LayersToPNG新版.jsx b/Spine插件/LayersToPNG新版.jsx new file mode 100644 index 0000000..21c5a65 --- /dev/null +++ b/Spine插件/LayersToPNG新版.jsx @@ -0,0 +1,476 @@ +// This script exports photoshop layers as individual PNGs. It also +// writes a JSON file that can be imported into Spine where the images +// will be displayed in the same positions and draw order. + +// Setting defaults. +var writePngs = true; +var writeTemplate = false; +var writeJson = true; +var ignoreHiddenLayers = true; +var pngScale = 1; +var groupsAsSkins = false; +var useRulerOrigin = false; +var imagesDir = "./images/"; +var projectDir = ""; +var padding = 1; + +// IDs for saving settings. +const settingsID = stringIDToTypeID("settings"); +const writePngsID = stringIDToTypeID("writePngs"); +const writeTemplateID = stringIDToTypeID("writeTemplate"); +const writeJsonID = stringIDToTypeID("writeJson"); +const ignoreHiddenLayersID = stringIDToTypeID("ignoreHiddenLayers"); +const groupsAsSkinsID = stringIDToTypeID("groupsAsSkins"); +const useRulerOriginID = stringIDToTypeID("useRulerOrigin"); +const pngScaleID = stringIDToTypeID("pngScale"); +const imagesDirID = stringIDToTypeID("imagesDir"); +const projectDirID = stringIDToTypeID("projectDir"); +const paddingID = stringIDToTypeID("padding"); + +var originalDoc; +try { + originalDoc = app.activeDocument; +} catch (ignored) {} +var settings, progress; +loadSettings(); +showDialog(); + +function run () { + // Output dirs. + var absProjectDir = absolutePath(projectDir); + new Folder(absProjectDir).create(); + var absImagesDir = absolutePath(imagesDir); + var imagesFolder = new Folder(absImagesDir); + imagesFolder.create(); + var relImagesDir = imagesFolder.getRelativeURI(absProjectDir); + relImagesDir = relImagesDir == "." ? "" : (relImagesDir + "/"); + + // Get ruler origin. + var xOffSet = 0, yOffSet = 0; + if (useRulerOrigin) { + var ref = new ActionReference(); + ref.putEnumerated(charIDToTypeID("Dcmn"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt")); + var desc = executeActionGet(ref); + xOffSet = desc.getInteger(stringIDToTypeID("rulerOriginH")) >> 16; + yOffSet = desc.getInteger(stringIDToTypeID("rulerOriginV")) >> 16; + } + + activeDocument.duplicate(); + + // Output template image. + if (writeTemplate) { + if (pngScale != 1) { + scaleImage(); + storeHistory(); + } + + var file = new File(absImagesDir + "template" + ".png"); + if (file.exists) file.remove(); + + var opts; + opts = new ExportOptionsSaveForWeb(); + opts.format = SaveDocumentType.PNG; + opts.PNG8 = false; + opts.quality = 100; + + activeDocument.exportDocument(file, ExportType.SAVEFORWEB, opts); + + if (pngScale != 1) restoreHistory(); + } + + if (!writeJson && !writePngs) { + activeDocument.close(SaveOptions.DONOTSAVECHANGES); + return; + } + + // Rasterize all layers. + try { + executeAction(stringIDToTypeID( "rasterizeAll" ), undefined, DialogModes.NO); + } catch (ignored) {} + + // Collect and hide layers. + var layers = []; + collectLayers(activeDocument, layers); + var layersCount = layers.length; + + storeHistory(); + + // Store the slot names and layers for each skin. + var slots = {}, skins = { "default": [] }; + for (var i = layersCount - 1; i >= 0; i--) { + var layer = layers[i]; + + // Use groups as skin names. + var potentialSkinName = trim(layer.parent.name); + var layerGroupSkin = potentialSkinName.indexOf("-NOSKIN") == -1; + var skinName = (groupsAsSkins && layer.parent.typename == "LayerSet" && layerGroupSkin) ? potentialSkinName : "default"; + + var skinLayers = skins[skinName]; + if (!skinLayers) skins[skinName] = skinLayers = []; + skinLayers[skinLayers.length] = layer; + + slots[layerName(layer)] = true; + } + + // Output skeleton and bones. + var json = '{"skeleton":{"images":"' + relImagesDir + '"},\n"bones":[{"name":"root"}],\n"slots":[\n'; + + // Output slots. + var slotsCount = countAssocArray(slots); + var slotIndex = 0; + for (var slotName in slots) { + if (!slots.hasOwnProperty(slotName)) continue; + + // Use image prefix if slot's attachment is in the default skin. + var attachmentName = slotName; + var defaultSkinLayers = skins["default"]; + for (var i = defaultSkinLayers.length - 1; i >= 0; i--) { + if (layerName(defaultSkinLayers[i]) == slotName) { + attachmentName = slotName; + break; + } + } + + json += '\t{"name":"' + slotName + '","bone":"root","attachment":"' + attachmentName + '"}'; + slotIndex++; + json += slotIndex < slotsCount ? ",\n" : "\n"; + } + json += '],\n"skins":{\n'; + + // Output skins. + var skinsCount = countAssocArray(skins); + var skinIndex = 0; + for (var skinName in skins) { + if (!skins.hasOwnProperty(skinName)) continue; + json += '\t"' + skinName + '":{\n'; + + var skinLayers = skins[skinName]; + var skinLayersCount = skinLayers.length; + var skinLayerIndex = 0; + for (var i = skinLayersCount - 1; i >= 0; i--) { + var layer = skinLayers[i]; + var slotName = layerName(layer); + var placeholderName, attachmentName; + if (skinName == "default") { + placeholderName = slotName; + attachmentName = placeholderName; + } else { + placeholderName = slotName; + attachmentName = skinName + "/" + slotName; + } + + var x = activeDocument.width.as("px") * pngScale; + var y = activeDocument.height.as("px") * pngScale; + + layer.visible = true; + if (!layer.isBackgroundLayer) activeDocument.trim(TrimType.TRANSPARENT, false, true, true, false); + x -= activeDocument.width.as("px") * pngScale; + y -= activeDocument.height.as("px") * pngScale; + if (!layer.isBackgroundLayer) activeDocument.trim(TrimType.TRANSPARENT, true, false, false, true); + var width = activeDocument.width.as("px") * pngScale + padding * 2; + var height = activeDocument.height.as("px") * pngScale + padding * 2; + + // Save image. + if (writePngs) { + if (pngScale != 1) scaleImage(); + if (padding > 0) activeDocument.resizeCanvas(width, height, AnchorPosition.MIDDLECENTER); + + if (skinName != "default") new Folder(absImagesDir + skinName).create(); + + var opts; + opts = new ExportOptionsSaveForWeb(); + opts.format = SaveDocumentType.PNG; + opts.PNG8 = false; + opts.quality = 100; + + activeDocument.exportDocument(new File(absImagesDir + attachmentName + ".png"), ExportType.SAVEFORWEB, opts); + } + + restoreHistory(); + layer.visible = false; + + x += Math.round(width) / 2; + y += Math.round(height) / 2; + + // Make relative to the Photoshop document ruler origin. + if (useRulerOrigin) { + x -= xOffSet * pngScale; + y -= activeDocument.height.as("px") * pngScale - yOffSet * pngScale; // Invert y. + } + + if (attachmentName == placeholderName) { + json += '\t\t"' + slotName + '":{"' + placeholderName + '":{' + + '"x":' + x + ',"y":' + y + ',"width":' + Math.round(width) + ',"height":' + Math.round(height) + '}}'; + } else { + json += '\t\t"' + slotName + '":{"' + placeholderName + '":{"name":"' + attachmentName + '", ' + + '"x":' + x + ',"y":' + y + ',"width":' + Math.round(width) + ',"height":' + Math.round(height) + '}}'; + } + + skinLayerIndex++; + json += skinLayerIndex < skinLayersCount ? ",\n" : "\n"; + } + json += "\t\}"; + + skinIndex++; + json += skinIndex < skinsCount ? ",\n" : "\n"; + } + json += '},\n"animations":{"animation":{}}\n}'; + + activeDocument.close(SaveOptions.DONOTSAVECHANGES); + + // Output JSON file. + if (writeJson) { + var name = decodeURI(originalDoc.name); + name = name.substring(0, name.indexOf(".")); + var file = new File(absProjectDir + name + ".json"); + file.remove(); + file.open("w", "TEXT"); + file.lineFeed = "\n"; + file.write(json); + file.close(); + } +} + +// Dialog and settings: + +function showDialog () { + if (!originalDoc) { + alert("Please open a document before running the LayersToPNG script."); + return; + } + if (!hasFilePath()) { + alert("Please save the document before running the LayersToPNG script."); + return; + } + + var dialog = new Window("dialog", "Spine LayersToPNG"); + dialog.alignChildren = "fill"; + + var checkboxGroup = dialog.add("group"); + var group = checkboxGroup.add("group"); + group.orientation = "column"; + group.alignChildren = "left"; + var writePngsCheckbox = group.add("checkbox", undefined, " Write layers as PNGs"); + writePngsCheckbox.value = writePngs; + var writeTemplateCheckbox = group.add("checkbox", undefined, " Write a template PNG"); + writeTemplateCheckbox.value = writeTemplate; + var writeJsonCheckbox = group.add("checkbox", undefined, " Write Spine JSON"); + writeJsonCheckbox.value = writeJson; + group = checkboxGroup.add("group"); + group.orientation = "column"; + group.alignChildren = "left"; + var ignoreHiddenLayersCheckbox = group.add("checkbox", undefined, " Ignore hidden layers"); + ignoreHiddenLayersCheckbox.value = ignoreHiddenLayers; + var groupsAsSkinsCheckbox = group.add("checkbox", undefined, " Use groups as skins"); + groupsAsSkinsCheckbox.value = groupsAsSkins; + var useRulerOriginCheckbox = group.add("checkbox", undefined, " Use ruler origin as 0,0"); + useRulerOriginCheckbox.value = useRulerOrigin; + + var slidersGroup = dialog.add("group"); + group = slidersGroup.add("group"); + group.orientation = "column"; + group.alignChildren = "right"; + group.add("statictext", undefined, "PNG scale:"); + group.add("statictext", undefined, "Padding:"); + group = slidersGroup.add("group"); + group.orientation = "column"; + var scaleText = group.add("edittext", undefined, pngScale * 100); + scaleText.characters = 4; + var paddingText = group.add("edittext", undefined, padding); + paddingText.characters = 4; + group = slidersGroup.add("group"); + group.orientation = "column"; + group.add("statictext", undefined, "%"); + group.add("statictext", undefined, "px"); + group = slidersGroup.add("group"); + group.alignment = ["fill", ""]; + group.orientation = "column"; + group.alignChildren = ["fill", ""]; + var scaleSlider = group.add("slider", undefined, pngScale * 100, 1, 100); + var paddingSlider = group.add("slider", undefined, padding, 0, 4); + scaleText.onChanging = function () { scaleSlider.value = scaleText.text; }; + scaleSlider.onChanging = function () { scaleText.text = Math.round(scaleSlider.value); }; + paddingText.onChanging = function () { paddingSlider.value = paddingText.text; }; + paddingSlider.onChanging = function () { paddingText.text = Math.round(paddingSlider.value); }; + + var outputGroup = dialog.add("panel", undefined, "Output directories"); + outputGroup.alignChildren = "fill"; + outputGroup.margins = [10,15,10,10]; + var textGroup = outputGroup.add("group"); + group = textGroup.add("group"); + group.orientation = "column"; + group.alignChildren = "right"; + group.add("statictext", undefined, "Images:"); + group.add("statictext", undefined, "JSON:"); + group = textGroup.add("group"); + group.orientation = "column"; + group.alignChildren = "fill"; + group.alignment = ["fill", ""]; + var imagesDirText = group.add("edittext", undefined, imagesDir); + var projectDirText = group.add("edittext", undefined, projectDir); + outputGroup.add("statictext", undefined, "Begin paths with \"./\" to be relative to the PSD file.").alignment = "center"; + + var group = dialog.add("group"); + group.alignment = "center"; + var runButton = group.add("button", undefined, "OK"); + var cancelButton = group.add("button", undefined, "Cancel"); + cancelButton.onClick = function () { + dialog.close(0); + return; + }; + + function updateSettings () { + writePngs = writePngsCheckbox.value; + writeTemplate = writeTemplateCheckbox.value; + writeJson = writeJsonCheckbox.value; + ignoreHiddenLayers = ignoreHiddenLayersCheckbox.value; + var scaleValue = parseFloat(scaleText.text); + if (scaleValue > 0 && scaleValue <= 100) pngScale = scaleValue / 100; + groupsAsSkins = groupsAsSkinsCheckbox.value; + useRulerOrigin = useRulerOriginCheckbox.value; + imagesDir = imagesDirText.text; + projectDir = projectDirText.text; + var paddingValue = parseInt(paddingText.text); + if (paddingValue >= 0) padding = paddingValue; + } + + dialog.onClose = function() { + updateSettings(); + saveSettings(); + }; + + runButton.onClick = function () { + if (scaleText.text <= 0 || scaleText.text > 100) { + alert("PNG scale must be between > 0 and <= 100."); + return; + } + if (paddingText.text < 0) { + alert("Padding must be >= 0."); + return; + } + dialog.close(0); + + var rulerUnits = app.preferences.rulerUnits; + app.preferences.rulerUnits = Units.PIXELS; + try { + run(); + } catch (e) { + alert("An unexpected error has occurred.\n\nTo debug, run the LayersToPNG script using Adobe ExtendScript " + + "with \"Debug > Do not break on guarded exceptions\" unchecked."); + debugger; + } finally { + if (activeDocument != originalDoc) activeDocument.close(SaveOptions.DONOTSAVECHANGES); + app.preferences.rulerUnits = rulerUnits; + } + }; + + dialog.center(); + dialog.show(); +} + +function loadSettings () { + try { + settings = app.getCustomOptions(settingsID); + } catch (e) { + saveSettings(); + } + if (typeof settings == "undefined") saveSettings(); + settings = app.getCustomOptions(settingsID); + if (settings.hasKey(writePngsID)) writePngs = settings.getBoolean(writePngsID); + if (settings.hasKey(writeTemplateID)) writeTemplate = settings.getBoolean(writeTemplateID); + if (settings.hasKey(writeJsonID)) writeJson = settings.getBoolean(writeJsonID); + if (settings.hasKey(ignoreHiddenLayersID)) ignoreHiddenLayers = settings.getBoolean(ignoreHiddenLayersID); + if (settings.hasKey(pngScaleID)) pngScale = settings.getDouble(pngScaleID); + if (settings.hasKey(groupsAsSkinsID)) groupsAsSkins = settings.getBoolean(groupsAsSkinsID); + if (settings.hasKey(useRulerOriginID)) useRulerOrigin = settings.getBoolean(useRulerOriginID); + if (settings.hasKey(imagesDirID)) imagesDir = settings.getString(imagesDirID); + if (settings.hasKey(projectDirID)) projectDir = settings.getString(projectDirID); + if (settings.hasKey(paddingID)) padding = settings.getDouble(paddingID); +} + +function saveSettings () { + var settings = new ActionDescriptor(); + settings.putBoolean(writePngsID, writePngs); + settings.putBoolean(writeTemplateID, writeTemplate); + settings.putBoolean(writeJsonID, writeJson); + settings.putBoolean(ignoreHiddenLayersID, ignoreHiddenLayers); + settings.putDouble(pngScaleID, pngScale); + settings.putBoolean(groupsAsSkinsID, groupsAsSkins); + settings.putBoolean(useRulerOriginID, useRulerOrigin); + settings.putString(imagesDirID, imagesDir); + settings.putString(projectDirID, projectDir); + settings.putDouble(paddingID, padding); + app.putCustomOptions(settingsID, settings, true); +} + +// Photoshop utility: + +function scaleImage () { + var imageSize = activeDocument.width.as("px"); + activeDocument.resizeImage(UnitValue(imageSize * pngScale, "px"), null, null, ResampleMethod.BICUBICSHARPER); +} + +var historyIndex; +function storeHistory () { + historyIndex = activeDocument.historyStates.length - 1; +} +function restoreHistory () { + activeDocument.activeHistoryState = activeDocument.historyStates[historyIndex]; +} + +function collectLayers (layer, collect) { + for (var i = 0, n = layer.layers.length; i < n; i++) { + var child = layer.layers[i]; + if (ignoreHiddenLayers && !child.visible) continue; + if (child.bounds[2] == 0 && child.bounds[3] == 0) continue; + if (child.layers && child.layers.length > 0) + collectLayers(child, collect); + else if (child.kind == LayerKind.NORMAL) { + collect.push(child); + child.visible = false; + } + } +} + +function hasFilePath () { + var ref = new ActionReference(); + ref.putEnumerated(charIDToTypeID("Dcmn"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt")); + return executeActionGet(ref).hasKey(stringIDToTypeID("fileReference")); +} + +function absolutePath (path) { + path = trim(path); + if (path.length == 0) + path = activeDocument.path.toString(); + else if (imagesDir.indexOf("./") == 0) + path = activeDocument.path + path.substring(1); + path = path.replace(/\\/g, "/"); + if (path.substring(path.length - 1) != "/") path += "/"; + return path; +} + +// JavaScript utility: + +function countAssocArray (obj) { + var count = 0; + for (var key in obj) + if (obj.hasOwnProperty(key)) count++; + return count; +} + +function trim (value) { + return value.replace(/^\s+|\s+$/g, ""); +} + +function endsWith (str, suffix) { + return str.indexOf(suffix, str.length - suffix.length) !== -1; +} + +function stripSuffix (str, suffix) { + if (endsWith(str.toLowerCase(), suffix.toLowerCase())) str = str.substring(0, str.length - suffix.length); + return str; +} + +function layerName (layer) { + return stripSuffix(trim(layer.name), ".png").replace(/[:\/\\*\?\"\<\>\|]/g, ""); +} diff --git a/Spine插件/LayersToPNG旧版.jsx b/Spine插件/LayersToPNG旧版.jsx new file mode 100644 index 0000000..dd1ccb9 --- /dev/null +++ b/Spine插件/LayersToPNG旧版.jsx @@ -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(); +}