Copy link to clipboard
Copied
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!
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++
...Copy link to clipboard
Copied
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
{
updateOpacity(layers
}
}
}
test();
Copy link to clipboard
Copied
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];
Copy link to clipboard
Copied
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.
Copy link to clipboard
Copied
Ill try that out now. If that's the case it will save immense time compared to renél80416020's method.
Copy link to clipboard
Copied
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.
Copy link to clipboard
Copied
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();
Copy link to clipboard
Copied
I found the error. I was missing 10 and "," after each line.
This works perfectly!
Thanks!
Copy link to clipboard
Copied
Digging through some other code i found another set of code you wrote that i want to implement with this.
- var docRef = app.activeDocument;
- var paths = docRef.pathItems;
- for (i=0; i< paths.length; i++){
- if (paths.fillColor.tint == 50 && paths.opacity == 100){
- paths.fillColor.tint = 100;
- paths.opacity = 50;
- }
- else if (paths.fillColor.tint == 100 && paths.opacity == 50){
- paths.fillColor.tint = 50;
- paths.opacity = 100;
- }
- }
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!
Copy link to clipboard
Copied
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.
Copy link to clipboard
Copied
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!
Copy link to clipboard
Copied
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.
Copy link to clipboard
Copied
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.
Copy link to clipboard
Copied
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.
Copy link to clipboard
Copied
Is it possible to add gradientStops.Opacity to the updateOpacity(item) as well or is that a whole bunch more code needed?
Copy link to clipboard
Copied
** 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.
Copy link to clipboard
Copied
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!
Copy link to clipboard
Copied
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();
Copy link to clipboard
Copied
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();
Copy link to clipboard
Copied
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.
Copy link to clipboard
Copied
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.
Copy link to clipboard
Copied
i'm also fascinated to learn the methodology behind your opacity relationships... what's the pattern??
Copy link to clipboard
Copied
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.
Copy link to clipboard
Copied
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
Copy link to clipboard
Copied
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!
Find more inspiration, events, and resources on the new Adobe Community
Explore Now