Copy link to clipboard
Copied
I'd like to assign a color to a selection based on the selection name (or any other variable). How do I do that? I tried defining a color and giving it the selection name but AI VSCode says "Object expected".
1 Correct answer
You need to assign a fillColor a color object, not a name. How you target your item depends on your needs.
To assign a selected item a color:
app.selection[0].fillColor = Bar;
A selection element won't accept a string identifier. So if you want to target a selected item by name, you will have to iterate through the selection collection and test for the name:
for (var i = 0; i < app.selection.length; i++) {
if (app.selection[i].name == "Something") {
app.selection[i].fillColor = Bar;
...
Explore related tutorials & articles
Copy link to clipboard
Copied
You need to assign a fillColor a color object, not a name. How you target your item depends on your needs.
To assign a selected item a color:
app.selection[0].fillColor = Bar;
A selection element won't accept a string identifier. So if you want to target a selected item by name, you will have to iterate through the selection collection and test for the name:
for (var i = 0; i < app.selection.length; i++) {
if (app.selection[i].name == "Something") {
app.selection[i].fillColor = Bar;
}
}
But in your case the above only applies if you are specifically selecting members of groups. The selection collection contains only top level items (i.e. only the group), so it won't contain members of groups. If you are targeting a member of a group by name, do you need it selected?
setCustomCrop()
function setCustomCrop() {
var aDoc = app.activeDocument;
var CropGroup = aDoc.groupItems['CropGroup'];
var myItems = CropGroup.pageItems;
var myMask = myItems["Something"];
myMask.fillColor = Bar;
// ...
}
Copy link to clipboard
Copied
Thanks, @femkeblanco .
Yes, the artist will have an selected. That item name should be used to assign the color. Your solution works perfectly! I have 5 named color possibilities. Does that mean I need to add 4 "else if" statements to iterate through all the possibilites?
EDIT:
I realized since I have a single item selected the "for" loop is not needed. This now works:
function setCustomCrop() {
var aDoc = app.activeDocument;
var selMask = selection[0];
customCrop = selMask.name;
var CropGroup = aDoc.groupItems['CropGroup'];
var myItem = CropGroup.pageItems;
var myMask = myItem[customCrop];
myMask.locked = false;
if (selMask.name == "Bar") {
selMask.fillColor = Bar;
} else if (selMask.name == "Round") {
selMask.fillColor = Round;
} else if (selMask.name == "Heart") {
selMask.fillColor = Heart;
} else if (selMask.name == "SmallHeart") {
selMask.fillColor = SmallHeart;
} else if (selMask.name == "LargeHeart") {
selMask.fillColor = LargeHeart;
}
…
Copy link to clipboard
Copied
Hi Craig, we could make this a bit more dynamic and less reliant on the hard-coded values for selMask.fillColor assignment and name checking. Consider this:
// Store all our colors in a global object with key values matching mask names:
var masks = {
Bar: createRGB(255, 0, 0),
Round: createRGB(0, 255, 0),
Heart: createRGB(0, 0, 255)
}
// Create a simple utility function to allow us to more easily make RGB colors:
function createRGB(red, green, blue) {
var temp = new RGBColor();
temp.red = red;
temp.green = green;
temp.blue = blue;
return temp;
}
// Now we dynamically retreive all our key mask names:
var keys = [];
for (var key in masks) keys.push(key);
// And create a RegEx to check them:
var maskRX = new RegExp("^(" + keys.join("|") + ")$");
// Equivalent to /^(Bar|Round|Heart)$/
function setCustomCrop() {
var aDoc = app.activeDocument;
var selMask = selection[0];
customCrop = selMask.name;
var CropGroup = aDoc.groupItems['CropGroup'];
var myItem = CropGroup.pageItems;
var myMask = myItem[customCrop];
myMask.locked = false;
// If the name matches our RegEx above:
if (maskRX.test(selMask.name))
selMask.fillColor = masks[selMask.name]
// ^ We use the name to match the color from our masks variable
/**
* No need for long ternary chains and makes our code more dynamic
* because adding a new mask is as simple as adding:
*
* SmallHeart: createRGB(150, 50, 50)
*
* In the original "masks" variable at the top.
*/
}
In ES6 this would be much easier:
let maskRX = new RegExp(`^(${Object.keys(masks).join("|")})$`);
I mention this mostly because the more we rely on static or hard-coded values, the more opportunities we have to get errors on typos and misspellings, and the more modifications you'd have to make to the script in multiple locations if you were to change one of these variable names or add/remove them. Doing this in a dynamic way has a bit of an overhead cost but afterwards can save a lot of time and energy maintaining it later on, because I can now have any number of masks all neatly organized in the "masks" variable.
Copy link to clipboard
Copied
I hope you don't mind me piggybacking on this post because my question is very similar. I'm making a card game for my students, and the card text is linked to a CSV using variables. In my Illustrator file, I have a rectangle with a stroke (and no fill) as the card border (let's call this "border"), and another rectangle with a fill (and no stroke) as the card title background (let's call this "background"). I want these colours to be determined by the variable called "CONTINENT", which also determines the card title text (i.e. "Europe", "Asia", "Africa", "Americas", "Oceania"), and to be interpreted as specific CMYK values.
I've tried my hand at modifying your script, but I'm a complete novice when it comes to Illustrator scripting (and to JS in general), so I don't really know what I'm doing. (TBH, I don't even know how to run the script in Illustrator.) I'd be very grateful if you could lend your support.
// Store all our colors in a global object with key values matching CONTINENT names:
var continents = {
Europe: createCMYK(100, 40, 0, 0),
Americas: createCMYK(0, 95, 90, 0),
Africa: createCMYK(0, 0, 0, 100),
Asia: createCMYK(0, 35, 100, 0),
Oceania: createCMYK(100, 0, 100, 0)
}
// Create a simple utility function to allow us to more easily make CMYK colors:
function createCMYK(cyan, magenta, yellow, black) {
var temp = new CMYKColor();
temp.cyan = cyan;
temp.magenta = magenta;
temp.yellow = yellow;
temp.black = black;
return temp;
}
// Now we dynamically retreive all our key CONTINENT names:
var keys = [];
for (var key in continents) keys.push(key);
// And create a RegEx to check them:
var continentRX = new RegExp("^(" + keys.join("|") + ")$");
// Equivalent to /^(Europe|Americas|Asia|Oceania|Africa)$/
// TJWD note: I'm really not sure how to modify this part...
function setCustomCrop() {
var aDoc = app.activeDocument;
var selMask = selection[0];
customCrop = selMask.name;
var CropGroup = aDoc.groupItems['CropGroup'];
var myItem = CropGroup.pageItems;
var myMask = myItem[customCrop];
myMask.locked = false;
// If the name matches our RegEx above:
if (maskRX.test(selMask.name))
selMask.fillColor = continents[selMask.name]
// ^ We use the name to match the color from our continents variable
}

