Copy link to clipboard
Copied
Hi all,
I'm looking to change the fill colour of every selected item on an artboard.
This isn't the actual logo, just a mockup, but helps explain things...
The stars are grouped
UGH is outlined text (a compound path).
The black line is a rectangle
"Truly..." is editable text
"Wherever..." is also editable text.
I've been reading about compound paths being tricky to colour, but why is only one element being changed? My head hurts.
Can any kind soul help out?
var doc = app.activeDocument;
var ABs = doc.artboards;
ABs.setActiveArtboardIndex(178);
doc.selectObjectsOnActiveArtboard();
var setColor = new RGBColor();
setColor.red = 90;
setColor.green = 180;
setColor.blue = 180;
var pathItems = doc.selection;
for (var i = 0; i < pathItems.length; i++) {
pathItems[i].filled = true;
pathItems[i].fillColor = setColor;
}
Copy link to clipboard
Copied
...this is what changes when the script is run...
Copy link to clipboard
Copied
I presume you want to color everything the same color. The problem is that the "selection" collection consists of just the top level items, i.e. the first level in a hierarchy. If there are nested items (groups and compound paths, which could be of any depth), the pathItems you want to color will be the last level in the hierarchy. For example (these are just some possibilities)
// doc.pathItems[...].fillColor = setColor;
// doc.groupItems[...].pathItems[...].fillColor = setColor;
// doc.compoundPathItems[...].pathItems[...].fillColor = setColor;
// doc.groupItems[...].compoundPathItems[...].pathItems[...].fillColor = setColor;
The easier code to write, although it may be more difficult to visualise, uses recursion. This also covers every possibility. The alternative, if you know your hierarchy, would be a series of nested loops with a conditional before each loop testing for the item type. The method with recursion is shown below. For more on recursion, see here
Text frames have their owen syntax:
// doc.textFrames[...].textRange.fillColor = setColor;
One last note: "pathItems" is a name of a built-in collection. Don't use it as a variable name. Use "items" instead.
var doc = app.activeDocument;
var ABs = doc.artboards;
ABs.setActiveArtboardIndex(178);
doc.selectObjectsOnActiveArtboard();
var setColor = new RGBColor();
setColor.red = 90;
setColor.green = 180;
setColor.blue = 180;
var items = doc.selection;
var array = [];
recurse(items);
for (var i = 0; i < array.length; i++) {
array[i].filled = true;
array[i].fillColor = setColor;
}
function recurse(items) {
for (var i = 0; i < items.length; i++) {
if (items[i].typename == "TextFrame") {
items[i].textRange.fillColor = setColor;
} else if (items[i].typename == "PathItem") {
array.push(items[i]);
} else if (items[i].typename == "GroupItem") {
recurse(items[i].pageItems);
} else if (items[i].typename == "CompoundPathItem") {
recurse(items[i].pathItems);
}
}
}
Copy link to clipboard
Copied
Once again, thank you!
Your script was changing all text frames on all artboards, so I swapped this line:
doc.textFrames[i].textRange.fillColor = setColor;
to this:
doc.selection[i].textRange.fillColor = setColor;
Now it works perfectly.
Copy link to clipboard
Copied
My bad. It was originally inside recurse(), but I took it out to make it look easier. But two loops are unnecessary, so I've put it back in there.
Copy link to clipboard
Copied
That's great – I was getting an undefined object error in VSC but now it's gone. Integrating your script into a new one to check filenames first before changing colours.