el-j
Community Beginner
el-j
Community Beginner
Activity
‎Dec 20, 2024
08:27 AM
so nice! here the latest version with some nice updates 😉 added little options: - for scaling (sadly just for plain paths) - to have a bit margins between the artboards - named artboards after symbolnames with number indicator infront (for easy export with nice names ;)) // Initialize variables
var doc1 = null;
// Conversion functions - 1:1 since Illustrator uses 72ppi where 1pt = 1px
function pxToPt(px) { return px; }
function ptToPx(pt) { return pt; }
// Check if any document is open
if (app.documents.length > 0) {
doc1 = app.activeDocument;
}
// Create dialog window
var dialog = new Window("dialog", "Symbol Export Settings");
dialog.orientation = "column";
// Add file selection group
var fileGroup = dialog.add("panel", undefined, "Source File");
fileGroup.orientation = "column";
fileGroup.alignChildren = "left";
var useCurrentRb = fileGroup.add("radiobutton", undefined, "Use Current Document");
var chooseFileRb = fileGroup.add("radiobutton", undefined, "Choose AI File");
// Set initial state based on document availability
if (doc1 === null) {
useCurrentRb.enabled = false;
chooseFileRb.value = true;
} else {
useCurrentRb.value = true;
useCurrentRb.enabled = true;
}
var chooseGroup = fileGroup.add("group");
var filePathText = chooseGroup.add("edittext", undefined, "");
filePathText.preferredSize.width = 200;
var chooseBtn = chooseGroup.add("button", undefined, "Browse...");
// Set initial state of file selection controls
filePathText.enabled = (doc1 === null);
chooseBtn.enabled = (doc1 === null);
// Enable/disable file selection based on radio button
chooseFileRb.onClick = function() {
filePathText.enabled = chooseFileRb.value;
chooseBtn.enabled = chooseFileRb.value;
}
useCurrentRb.onClick = function() {
filePathText.enabled = false;
chooseBtn.enabled = false;
}
// Browse button functionality
chooseBtn.onClick = function() {
var file = File.openDialog("Select Illustrator File", "*.ai");
if (file) {
filePathText.text = file.fsName;
// Open file and update symbol list
try {
var tempDoc = app.open(file);
updateSymbolList(tempDoc);
tempDoc.close(SaveOptions.DONOTSAVECHANGES);
} catch(e) {
alert("Could not open file: " + e);
}
}
}
// Add symbol size input (now in pixels)
var sizeGroup = dialog.add("group");
sizeGroup.add("statictext", undefined, "Symbol Size (px):");
var symbolSizeInput = sizeGroup.add("edittext", undefined, "64"); // Default 64px instead of 50pt
symbolSizeInput.characters = 6;
var explainScale = dialog.add("group");
explainScale.add("statictext", undefined, "(!!! needs plain Paths, NO STROCK or EFFECT SCALEING !!!");
// Add margin input (now in pixels)
var marginGroup = dialog.add("group");
marginGroup.add("statictext", undefined, "Margin (px):");
var marginInput = marginGroup.add("edittext", undefined, "24"); // Default 24px instead of 20pt
marginInput.characters = 6;
// Add symbol selection list
var listGroup = dialog.add("group");
listGroup.orientation = "column";
listGroup.alignChildren = "fill";
listGroup.add("statictext", undefined, "Select Symbols to Export:");
// Create selection list
var symbolList = listGroup.add("listbox", undefined, [], {multiselect: true});
symbolList.preferredSize.width = 300;
symbolList.preferredSize.height = 200;
// Function to populate symbol list
function updateSymbolList(sourceDoc) {
symbolList.removeAll(); // Clear existing items
for (var i = 0; i < sourceDoc.symbols.length; i++) {
var item = symbolList.add("item", sourceDoc.symbols[i].name);
item.selected = true;
}
}
// Initialize list with current document symbols only if we have one
if (doc1 !== null) {
updateSymbolList(doc1);
}
// Add Select All/None buttons
var selectGroup = dialog.add("group");
var selectAll = selectGroup.add("button", undefined, "Select All");
var selectNone = selectGroup.add("button", undefined, "Select None");
selectAll.onClick = function() {
for (var i = 0; i < symbolList.items.length; i++) {
symbolList.items[i].selected = true;
}
}
selectNone.onClick = function() {
for (var i = 0; i < symbolList.items.length; i++) {
symbolList.items[i].selected = false;
}
}
// Add buttons
var buttons = dialog.add("group");
buttons.add("button", undefined, "OK");
buttons.add("button", undefined, "Cancel");
// Show dialog
if (dialog.show() == 1) { // OK was pressed
// Get the source document
var doc1;
if (chooseFileRb.value) {
if (filePathText.text) {
try {
doc1 = app.open(File(filePathText.text));
} catch(e) {
alert("Could not open file: " + e);
exit();
}
} else {
alert("Please select a file first!");
exit();
}
} else {
doc1 = app.activeDocument;
}
// Convert pixel values to points for Illustrator
var symbolSize = pxToPt(Number(symbolSizeInput.text));
var margin = pxToPt(Number(marginInput.text));
// Get selected symbols
var selectedSymbols = [];
for (var i = 0; i < symbolList.items.length; i++) {
if (symbolList.items[i].selected) {
selectedSymbols.push(doc1.symbols[i]);
}
}
// Layout only selected symbols (using point values internally)
var x = 0, y = 0, row = 1;
for (var i = 0; i < selectedSymbols.length; i++) {
symbolItem1 = doc1.symbolItems.add(selectedSymbols[i]);
// Get original dimensions
var originalBounds = symbolItem1.geometricBounds;
var originalWidth = originalBounds[2] - originalBounds[0];
var originalHeight = originalBounds[1] - originalBounds[3];
// Calculate scale percentage
var scalePercentage = (symbolSize / Math.max(originalWidth, originalHeight)) * 100;
// Position first, then scale
symbolItem1.left = x;
symbolItem1.top = y;
// Scale with stroke preservation
symbolItem1.selected = true;
app.executeMenuCommand('expandStyle'); // Expand appearance first
app.executeMenuCommand('expandStyle'); // Sometimes needs two passes
// Scale the expanded item
symbolItem1.resize(
scalePercentage, // x percentage
scalePercentage, // y percentage
true, // transform patterns
true, // transform gradients
true, // transform stroke patterns
true // transform linewidths
);
if (i < (10 * row) - 1) {
x += symbolSize + margin;
} else {
x = 0;
y -= symbolSize + margin;
row++;
}
}
// Copy to new document
app.copy();
// Create new document with same settings as source
var preset = new DocumentPreset();
preset.colorMode = doc1.documentColorSpace;
preset.units = doc1.rulerUnits;
preset.width = 800;
preset.height = 600;
var doc2 = app.documents.addDocument(doc1.documentColorSpace, preset);
// Remove default swatches and symbols (if any)
while(doc2.symbols.length > 0) {
doc2.symbols[0].remove();
}
app.paste();
// Create artboards from symbols and match names
for (var k = 0; k < doc2.symbolItems.length; k++){
var currentSymbolItem = doc2.symbolItems[k];
// Find matching symbol from selected symbols by comparing names
var matchingSymbol = null;
for (var s = 0; s < selectedSymbols.length; s++) {
if (currentSymbolItem.symbol.name === selectedSymbols[s].name) {
matchingSymbol = selectedSymbols[s];
break;
}
}
var newArtboard = doc2.artboards.add(currentSymbolItem.visibleBounds);
if (matchingSymbol) {
newArtboard.name = (k + 1) + "_" + matchingSymbol.name;
} else {
newArtboard.name = (k + 1) + "_unknown";
}
}
doc2.artboards[0].remove()
if (chooseFileRb.value) {
doc1.close(SaveOptions.DONOTSAVECHANGES);
}
} else {
// User cancelled
alert("Export cancelled");
}
... View more
‎Dec 20, 2024
06:32 AM
one little issue is the pt to px conversion, it has factor what i wrong for illstrator // Conversion functions
function pxToPt(px) { return px }
function ptToPx(pt) { return pt }
... View more
‎Dec 20, 2024
06:23 AM
thank u @femkeblanco! very good starting point. i did some more extras so size and padding also documentinput and the items that should be processed can be choosen when script is loaded. also i made sure no color-conversion happens. // Initialize variables
var doc1 = null;
// Check if any document is open
if (app.documents.length > 0) {
doc1 = app.activeDocument;
}
// Conversion functions
function pxToPt(px) { return px * 0.75; }
function ptToPx(pt) { return pt / 0.75; }
// Create dialog window
var dialog = new Window("dialog", "Symbol Export Settings");
dialog.orientation = "column";
// Add file selection group
var fileGroup = dialog.add("panel", undefined, "Source File");
fileGroup.orientation = "column";
fileGroup.alignChildren = "left";
var useCurrentRb = fileGroup.add("radiobutton", undefined, "Use Current Document");
var chooseFileRb = fileGroup.add("radiobutton", undefined, "Choose AI File");
// Set initial state based on document availability
if (doc1 === null) {
useCurrentRb.enabled = false;
chooseFileRb.value = true;
} else {
useCurrentRb.value = true;
useCurrentRb.enabled = true;
}
var chooseGroup = fileGroup.add("group");
var filePathText = chooseGroup.add("edittext", undefined, "");
filePathText.preferredSize.width = 200;
var chooseBtn = chooseGroup.add("button", undefined, "Browse...");
// Set initial state of file selection controls
filePathText.enabled = (doc1 === null);
chooseBtn.enabled = (doc1 === null);
// Enable/disable file selection based on radio button
chooseFileRb.onClick = function() {
filePathText.enabled = chooseFileRb.value;
chooseBtn.enabled = chooseFileRb.value;
}
useCurrentRb.onClick = function() {
filePathText.enabled = false;
chooseBtn.enabled = false;
}
// Browse button functionality
chooseBtn.onClick = function() {
var file = File.openDialog("Select Illustrator File", "*.ai");
if (file) {
filePathText.text = file.fsName;
// Open file and update symbol list
try {
var tempDoc = app.open(file);
updateSymbolList(tempDoc);
tempDoc.close(SaveOptions.DONOTSAVECHANGES);
} catch(e) {
alert("Could not open file: " + e);
}
}
}
// Add symbol size input (now in pixels)
var sizeGroup = dialog.add("group");
sizeGroup.add("statictext", undefined, "Symbol Size (px):");
var symbolSizeInput = sizeGroup.add("edittext", undefined, "64"); // Default 64px instead of 50pt
symbolSizeInput.characters = 6;
// Add margin input (now in pixels)
var marginGroup = dialog.add("group");
marginGroup.add("statictext", undefined, "Margin (px):");
var marginInput = marginGroup.add("edittext", undefined, "24"); // Default 24px instead of 20pt
marginInput.characters = 6;
// Add symbol selection list
var listGroup = dialog.add("group");
listGroup.orientation = "column";
listGroup.alignChildren = "fill";
listGroup.add("statictext", undefined, "Select Symbols to Export:");
// Create selection list
var symbolList = listGroup.add("listbox", undefined, [], {multiselect: true});
symbolList.preferredSize.width = 300;
symbolList.preferredSize.height = 200;
// Function to populate symbol list
function updateSymbolList(sourceDoc) {
symbolList.removeAll(); // Clear existing items
for (var i = 0; i < sourceDoc.symbols.length; i++) {
var item = symbolList.add("item", sourceDoc.symbols[i].name);
item.selected = true;
}
}
// Initialize list with current document symbols only if we have one
if (doc1 !== null) {
updateSymbolList(doc1);
}
// Add Select All/None buttons
var selectGroup = dialog.add("group");
var selectAll = selectGroup.add("button", undefined, "Select All");
var selectNone = selectGroup.add("button", undefined, "Select None");
selectAll.onClick = function() {
for (var i = 0; i < symbolList.items.length; i++) {
symbolList.items[i].selected = true;
}
}
selectNone.onClick = function() {
for (var i = 0; i < symbolList.items.length; i++) {
symbolList.items[i].selected = false;
}
}
// Add buttons
var buttons = dialog.add("group");
buttons.add("button", undefined, "OK");
buttons.add("button", undefined, "Cancel");
// Show dialog
if (dialog.show() == 1) { // OK was pressed
// Get the source document
var doc1;
if (chooseFileRb.value) {
if (filePathText.text) {
try {
doc1 = app.open(File(filePathText.text));
} catch(e) {
alert("Could not open file: " + e);
exit();
}
} else {
alert("Please select a file first!");
exit();
}
} else {
doc1 = app.activeDocument;
}
// Convert pixel values to points for Illustrator
var symbolSize = pxToPt(Number(symbolSizeInput.text));
var margin = pxToPt(Number(marginInput.text));
// Get selected symbols
var selectedSymbols = [];
for (var i = 0; i < symbolList.items.length; i++) {
if (symbolList.items[i].selected) {
selectedSymbols.push(doc1.symbols[i]);
}
}
// Layout only selected symbols (using point values internally)
var x = 0, y = 0, row = 1;
for (var i = 0; i < selectedSymbols.length; i++) {
symbolItem1 = doc1.symbolItems.add(selectedSymbols[i]);
symbolItem1.left = x;
symbolItem1.top = y;
symbolItem1.width = symbolSize;
symbolItem1.height = symbolSize;
symbolItem1.selected = true;
if (i < (10 * row) - 1) {
x += symbolSize + margin;
} else {
x = 0;
y -= symbolSize + margin;
row++;
}
}
// Copy to new document
app.copy();
// Create new document with same settings as source
var preset = new DocumentPreset();
preset.colorMode = doc1.documentColorSpace;
preset.units = doc1.rulerUnits;
preset.width = 800;
preset.height = 600;
var doc2 = app.documents.addDocument(doc1.documentColorSpace, preset);
// Remove default swatches and symbols (if any)
while(doc2.symbols.length > 0) {
doc2.symbols[0].remove();
}
app.paste();
// Create artboards from symbols and match names
for (var k = 0; k < doc2.symbolItems.length; k++){
var currentSymbolItem = doc2.symbolItems[k];
// Find matching symbol from selected symbols by comparing names
var matchingSymbol = null;
for (var s = 0; s < selectedSymbols.length; s++) {
if (currentSymbolItem.symbol.name === selectedSymbols[s].name) {
matchingSymbol = selectedSymbols[s];
break;
}
}
var newArtboard = doc2.artboards.add(currentSymbolItem.visibleBounds);
if (matchingSymbol) {
newArtboard.name = (k + 1) + "_" + matchingSymbol.name;
} else {
newArtboard.name = (k + 1) + "_unknown";
}
}
doc2.artboards[0].remove()
if (chooseFileRb.value) {
doc1.close(SaveOptions.DONOTSAVECHANGES);
}
} else {
// User cancelled
alert("Export cancelled");
}
... View more