Skip to main content
ecommarci
Participant
August 26, 2022
Answered

Select a global color swatch and change its CMYK color code

  • August 26, 2022
  • 2 replies
  • 1321 views

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!

 

 

 

This topic has been closed for replies.
Correct answer femkeblanco

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;

 

2 replies

m1b
Community Expert
Community Expert
August 26, 2022

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

ecommarci
ecommarciAuthor
Participant
August 27, 2022

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

femkeblanco
femkeblancoCorrect answer
Legend
August 27, 2022

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;

 

Charu Rajput
Community Expert
Community Expert
August 26, 2022

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);

 

Best regards
femkeblanco
Legend
August 26, 2022

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". 

Charu Rajput
Community Expert
Community Expert
August 26, 2022

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.

 

 

Best regards