Copy link to clipboard
Copied
Hi guys,
I am new to Illustrator development, but I need to find a solution for a problem, that an illustrator developer I hired couldn't solve.
That's the issue:
I have an illustrator file, where you can find different global colors (swatches).
Let's say we have 3 of them. Their names are:
- global color 1
- global color 2
- global color 3
I want to build a script that allows me to select one of those colors by the name of the global color and change its CMYK color code.
The logic should be like this (the syntax is arbitrary, because I have never built an illustrator script myself):
const gc1 = getElementByGlobalColorName('global color 1')
gc1.changeCMYKcolorCode('20,
50,50,30')
After running that script, the color code of the global color 'global color 1' should change to:
Cyan = 20
Magenta = 50
Yellow = 50
Key = 30
The global color 1 needs to remain a global color. All objects/elements/layers that are connected to the global color 1 (and therefore have the same color as global color 1), should change their color as well (I think that's nothing the script should do, but it's a side-effect of Illustrator itself.)
If I select the global color 1 afterwards and change the color code manually, the linking between the objects/elements/layers and the global color should still be available.
I hope my lack of syntax and incorrect coding language will not confuse you. I appreciate any help a lot and would pay for a solution.
Thanks guys!
Hi @ecommarci, I read your question a little differently to the other answerers. Here is my interpretation:
var doc = app.activeDocument;
setGlobalCMYKColor(doc, 'CMYK Red', 50, 50, 20, 0);
/**
* Set the color breakdown
* of a global CMYK swatch.
* @param {Document} doc - an Illustrator Document.
* @param {String} colorName - the swatch name.
* @param {Number} C - the cyan value 0-100.
* @param {Number} M - the magenta value 0-100.
* @param {Number} Y - the yellow value 0-100.
* @para
...
When testing @m1b's script last night, I noticed that I had a problem with getByName(). I put it down to a peculiarity of my version of Illustrator. The script works fine using bracket notation. By the off chance that you have a similar problem, you could try changing the fifth line to
var c = doc.swatches[colorName].color.spot.color;
Copy link to clipboard
Copied
Hello,
Below is the version where the color value of the swatch is changed and also, the object that have Global Color 1 applied as fill or stroke color, will also get updated
docRef = app.activeDocument;
function getElementByGlobalColorName(colorName) {
try {
return docRef.swatches.getByName(colorName);
} catch (e) {
return null;
}
}
function changeCMYKcolorCode(colorObj) {
var _swatch = getElementByGlobalColorName('Global Color 1');
if (_swatch != null) {
app.executeMenuCommand('deselectall');
docRef.defaultFillColor = _swatch.color;
app.executeMenuCommand('Find Fill & Stroke menu item');
var _newColor = new CMYKColor();
_newColor.cyan = colorObj.C;
_newColor.magenta = colorObj.M;
_newColor.yellow = colorObj.Y;
_newColor.black = colorObj.K;
_swatch.color = _newColor;
docRef.defaultFillColor = _newColor
app.executeMenuCommand('deselectall');
}
}
var _newColorObj = {
C: 20,
M: 50,
Y: 50,
K: 30
}
changeCMYKcolorCode(_newColorObj);
Copy link to clipboard
Copied
Hi @Charu Rajput Correct me if I am wrong, but for the script to work (1) the swatch has to be selected (or an item has to be selected) and (2) the stroke and fill have to be the same color (the menu command will find items with the same stroke and fill).
Edit: I didn't see "defaultFillColor".
Copy link to clipboard
Copied
Hi @femkeblanco ,
1. No, it is not mandatory to have a swatch or item as selected because, I am getting the swatch by name and also, I am using the command to deselect if anything is selected before.
2. I did not get your 2nd question completely, what I am doing here I am selecting all the items that uses Global Color 1 as a stroke or fill color. But I did more testing and find that abover version not work when both fill and stroke are set.
So below is the upadated version.
docRef = app.activeDocument;
function getElementByGlobalColorName(colorName) {
try {
return docRef.swatches.getByName(colorName);
} catch (e) {
return null;
}
}
function changeCMYKcolorCode(colorObj) {
var _swatch = getElementByGlobalColorName('Global Color 1');
if (_swatch != null) {
app.executeMenuCommand('deselectall');
var _newColor = new CMYKColor();
_newColor.cyan = colorObj.C;
_newColor.magenta = colorObj.M;
_newColor.yellow = colorObj.Y;
_newColor.black = colorObj.K;
// For fill color
docRef.defaultFillColor = _swatch.color;
app.executeMenuCommand('Find Fill Color menu item');
docRef.defaultFillColor = _newColor;
// For Stroke;
docRef.defaultStrokeColor = _swatch.color;
app.executeMenuCommand('Find Stroke Color menu item');
docRef.defaultStrokeColor = _newColor;
_swatch.color = _newColor;
app.executeMenuCommand('deselectall');
}
}
var _newColorObj = {
C: 20,
M: 50,
Y: 50,
K: 30
}
changeCMYKcolorCode(_newColorObj);
So, first changing fill color of the objects, then stoke color of the objects and then the actual color of the swatch in the Swatches panel.
Copy link to clipboard
Copied
The updated version works fine. Thanks.
Copy link to clipboard
Copied
Hi there,
Thanks a lot for your script and the time you put in.
The colors do change, but there is a problem: the global color "global color 1" will not be a global color anymore. It's changed from global to "normal". The problem with that is, that all objects that are linked to that color are not linked anymore.
For example, let's say we have 3 blue rectangles that are linked to "global color 1" (which is also blue). If I change global color 1 to red, all 3 rectangles are getting red, too. When I run the script, the color also changes from for example blue to red. The only problem here is if I now change the global color 1 to yellow (manually), the rectangles' colors do not change (because "global color 1" is not global anymore).
Is there a way to keep the global colors globally after changing them?
Before running the script:
After running the script:
Thanks in advance! š
Copy link to clipboard
Copied
Hi @ecommarci, I read your question a little differently to the other answerers. Here is my interpretation:
var doc = app.activeDocument;
setGlobalCMYKColor(doc, 'CMYK Red', 50, 50, 20, 0);
/**
* Set the color breakdown
* of a global CMYK swatch.
* @param {Document} doc - an Illustrator Document.
* @param {String} colorName - the swatch name.
* @param {Number} C - the cyan value 0-100.
* @param {Number} M - the magenta value 0-100.
* @param {Number} Y - the yellow value 0-100.
* @param {Number} K - the black value 0-100.
*/
function setGlobalCMYKColor(doc, colorName, C, M, Y, K) {
try {
var c = doc.swatches.getByName(colorName).color.spot.color;
if (C != undefined) c.cyan = C;
if (M != undefined) c.magenta = M;
if (Y != undefined) c.yellow = Y;
if (K != undefined) c.black = K;
} catch (e) { }
}
This simply sets the color values of the global swatch. If any of the arguments C, M, Y, or K are undefined, it will leave that value alone.
- Mark
Copy link to clipboard
Copied
Hi Mark,
Thank you a lot for taking the time to answer. You read my question properly. š
If you have another minute, I'd appreciate it if you could have a look over the following:
I edited your script by adding "test" as the color name (and defined a global color with the name "test").
The color of the test swatch didn't change after running the script, so I added a few alerts to find out what happened.
My script looks like the following now (I removed your comments and the if functions so that it's clearer:
var doc = app.activeDocument;
setGlobalCMYKColor(doc, 'test', 10, 50, 50, 10);
function setGlobalCMYKColor(doc, colorName, C, M, Y, K) {
try {
var c = doc.swatches.getByName(colorName).color.spot.color;
// Let's see if we are in the right document [result (true): "[Test 2022-08-27.ai]"]
alert(doc)
// Let's check if the colorName is the correct one [result (true): "test"]
alert(colorName);
// Find out what "c" actually is [result (true): "[CMYKColor]"]
alert(c);
// If the code works, we should get the initial color code here [result (true): "48 0 100 0"]
alert(c.cyan + " " + c.magenta + " " + c.yellow + " " + c.black);
//let's change the colors of c and check for the cyan color if it works [result (true): "10"]
c.cyan = C;
alert(c.cyan);
c.magenta = M;
c.yellow = Y;
c.black = K;
//since the color itself doesn't change, but the alert results are as expected, I tried to select the global color by its name again [result (false): "48"]
alert(doc.swatches.getByName(colorName).color.spot.color.cyan)
//now, let's check to directly select the element, change its cyan color and check the result [result (false): "48"]
doc.swatches.getByName(colorName).color.spot.color.cyan = 10;
alert(doc.swatches.getByName(colorName).color.spot.color.cyan);
} catch (e) { alert ("An error occurred")}
}
Here, I'll send a screenshot of the global color:
Do you have an idea why changing the color codes after selecting the swatches doesn't work?
Thanks a lot for any effort you put into this!
Best regards
Marcel
Copy link to clipboard
Copied
When testing @m1b's script last night, I noticed that I had a problem with getByName(). I put it down to a peculiarity of my version of Illustrator. The script works fine using bracket notation. By the off chance that you have a similar problem, you could try changing the fifth line to
var c = doc.swatches[colorName].color.spot.color;
Copy link to clipboard
Copied
@femkeblanco incredible! It works - thanks a lot! š