Copy link to clipboard
Copied
Hello,
I'm looking to automate a process where I need to have a gradient fill layer modified. Is it possible to modify the Angle at which the linear gradient is applied. I know the values can go from 0-359 but is there a command to actually modify its value with one of the javascript command? I couldn't find any directly related to a gradient angle.
Thanks!
Have you used ScriptingListener.plugin to record the operation as AM code?
// 2022, use it at your own risk;
changeAngleOfGradientLayer (30);
function changeAngleOfGradientLayer (theAngle) {
try {
var idset = stringIDToTypeID( "set" );
var desc5 = new ActionDescriptor();
var idnull = stringIDToTypeID( "null" );
var ref1 = new ActionReference();
ref1.putEnumerated(stringIDToTypeID( "contentLayer" ), stringIDToTypeID( "ordinal" ), stringIDToTypeID( "targetEnum" ));
des
...
@Laethageal wrote:How would I pick a layer in a particular group?
Various methods are explored here:
https://gist.github.com/MarshySwamp/229a0676666a44cdaa007da1cfddc0b7
Copy link to clipboard
Copied
Have you used ScriptingListener.plugin to record the operation as AM code?
// 2022, use it at your own risk;
changeAngleOfGradientLayer (30);
function changeAngleOfGradientLayer (theAngle) {
try {
var idset = stringIDToTypeID( "set" );
var desc5 = new ActionDescriptor();
var idnull = stringIDToTypeID( "null" );
var ref1 = new ActionReference();
ref1.putEnumerated(stringIDToTypeID( "contentLayer" ), stringIDToTypeID( "ordinal" ), stringIDToTypeID( "targetEnum" ));
desc5.putReference( idnull, ref1 );
var idto = stringIDToTypeID( "to" );
var desc6 = new ActionDescriptor();
var idgradientsInterpolationMethod = stringIDToTypeID( "gradientsInterpolationMethod" );
var idgradientInterpolationMethodType = stringIDToTypeID( "gradientInterpolationMethodType" );
var idperceptual = stringIDToTypeID( "perceptual" );
desc6.putEnumerated( idgradientsInterpolationMethod, idgradientInterpolationMethodType, idperceptual );
var idangle = stringIDToTypeID( "angle" );
var idangleUnit = stringIDToTypeID( "angleUnit" );
desc6.putUnitDouble( idangle, idangleUnit, theAngle );
var idtype = stringIDToTypeID( "type" );
var idgradientType = stringIDToTypeID( "gradientType" );
var idlinear = stringIDToTypeID( "linear" );
desc6.putEnumerated( idtype, idgradientType, idlinear );
var idgradient = stringIDToTypeID( "gradient" );
var idgradientLayer = stringIDToTypeID( "gradientLayer" );
desc5.putObject( idto, idgradientLayer, desc6 );
executeAction( idset, desc5, DialogModes.NO );
} catch (e) {}
};
Copy link to clipboard
Copied
Sorry for the slow reply, new job came in and had to put my project on hold for a few days.
Also, thanks for the tip. I'm no javascript coder and still hardly get by modifying some basic commands on premade script to try and fit what I'm looking for, mostly by addition of some if/else check. I wasn't expecting something so complex 😉
From what I understand, this is the code that scriptlistener gave you when changing a gradient?
How would I pick a layer in a particular group?
Copy link to clipboard
Copied
Lots of ways to pick a layer: by name, by placement in the group, by type, or by index. What way are you looking for?
Copy link to clipboard
Copied
I have this code I am reusing from people on stackoverflow:
function Visible() {
var Grps = app.activeDocument.layerSets; // loops through all groups
for(var i = 0; i < Grps.length; i++){
var tmp = app.activeDocument.layerSets[i].layers.length;
app.activeDocument.layerSets[i].visible=true;
var groupChildArr = app.activeDocument.layerSets[i].layers;
var randLays = Math.floor(Math.random() * tmp);
groupChildArr[randLays].visible = true;
}
Save();
Revert();
}
The save() function was initially part of the "for(var..." loop but I realized it was saving a new version of t he same png until each group was done, saving itself 5 time (got 5 groups to pick from) for each png. Being a newbie at coding, I was proud finding this after reading the code multiple time to try and understand it.
Now, my group 4 is the group where gradient are stocked. 1 is picked randomly but I would like to add the degree variant to it. I was thinking adding a check in the loop so once it pick 1 of the gradient, it also randomize the degree.
function Visible() {
var Grps = app.activeDocument.layerSets; // loops through all groups
for(var i = 0; i < Grps.length; i++){
var tmp = app.activeDocument.layerSets[i].layers.length;
app.activeDocument.layerSets[i].visible=true;
var groupChildArr = app.activeDocument.layerSets[i].layers;
var randLays = Math.floor(Math.random() * tmp);
if ( i = 4 ) {
... code for modifying gradient degree of groupChildArr[randLays] ...
}
groupChildArr[randLays].visible = true;
}
Save();
Revert();
}
Does that make sense or am I crazy?
Copy link to clipboard
Copied
@Laethageal wrote:
Sorry for the slow reply, new job came in and had to put my project on hold for a few days.
15 days = a few days! 🙂
Copy link to clipboard
Copied
@Laethageal wrote:How would I pick a layer in a particular group?
Various methods are explored here:
https://gist.github.com/MarshySwamp/229a0676666a44cdaa007da1cfddc0b7
Copy link to clipboard
Copied
Thanks.
After seeing your teasing, I was on the defensive tbh. I had also posted right above the method I finally was able to use to select various layers, so I thought your answer was another teasing.
But I took 1 minute to check it out and it is actually some great information. I can't say I understand all the various form of coding, but some are easy to understand/use for me and as I learn more coding, I am pretty sure it'll be useful for me.
Thanks!
Would you happen to know how I can change the degree of the gradient when I already have code pointing to a particular gradient layer, as posted above?
function Visible() {
var Grps = app.activeDocument.layerSets; // loops through all groups
for(var i = 0; i < Grps.length; i++){
var tmp = app.activeDocument.layerSets[i].layers.length;
app.activeDocument.layerSets[i].visible=true;
var groupChildArr = app.activeDocument.layerSets[i].layers;
var randLays = Math.floor(Math.random() * tmp);
if ( i = 4 ) {
... code for modifying gradient degree of groupChildArr[randLays] ...
}
groupChildArr[randLays].visible = true;
}
Save();
Revert();
}
Copy link to clipboard
Copied
As c.pfaffenbichler mentioned, use scriptListener to record just changing the angle of a gradient. Then all you have to do is put in a variable for the value of the angle that you can change via code.
Copy link to clipboard
Copied
I tried looking at the code he gave, but this is coding complexity I'm not yet at.
I'm calling the layer by targeting it directly with something similar as :
app.activeDocument.layerSets[4].layers[2]
Can I replace the
stringIDToTypeID
with my call of the layer?
Copy link to clipboard
Copied
I don't have my computer, to check the script, but generally, no, you can't just replace stringIDtoType ID. That refers to a particular code. Stephen gave some examples of selecting the layer that you want. I would use that. Have the layer selected. Then use the scriptListener to record just an angle change for a gradient. That way the code generated will work on whatever layer is selected.
Copy link to clipboard
Copied
I'll try that, thanks.
Copy link to clipboard
Copied
@Laethageal wrote:
Thanks.
After seeing your teasing, I was on the defensive tbh. I had also posted right above the method I finally was able to use to select various layers, so I thought your answer was another teasing.
But I took 1 minute to check it out and it is actually some great information. I can't say I understand all the various form of coding, but some are easy to understand/use for me and as I learn more coding, I am pretty sure it'll be useful for me.
Thanks!
You will have to forgive my sense of humor. All of us are at different stages with scripting, I still class myself as a beginner. I just put it out there in case it was helpful. I have added your example to the gist. There is often a good chance that somebody has done what you wish to do before. I generally use the following "Active Layer Inspector" script to get info on the selected layer:
https://gist.github.com/MarshySwamp/ef345ef3dec60a843465347ee6fcae2f
Would you happen to know how I can change the degree of the gradient when I already have code pointing to a particular gradient layer, as posted above?
The other forum members have explained the process, this is what I came up with:
if (app.activeDocument.activeLayer.kind === LayerKind.GRADIENTFILL) {
gradAngle(-90);
function gradAngle(angle) {
var s2t = function (s) {
return app.stringIDToTypeID(s);
};
var descriptor = new ActionDescriptor();
var reference = new ActionReference();
reference.putEnumerated(s2t("contentLayer"), s2t("ordinal"), s2t("targetEnum"));
descriptor.putReference(s2t("null"), reference);
descriptor.putUnitDouble(s2t("angle"), s2t("angleUnit"), angle);
descriptor.putObject(s2t("to"), s2t("gradientLayer"), descriptor);
executeAction(s2t("set"), descriptor, DialogModes.NO);
}
} else {
alert("The active layer is not a Gradient Fill layer!")
}
I recorded changing the angle of an existing gradient fill layer via script listener, then through "targeted" trial and error removed the code that was not associated with the angle change, then ran the result through the Clean SL script and then added the conditional check.
EDIT: From the other topic, this modified code from jazz-y is cleaner than my attempt:
gradientLayerAngle(-90);
function gradientLayerAngle(theAngle) {
/* https://community.adobe.com/t5/photoshop-ecosystem-discussions/need-help-with-randomizing-gradient-fills/td-p/12349266 */
s2t = stringIDToTypeID;
(r = new ActionReference()).putEnumerated(s2t("contentLayer"), s2t("ordinal"), s2t("targetEnum"));
(d = new ActionDescriptor()).putReference(s2t("null"), r);
(d2 = new ActionDescriptor()).putUnitDouble(s2t("angle"), s2t("angleUnit"), theAngle);
d2.putEnumerated(s2t("type"), s2t("gradientType"), s2t("linear"));
d.putObject(s2t("to"), s2t("gradientLayer"), d2);
executeAction(s2t("set"), d, DialogModes.NO);
}
Copy link to clipboard
Copied
I just found the other topic thread where you posted, so a quick modification of the script provided by @jazz-y will randomize the selected gradient layer angle without changing other properties:
randomGradientLayerAngle();
function randomGradientLayerAngle() {
/* https://community.adobe.com/t5/photoshop-ecosystem-discussions/need-help-with-randomizing-gradient-fills/td-p/12349266 */
s2t = stringIDToTypeID;
(r = new ActionReference()).putEnumerated(s2t("contentLayer"), s2t("ordinal"), s2t("targetEnum"));
(d = new ActionDescriptor()).putReference(s2t("null"), r);
(d2 = new ActionDescriptor()).putUnitDouble(s2t("angle"), s2t("angleUnit"), Math.floor(Math.random() * 360));
d2.putEnumerated(s2t("type"), s2t("gradientType"), s2t("linear"));
d.putObject(s2t("to"), s2t("gradientLayer"), d2);
executeAction(s2t("set"), d, DialogModes.NO);
}
Copy link to clipboard
Copied
Thanks. His script did work but modified all color range and produced weird banding which I didn't like. I'll try the removal of color modification you did!
Don't mind how empty this is, I was testing having background group, text group and gradient group, while modifying the gradient only once and not once each time one of the group was displayed.
Started a new project with a few layer of number text to test out!
Copy link to clipboard
Copied
Here's the weird banding I get vs a normal gradient 1 color to nothing at about 80%
Copy link to clipboard
Copied
Looks like Noise Gradients.