Last active
February 25, 2024 16:33
-
-
Save gepatto/d19ad3eb1b5fd004ff5ecca73a8a6d2d to your computer and use it in GitHub Desktop.
Illustrator script: Create Duplicates of Selected group in a grid fitting inside a specified area setting it text to values from an array
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* @author Patrick Gutlich | |
* @year 2024 | |
* @description Create Duplicates of Selected group in a grid fitting inside a specified area setting it text to values from an array | |
*/ | |
/** | |
* Helpers | |
*/ | |
function cmToPoints(cm) { | |
return cm * 28.3464567; | |
} | |
function pointsToCm(pt) { | |
return pt * 0.035277776; | |
} | |
function trim(s) { | |
return String(s).replace(/^\s+|\s+$/gm, ""); | |
} | |
function firstWord(s) { | |
return String(s).split(" ")[0]; | |
} | |
// Variables | |
var doc; | |
var documentMarginX = 8; | |
var documentMarginY = 8; | |
var areaWidth = 40; // default value | |
var areaHeight = 30; // default value | |
var spacingHorizontal = 8; | |
var spacingVertical = 8; | |
var red = new RGBColor(); | |
red.red = 255; | |
red.green = 0; | |
red.blue = 0; | |
var noColor = new NoColor(); | |
var names = [ | |
"foo","bar","dodo" | |
]; | |
var fontIndex; | |
var fontNames_array = []; | |
var fontSize = 24; | |
var fontName = "Nobel-Bold"; //preferred font | |
var font; | |
// populate font_names array and find the index of preferred font; | |
// so it can be slected in the font dropdown | |
for (var t = 0; t < app.textFonts.length; t++) { | |
fontNames_array.push(app.textFonts[t].name); | |
if (fontNames_array[t] == fontName) { | |
fontIndex = t; | |
} | |
} | |
var original; // selected object to duplicate | |
var originalName = ""; // given name of selected object | |
var textTarget; // the textframe to fill with value of the array | |
var sizeWarning = false; | |
// UI Variables, make them global for easy access | |
var dialog; | |
var mainGroup; | |
var dimensionsGroup; | |
var originalPanel; | |
var originalwidthrow; | |
var lblOriginalwidth; | |
var txtOriginalWidth; | |
var originalheightrow; | |
var lblOriginalheight; | |
var txtOriginalHeight; | |
var panelArea; | |
var areaWidthGroup; | |
var lblAreareaWidth; | |
var txtAreaWidth; | |
var areaHeightGroup; | |
var lblAreaheight; | |
var txtAreaHeight; | |
var textGroup; | |
var textPanel; | |
var txtNames; | |
var chkTrimSpaces; | |
var chkFirstWord; | |
var fontPanel; | |
var chkOverrideFont; | |
var fontOverridesGroup; | |
var lblFontFamily; | |
var lstFontNames; | |
var fontsizeGroup; | |
var lblFontsize; | |
var txtFontSize; | |
var btnGroup; | |
var btnCreate; | |
/** | |
* CREATE DUPLICATES | |
*/ | |
function createDuplicates() { | |
if (original == null) { | |
// by now orginal should not be null, but check it anyway | |
alert("No object selected"); | |
} else { | |
// are there any textFrames in the selected object, if so select the first one. | |
if (original.textFrames.length > 0) { | |
textTarget = original.textFrames[0]; | |
} | |
// make a new group to hold the duplicates | |
var duplicatesGroup = doc.groupItems.add(doc, ElementPlacement.PLACEBEFORE); | |
duplicatesGroup.name = "duplicates group"; | |
var cols = Math.floor(areaWidth / (original.width + spacingHorizontal)); | |
if(fontName!="" && fontName!=undefined){ | |
font = app.textFonts.getByName(fontName); | |
} | |
if (font == null) { | |
font = app.textFonts[0] ; | |
} | |
for (var i = 0; i < names.length; i++) { | |
var j = i + 1; //leave original intact | |
var xPos = | |
original.position[0] + | |
(j % cols) * (original.width + spacingHorizontal); | |
var yPos = | |
original.position[1] - | |
Math.floor(j / cols) * (original.height + spacingVertical); | |
var duplicateObject = original.duplicate( | |
duplicatesGroup, | |
ElementPlacement.PLACEATEND | |
); | |
duplicateObject.name = originalName + "_" + j; | |
duplicateObject.position = [xPos, yPos]; | |
duplicateObject.stroked = true; | |
duplicateObject.strokeWidth = 0.01; | |
duplicateObject.strokeColor = red; | |
duplicateObject.fillColor = noColor; | |
textTarget = duplicateObject.textFrames[0]; | |
if (textTarget != undefined) { | |
textTarget.contents = chkFirstWord.value | |
? firstWord(names[i]) | |
: trim(names[i]); | |
if (chkOverrideFont.value) { | |
textTarget.textRange.characterAttributes.textFont = font; | |
textTarget.textRange.characterAttributes.size = fontSize; | |
} | |
} else { | |
// if there is no textFrame let's add one and center it | |
var myTextFrame = duplicatesGroup.textFrames.add(); | |
myTextFrame.contents = trim(names[i]); | |
myTextFrame.textRange.characterAttributes.textFont = font; | |
myTextFrame.textRange.characterAttributes.size = fontSize; | |
myTextFrame.position = [ | |
xPos + (original.width - myTextFrame.width) * 0.5, | |
yPos - (original.height - myTextFrame.height) * 0.5, | |
]; | |
} | |
if(textTarget.width > original.width || textTarget.height > original.height){ | |
sizeWarning = true; | |
textTarget.textRange.characterAttributes.fillColor = red; | |
} | |
} | |
if( sizeWarning ){ | |
alert("Some texts exceed the area of the original\n They are colored red"); | |
} | |
} | |
} | |
/** | |
* CREATE DIALOG UI | |
*/ | |
function createDialog() { | |
// CREATE DIALOG | |
// ====== | |
dialog = new Window("dialog"); | |
dialog.text = "Original Creator"; | |
//ialog.orientation = "column"; | |
dialog.alignChildren = ["center", "top"]; | |
dialog.spacing = 16; | |
dialog.margins = 16; | |
// MAINGROUP | |
// ========= | |
mainGroup = dialog.add("group", undefined, { name: "mainGroup" }); | |
mainGroup.orientation = "column"; | |
mainGroup.alignChildren = ["left", "center"]; | |
mainGroup.spacing = 8; | |
mainGroup.margins = 4; | |
// DIMENSIONSGROUP | |
// =============== | |
dimensionsGroup = mainGroup.add("group", undefined, {name: "dimensionsGroup"}); | |
dimensionsGroup.orientation = "row"; | |
dimensionsGroup.alignChildren = ["center", "center"]; | |
dimensionsGroup.spacing = 10; | |
dimensionsGroup.margins = 4; | |
dimensionsGroup.alignment = ["fill", "center"]; | |
// ORIGINALPANEL | |
// ========== | |
originalPanel = dimensionsGroup.add("panel", undefined, undefined, {name: "originalPanel"}); | |
originalPanel.text = "Selected Original (cm)"; | |
originalPanel.preferredSize.width = 201; | |
originalPanel.orientation = "column"; | |
originalPanel.alignChildren = ["right", "top"]; | |
originalPanel.spacing = 10; | |
originalPanel.margins = 16; | |
originalPanel.alignment = ["center", "fill"]; | |
// ORIGINALWIDTHROW | |
// ============= | |
originalwidthrow = originalPanel.add("group", undefined, {name: "originalwidthrow"}); | |
originalwidthrow.orientation = "row"; | |
originalwidthrow.alignChildren = ["left", "center"]; | |
originalwidthrow.spacing = 10; | |
originalwidthrow.margins = 0; | |
lblOriginalwidth = originalwidthrow.add("statictext", undefined, undefined, {name: "lblOriginalwidth"}); | |
lblOriginalwidth.text = "Width"; | |
txtOriginalWidth = originalwidthrow.add('edittext {properties: {name: "originalWidth", "readonly":true}}'); | |
txtOriginalWidth.text = pointsToCm(original.width); | |
txtOriginalWidth.preferredSize.width = 120; | |
// ORIGINALHEIGHTROW | |
// ============== | |
originalheightrow = originalPanel.add("group", undefined, {name: "originalheightrow"}); | |
originalheightrow.orientation = "row"; | |
originalheightrow.alignChildren = ["left", "center"]; | |
originalheightrow.spacing = 10; | |
originalheightrow.margins = 0; | |
lblOriginalheight = originalheightrow.add("statictext", undefined,undefined,{ name: "lblOriginalheight" }); | |
lblOriginalheight.text = "Height"; | |
txtOriginalHeight = originalheightrow.add('edittext {properties: {name: "originalHeight","readonly":true}}'); | |
txtOriginalHeight.text = pointsToCm(original.height); | |
txtOriginalHeight.preferredSize.width = 120; | |
// PANELAREA | |
// ========= | |
panelArea = dimensionsGroup.add("panel", undefined, undefined, {name: "panelArea"}); | |
panelArea.text = "Bounding Area (cm)"; | |
panelArea.orientation = "column"; | |
panelArea.alignChildren = ["right", "top"]; | |
panelArea.spacing = 10; | |
panelArea.margins = 16; | |
panelArea.alignment = ["center", "fill"]; | |
// areaWidthGroup | |
// ====== | |
areaWidthGroup = panelArea.add("group", undefined, {name: "areaWidthGroup"}); | |
areaWidthGroup.orientation = "row"; | |
areaWidthGroup.alignChildren = ["left", "center"]; | |
areaWidthGroup.spacing = 10; | |
areaWidthGroup.margins = 0; | |
lblAreareaWidth = areaWidthGroup.add("statictext", undefined, undefined, {name: "lblAreareaWidth"}); | |
lblAreareaWidth.text = "Width"; | |
txtAreaWidth = areaWidthGroup.add('edittext {justify: "right", properties: {name: "areaWidth"}}'); | |
txtAreaWidth.text = parseFloat(areaWidth).toFixed(2); | |
txtAreaWidth.preferredSize.width = 62; | |
// areaHeightGroup | |
// ======= | |
areaHeightGroup = panelArea.add("group", undefined, {name: "areaHeightGroup"}); | |
areaHeightGroup.orientation = "row"; | |
areaHeightGroup.alignChildren = ["left", "center"]; | |
areaHeightGroup.spacing = 10; | |
areaHeightGroup.margins = 0; | |
lblAreaheight = areaHeightGroup.add("statictext", undefined, undefined, {name: "lblAreaheight"}); | |
lblAreaheight.text = "Height"; | |
txtAreaHeight = areaHeightGroup.add('edittext {justify: "right", properties: {name: "areaHeight"}}'); | |
txtAreaHeight.text = parseFloat(areaHeight).toFixed(2);; | |
txtAreaHeight.preferredSize.width = 62; | |
// TEXTGROUP | |
// ========= | |
textGroup = mainGroup.add("group", undefined, { name: "textGroup" }); | |
textGroup.orientation = "column"; | |
textGroup.alignChildren = ["center", "center"]; | |
textGroup.spacing = 12; | |
textGroup.margins = 0; | |
textGroup.alignment = ["fill", "center"]; | |
// TEXTPANEL | |
// ========= | |
textPanel = textGroup.add("panel", undefined, undefined, {name: "textPanel"}); | |
textPanel.text = "Names"; | |
textPanel.orientation = "column"; | |
textPanel.alignChildren = ["fill", "top"]; | |
textPanel.spacing = 10; | |
textPanel.margins = 16; | |
textPanel.alignment = ["fill", "center"]; | |
txtNames = textPanel.add("edittext {properties: {name: names , multiline: true, scrollable: true }}"); | |
txtNames.helpTip = "comma separated names "; | |
txtNames.text = names.join(","); | |
txtNames.preferredSize.height = 128; | |
chkTrimSpaces = textPanel.add("checkbox", undefined, undefined, {name: "trimSpaces"}); | |
chkTrimSpaces.text = "Trim Spaces"; | |
chkTrimSpaces.value = true; | |
chkFirstWord = textPanel.add("checkbox", undefined, undefined, {name: "firstWord"}); | |
chkFirstWord.text = "First Word Only"; | |
chkFirstWord.value = true; | |
// FONTPANEL | |
// ========= | |
fontPanel = textGroup.add("panel", undefined, undefined, {name: "fontPanel"}); | |
fontPanel.text = "Font"; | |
fontPanel.orientation = "column"; | |
fontPanel.alignChildren = ["fill", "top"]; | |
fontPanel.spacing = 10; | |
fontPanel.margins = 16; | |
fontPanel.alignment = ["fill", "center"]; | |
chkOverrideFont = fontPanel.add("checkbox", undefined, undefined, {name: "overrideFont"}); | |
chkOverrideFont.text = "Override Font"; | |
chkOverrideFont.value = false; | |
chkOverrideFont.onClick = function () { | |
fontOverridesGroup.enabled = chkOverrideFont.value; | |
}; | |
fontOverridesGroup = fontPanel.add("group", undefined, { name: "overrides" }); | |
fontOverridesGroup.orientation = "column"; | |
fontOverridesGroup.alignChildren = ["fill", "top"]; | |
fontOverridesGroup.enabled = chkOverrideFont.value; | |
lblFontFamily = fontOverridesGroup.add("statictext", undefined, undefined, {name: "lblFontFamily"}); | |
lblFontFamily.text = "FontFamily"; | |
lstFontNames = fontOverridesGroup.add("dropdownlist", undefined, undefined, {name: "fontName", items: fontNames_array}); | |
lstFontNames.selection = fontIndex; | |
fontName = lstFontNames.selection; | |
lstFontNames.onChange = function () { | |
fontName = lstFontNames.selection; | |
}; | |
// FONTSIZEGROUP | |
// ============= | |
fontsizeGroup = fontOverridesGroup.add("group", undefined, {name: "fontsizeGroup"}); | |
fontsizeGroup.orientation = "row"; | |
fontsizeGroup.alignChildren = ["right", "center"]; | |
fontsizeGroup.spacing = 10; | |
fontsizeGroup.alignment = ["left", "top"]; | |
lblFontsize = fontsizeGroup.add("statictext", undefined, undefined, {name: "lblFontsize"}); | |
lblFontsize.text = "Font Size (points)"; | |
txtFontSize = fontsizeGroup.add('edittext {properties: {name: "fontSize"}}'); | |
txtFontSize.text = fontSize; | |
txtFontSize.preferredSize.width = 65; | |
txtFontSize.alignment = ["right", "center"]; | |
// BTNGROUP | |
// ======== | |
btnGroup = mainGroup.add("group", undefined, { name: "btnGroup" }); | |
btnGroup.orientation = "column"; | |
btnGroup.alignChildren = ["center", "center"]; | |
btnGroup.spacing = 10; | |
btnGroup.margins = 0; | |
btnGroup.alignment = ["center", "center"]; | |
btnCreate = btnGroup.add("button", undefined, undefined, {name: "btnCreate"}); | |
btnCreate.text = "Create"; | |
btnCreate.onClick = function () { | |
areaWidth = cmToPoints(parseFloat(txtAreaWidth.text)); | |
areaHeight = cmToPoints(parseFloat(txtAreaHeight.text)); | |
fontSize = parseFloat(txtFontSize.text); | |
names = txtNames.text.split(","); | |
layer = doc.layers[0]; | |
createDuplicates(); | |
dialog.close(); | |
}; | |
} | |
// Check if there is an open docuement | |
doc = app.activeDocument; | |
if (doc != null) { | |
areaWidth = pointsToCm(doc.width); | |
areaHeight = pointsToCm(doc.height); | |
// Check if there is something selected | |
original = app.activeDocument.selection[0]; | |
if (original != undefined) { | |
originalName = original.name; //store the name of the selected object | |
//original.name = "original_" + original.name; | |
createDialog(); | |
dialog.show(); | |
} else { | |
alert("Select a group in an open document"); | |
} | |
} else { | |
alert("Select a group in an open document"); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment