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

Modifying a gradient fill with a script

Community Beginner ,
Mar 02, 2022 Mar 02, 2022

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!

Laethageal_0-1646272439318.png

 

 

TOPICS
Actions and scripting
2.3K
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 2 Correct answers

Community Expert , Mar 02, 2022 Mar 02, 2022

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
...
Translate
Community Expert , Mar 18, 2022 Mar 18, 2022

@Laethageal wrote:

How would I pick a layer in a particular group?


 

Various methods are explored here:

 

https://gist.github.com/MarshySwamp/229a0676666a44cdaa007da1cfddc0b7

 

Translate
Adobe
Community Expert ,
Mar 02, 2022 Mar 02, 2022

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

 

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 Beginner ,
Mar 17, 2022 Mar 17, 2022

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?





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 ,
Mar 17, 2022 Mar 17, 2022

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?

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 Beginner ,
Mar 17, 2022 Mar 17, 2022

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?

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 ,
Mar 18, 2022 Mar 18, 2022

@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! 🙂

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 ,
Mar 18, 2022 Mar 18, 2022

@Laethageal wrote:

How would I pick a layer in a particular group?


 

Various methods are explored here:

 

https://gist.github.com/MarshySwamp/229a0676666a44cdaa007da1cfddc0b7

 

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 Beginner ,
Mar 18, 2022 Mar 18, 2022

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



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 ,
Mar 18, 2022 Mar 18, 2022

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. 

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 Beginner ,
Mar 18, 2022 Mar 18, 2022

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?

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 ,
Mar 18, 2022 Mar 18, 2022

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. 

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 Beginner ,
Mar 18, 2022 Mar 18, 2022

I'll try that, 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
Community Expert ,
Mar 18, 2022 Mar 18, 2022

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

 

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 ,
Mar 18, 2022 Mar 18, 2022

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

 

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 Beginner ,
Mar 21, 2022 Mar 21, 2022

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!

Pattern_3.png

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 Beginner ,
Mar 21, 2022 Mar 21, 2022

Here's the weird banding I get vs a normal gradient 1 color to nothing at about 80%

Laethageal_0-1647911207949.png

 

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 ,
Mar 21, 2022 Mar 21, 2022
LATEST

Looks like Noise Gradients. Screenshot 2022-03-22 at 07.54.57.png 

 

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