Exit
  • Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
  • 한국 커뮤니티
0

Select object based on its opacity and change opacity to set value.

Participant ,
Aug 06, 2018 Aug 06, 2018

I am trying to create some javascript code but cannot find any references online relating to this specific instance.

What i am attempting to do is have the script find an object(s) based on its opacity in the transparency window and then if it is 80% i want to change it to be 60%.

This would be done for every opacity value from 99% to 1% and then changing it to a specific value.

Any thoughts on where to start?

Thanks!

TOPICS
Scripting
3.6K
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 1 Correct answer

Community Expert , Aug 06, 2018 Aug 06, 2018

function test()

{

    var docRef = app.activeDocument;

    var layers = docRef.layers;

    var opacityRelationships = {

        "80": 60

        //put in the rest of your relationships here

        //left side is the current opacity of an object

        //right side is what you want to change it to

    }

    function updateOpacity(item)

    {

        var curOpacity = Math.floor(item.opacity).toString();

        item.opacity = opacityRelationships[curOpacity];

    }

    for(var x=0,len = layers.length;x<len;x++

...
Translate
Adobe
Community Expert ,
Aug 06, 2018 Aug 06, 2018

function test()

{

    var docRef = app.activeDocument;

    var layers = docRef.layers;

    var opacityRelationships = {

        "80": 60

        //put in the rest of your relationships here

        //left side is the current opacity of an object

        //right side is what you want to change it to

    }

    function updateOpacity(item)

    {

        var curOpacity = Math.floor(item.opacity).toString();

        item.opacity = opacityRelationships[curOpacity];

    }

    for(var x=0,len = layers.length;x<len;x++)

    {

        for(var y=0,yLen = layers.pageItems.length;y<yLen;y++)

        {

            updateOpacity(layers.pageItems);

        }

    }

}

test();

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Participant ,
Aug 06, 2018 Aug 06, 2018

Getting an error on "item.opacity = opacityRelationships[curOpacity];" Says "Numeric value expected".

Edit* is it due to this code referencing itself?:

  var curOpacity = Math.floor(item.opacity).toString();

       item.opacity = opacityRelationships[curOpacity];

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Aug 06, 2018 Aug 06, 2018

that error message was because it encountered an item that had an opacity that you had not yet written into the opacityRelationships object. Therefore, it was trying to set the item.opacity to "undefined".

renél80416020's method is good, but it has numbers hard coded into the changeOpacity function which makes it not every versatile. To use that method, you'll either need to add a ton of if/else statements to handle every possibility, or employ some kind of data structure like i did.

my method did indeed reference itself, it uses the current opacity of the given object to find the new desired opacity. But that in itself won't cause an error. I put a comment to let you know where you should fill out the rest of your desired relationships.

Alternatively, instead of hard coding the relationships, we can create a mathematical relationship instead.. for example, if you want to decrement the opacity by 20%, we can just write an equation and leave out the data structure all together.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Participant ,
Aug 06, 2018 Aug 06, 2018

Ill try that out now. If that's the case it will save immense time compared to renél80416020's method.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Aug 06, 2018 Aug 06, 2018

it's always a good idea to write as little code as possible. With the working example you posted, you have two separate functions that are identical except for the "before" and "after" variables. Assuming you had 20 more relationships.. that means you have 22 copies of the exact same function and only the o1 and o2 variables are different. next lets assume that you realize you need to make a change to the function.. perhaps you wanted to change the opacity AND rename the object for some reason. now you have to make that change 22 separate times.

but if you use one function and just pass in some data, you can make one change that applies to everything.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Participant ,
Aug 06, 2018 Aug 06, 2018

Trying this out with all possible values of opacity with just random values to change them to and i am getting the error "Expected: }" on "99": 40.

My code looks like

function test()

{

    var docRef = app.activeDocument;

    var layers = docRef.layers;

    var opacityRelationships = {

        "100": 100

        "99": 40

        "98": 40

        "97": 60

        "96": 40

        "95": 40

        "94": 60

        "93": 40

        "92": 40

        "91": 60

        "90": 40

        "89": 40

        "88": 40

        "87": 60

        "86": 40

        "85": 40

        "84": 60

        "83": 40

        "82": 40

        "81": 60

        "80": 40

        "79": 40

        "78": 40

        "77": 60

        "76": 40

        "75": 40

        "74": 60

        "73": 40

        "72": 40

        "71": 60

        "70": 40

        "69": 40

        "68": 40

        "67": 60

        "66": 40

        "65": 40

        "64": 60

        "63": 40

        "62": 40

        "61": 60

        "60": 40

        "59": 40

        "58": 40

        "57": 60

        "56": 40

        "55": 40

        "54": 60

        "53": 40

        "52": 40

        "51": 60

        "50": 40

        "49": 40

        "48": 40

        "47": 60

        "46": 40

        "45": 40

        "44": 60

        "43": 40

        "42": 40

        "41": 60

        "40": 40

        "39": 40

        "38": 40

        "37": 60

        "36": 40

        "35": 40

        "34": 60

        "33": 40

        "32": 40

        "31": 60

        "30": 40

        "29": 40

        "28": 40

        "27": 60

        "26": 40

        "25": 40

        "24": 60

        "23": 40

        "22": 40

        "21": 60

        "20": 40

        "19": 40

        "18": 40

        "17": 60

        "16": 40

        "15": 40

        "14": 60

        "13": 40

        "12": 40

        "11": 60

        "9": 40

        "8": 40

        "7": 60

        "6": 40

        "5": 40

        "4": 60

        "3": 40

        "2": 40

        "1": 60

        "0": 0

        //put in the rest of your relationships here

        //left side is the current opacity of an object

        //right side is what you want to change it to

    }

    function updateOpacity(item)

    {

        var curOpacity = Math.floor(item.opacity).toString();

        item.opacity = opacityRelationships[curOpacity];

    }

    for(var x=0,len = layers.length;x<len;x++)

    {

        for(var y=0,yLen = layers.pageItems.length;y<yLen;y++)

        {

            updateOpacity(layers.pageItems);

        }

    }

}

test();

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Participant ,
Aug 06, 2018 Aug 06, 2018

I found the error. I was missing 10 and "," after each line.

This works perfectly!


Thanks!

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Participant ,
Aug 06, 2018 Aug 06, 2018

Digging through some other code i found another set of code you wrote that i want to implement with this.

  1. var docRef = app.activeDocument; 
  2. var paths = docRef.pathItems; 
  3.  
  4.  
  5. for (i=0; i< paths.length; i++){ 
  6.     if (paths.fillColor.tint == 50 && paths.opacity == 100){ 
  7.         paths.fillColor.tint = 100
  8.         paths.opacity = 50
  9.          
  10.         } 
  11.     else if (paths.fillColor.tint == 100 && paths.opacity == 50){ 
  12.         paths.fillColor.tint = 50
  13.         paths.opacity = 100
  14.         
  15.         } 
  16.     } 

How can i add this in with what we currently have?

Ive been playing with the curOpacity and item.opacity within the variables of 50 and 100.


Thanks again though for all your help!

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Aug 06, 2018 Aug 06, 2018

what exactly do you want to do with the tint? like, what are the rules that you want to follow?

implementing the tint changes into this code makes things significantly more complex. because opacity is an available property of basically any object inside illustrator.. but tint is only a property of a pathItem, and only when that pathItem is filled with a spot color.

In order to implement tint, we will need to build a recursive loop to dig inside groupItems to find any instance of a filled pathItem that has a certain tint.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Participant ,
Aug 06, 2018 Aug 06, 2018

The code you have from your other answer is exactly what i am looking for. Making anything that is tint go to 100% and set the opacity to what the tint was at. Then apply the referenced opacity relationships.

I've already begun the hard coding of the tint values to run prior to executing the opacity script.

Thanks for all your work!

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Aug 06, 2018 Aug 06, 2018

Ok. but what i'm trying to say is that it's probably not realistic to implement the tint portion of this into the same code for the opacity. because they will have to be set differently. consider this group of items:

Main Group (opacity: 50%) (fill color: not applicable) (tint: not applicable)

     pathItem (opacity: 100%) (fill color: My Spot Color) (tint: 50)

     groupItem (opacity: 75%) (fill color: not applicable) (tint: not applicable

          pathItem (opacity: 100%) (fill color: My Other Spot Color) (tint: 75)

          pathItem (opacity: 25%) (fill color: My Third Spot Color) (tint: 100)

the function i wrote for you earlier would update the opacity of "Main Group" as a whole, but it would ignore all of the subItems. We cannot use the same function to also update the tint, because "tint" is not a property of groupItem. So in order to access the tint property of each sub item, we need to build a recursive loop to dig into the groupItem and find all of it's child elements until we access all of the pathItems.

If we do that, then it breaks the function i already wrote for you because then the opacities of the child elements will be changed also, instead of only changing the parent group's opacity.

These tasks should be treated separately.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Aug 06, 2018 Aug 06, 2018

here. i went ahead and made an .ai file with the structure that I proposed. In case it was unclear..

woops. the first version i sent wasn't correct. here it is.

jake7732_example.ai - Google Drive

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Participant ,
Aug 06, 2018 Aug 06, 2018

I see what you are saying with them having to be both separate scripts.

Currently, i have it running the tint script to convert the tint to opacity and set the tint back to 100%.

Then i have it running the script above and it seems to all be working perfectly.

Just have to add in the gradient stops next.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Participant ,
Aug 07, 2018 Aug 07, 2018

Is it possible to add gradientStops.Opacity to the updateOpacity(item) as well or is that a whole bunch more code needed?

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Aug 07, 2018 Aug 07, 2018

** this is hogwash..**

i've never actually done any coding with gradients or gradientStops myself. But theoretically the answer is yes, we could do that. HOWEVER. we run into the same problem of "what kind of object is 'item'?"

In the initial code i wrote for you, item could be any pageItem. gradientStop is not going to be a sub property of groupItem, textFrame, placedItem, rasterItem etc.

** this is hogwash..**

Ok. you can basically ignore the above. i'll leave it in there just in case the thought process helps get a deeper understanding of the API. Turns out that a gradient is not a property of the item itself. it's a document property (just like a swatch or a spot color). So if you can identify an existing gradient in the document, you could add/remove/change gradient stops globally instead of inside the loop.

do you have access to the Scripting Reference for your version of illustrator? If not, you need to get it right away as it is an invaluable (though wildly incomplete) resource as it spells out the relationships between different elements of the DOM. (just don't spend too much time trying to make sense of the example code in there... for real, i have no idea who wrote those things or why they thought they'd be helpful..). If you do have it, do a search for Gradient, GradientColor and GradientStops. It gives you all you need to know about manipulating a gradient.

Then, so long as the items you want to update have that gradient applied to them, they should update on the fly.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Participant ,
Aug 07, 2018 Aug 07, 2018

Yeah I was experimenting with the var gradientRef = app.activeDocument.graident[1] but wasnt having any luck getting it to pull the curOpacity. I'll keep playing, thanks for the update!

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Aug 07, 2018 Aug 07, 2018

not sure if you copied and pasted or just made a typo when typing your message, but you misspelled "gradient" in your last post here.

try this:

var gradientRef = app.activeDocument.gradients[1]; //this assumes you have at least 2 gradients in your document already, otherwise you will get an error: "undefined is not an object"

i received the above error when i tested this because the document had no gradients in it. so i wrote this little test and it seemed to work great. hope it helps. (don't mind the extraneous variables. i have a snippet that just creates all kinds of things that i use frequently so i don't have to type them out every time.)

function test()

{

    var valid = true;

    var docRef = app.activeDocument;

    var layers = docRef.layers;

    var aB = docRef.artboards;

    var swatches = docRef.swatches;

    var obj = {};

    var arr = [];

    var newGradient = docRef.gradients.add();

        newGradient.name = "New Gradient";

    var gradient1 = docRef.gradients[0];

    alert(gradient1);

   

}

test();

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Participant ,
Aug 07, 2018 Aug 07, 2018

Oh man, finally on the right track. Gradients convert correctly, pops an error about undefined on line 127, but still runs correctly. Current code i have below:

function test()

{

    var docRef = app.activeDocument;

    var layers = docRef.layers;

    var paths = docRef.pathItems;

    var items = docRef.selection;

    var gradient1 = docRef.gradients; 

    var opacityRelationships = {

        "100": 100,

        "99": 40,

        "98": 40,

        "97": 60,

        "96": 40,

        "95": 40,

        "94": 60,

        "93": 40,

        "92": 40,

        "91": 60,

        "90": 40,

        "89": 40,

        "88": 40,

        "87": 60,

        "86": 40,

        "85": 40,

        "84": 60,

        "83": 40,

        "82": 40,

        "81": 60,

        "80": 40,

        "79": 40,

        "78": 40,

        "77": 60,

        "76": 40,

        "75": 40,

        "74": 60,

        "73": 40,

        "72": 40,

        "71": 60,

        "70": 40,

        "69": 40,

        "68": 40,

        "67": 60,

        "66": 40,

        "65": 40,

        "64": 60,

        "63": 40,

        "62": 40,

        "61": 60,

        "60": 40,

        "59": 40,

        "58": 40,

        "57": 60,

        "56": 40,

        "55": 40,

        "54": 60,

        "53": 40,

        "52": 40,

        "51": 60,

        "50": 40,

        "49": 40,

        "48": 40,

        "47": 60,

        "46": 40,

        "45": 40,

        "44": 60,

        "43": 40,

        "42": 40,

        "41": 60,

        "40": 40,

        "39": 40,

        "38": 40,

        "37": 60,

        "36": 40,

        "35": 40,

        "34": 60,

        "33": 40,

        "32": 40,

        "31": 60,

        "30": 40,

        "29": 40,

        "28": 40,

        "27": 60,

        "26": 40,

        "25": 40,

        "24": 60,

        "23": 40,

        "22": 40,

        "21": 60,

        "20": 40,

        "19": 40,

        "18": 40,

        "17": 60,

        "16": 40,

        "15": 40,

        "14": 60,

        "13": 40,

        "12": 40,

        "11": 60,

        "10": 60,

        "9": 40,

        "8": 40,

        "7": 60,

        "6": 40,

        "5": 40,

        "4": 60,

        "3": 40,

        "2": 40,

        "1": 60,

        "0": 0

    }

    function updateOpacity(item)

    {

        var curOpacity = Math.floor(item.opacity).toString();

        item.opacity = opacityRelationships[curOpacity];

    }

    for(var x=0,len = layers.length;x<len;x++)

    {

        for(var y=0,yLen = layers.pageItems.length;y<yLen;y++)

        {

            updateOpacity(layers.pageItems);

    }

    } 

     //this is for changing gradients

    for(var x=0,gs = paths.length;x<gs;x++)

    {

        for(var y=0,yGs = paths.fillColor.gradient.gradientStops.length;y<yGs;y++)

        {      

    updateOpacity(paths.fillColor.gradient.gradientStops);

}

}   

}

test();

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Aug 07, 2018 Aug 07, 2018

so if you have a pathItem in the document that has "My Gradient" applied to it. and you make a change to "My Gradient" that change isn't reflected in the pathItem? You have to have the pathItem selected while you make the global change?

just want to make sure i'm understanding the problem so i can better decide how to tackle it.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Participant ,
Aug 07, 2018 Aug 07, 2018

Hi,

You might have seen this before my edit. I switched everything over to paths.length, etc,  and it runs fine now. Just pops an undefined error on line 127 but finishes processing correctly.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Aug 06, 2018 Aug 06, 2018

i'm also fascinated to learn the methodology behind your opacity relationships... what's the pattern??

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Participant ,
Aug 06, 2018 Aug 06, 2018

Oh those are just random inputs for now just to ensure it was working. I am actually creating a script that automates the processing of art for screen printing from separating colors, setting colors, setting halftones based on opacity (this script), setting halftone per mesh count, etc.

Thank you so much again for your work, you have no idea how long i was staring at the guide trying to piece this all together.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Advocate ,
Aug 06, 2018 Aug 06, 2018

Salut !

// traite les tracés sélectionnés

function test() {

  var o1 = 80;

  var o2 = 60

    if (!selection.length) return;

    var sel = selection;

      function changeOpacity(items) {

          for(var n = 0; n < items.length; n++) {

            if (Math.round(items.opacity) == o1) {

              items.opacity = 60;

            }

          }

      }

      changeOpacity(sel);

}

if (app.documents.length) {test();}

de LR

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Participant ,
Aug 06, 2018 Aug 06, 2018

This does what i need if the individual object is selected already which is very helpful for getting me started but I am also looking for a way to auto select the similar opacity items and then modify them with the specific value. i'll play around with this a bit and update if i find any further info as well.

Thanks!

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines