Modifying a gradient fill with a script

Community Beginner ,
Mar 02, 2022 Mar 02, 2022

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!

Laethageal_0-1646272439318.png

 

 

TOPICS
Actions and scripting

Views

238

Likes

Translate

Translate

Report

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

Adobe Community Professional , 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...

Likes

Translate

Translate
Adobe Community Professional , 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

Likes

Translate

Translate
Adobe Community Professional ,
Mar 02, 2022 Mar 02, 2022

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

 

Likes

Translate

Translate

Report

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

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?





Likes

Translate

Translate

Report

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

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?

Likes

Translate

Translate

Report

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

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?

Likes

Translate

Translate

Report

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

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

Likes

Translate

Translate

Report

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

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

 

Likes

Translate

Translate

Report

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

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



Likes

Translate

Translate

Report

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

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. 

Likes

Translate

Translate

Report

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

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?

Likes

Translate

Translate

Report

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

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. 

Likes

Translate

Translate

Report

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

Copy link to clipboard

Copied

I'll try that, thanks.

Likes

Translate

Translate

Report

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

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

 

Likes

Translate

Translate

Report

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

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

 

Likes

Translate

Translate

Report

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

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!

Pattern_3.png

Likes

Translate

Translate

Report

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

Copy link to clipboard

Copied

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

Laethageal_0-1647911207949.png

 

Likes

Translate

Translate

Report

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
Adobe Community Professional ,
Mar 21, 2022 Mar 21, 2022

Copy link to clipboard

Copied

LATEST

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

 

Likes

Translate

Translate

Report

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