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

JavaScript to change the Gradient color

Participant ,
May 24, 2024 May 24, 2024

Copy link to clipboard

Copied

Hi,

I have this script that works perfectly fine. However, I have a new requirement to specifically target the gradient layers "Gradient Fill 1456" and "Gradient Fill 1459" within the designated layer groups. Additionally, the left Stop Color of these gradients should match the gradientColorInput color provided by the user.
Link to PSD: https://drive.google.com/file/d/1FlfauSXbxwKIXtAEGaxgxrMQoTy_P7aJ/view?usp=sharing 

Layer group name 1: Additional gradients (FOLDER opacity must not exceed 40%)
Gradient Layer name 1: Gradient Fill 1456

Layer group name 2: Crop Gradient (Don't use with other graident)
Gradient Layer name 2: Gradient Fill 1459

In the Gradient Layer 1 and 2, there's a gradient fill applied. The left Stop Color value in the gradient map should match the 'gradientColorInput' color (user Input as per the script).

 

 

function showDialog() {
  var dialog = new Window('dialog', 'Set Layer Group Colors');

  // Add checkboxes
  var gradientCheckbox = dialog.add('checkbox', undefined, 'Gradient');
  var gradientColorInput = dialog.add('edittext', undefined, '#FFFFFF');
  gradientColorInput.characters = 7;
  gradientColorInput.enabled = false; // Disable until checkbox is selected

  var accentColorCheckbox = dialog.add('checkbox', undefined, 'Accent Colour');
  var accentColorInput = dialog.add('edittext', undefined, '#FFFFFF');
  accentColorInput.characters = 7;
  accentColorInput.enabled = false; // Disable until checkbox is selected

  // Enable color inputs when checkboxes are selected
  gradientCheckbox.onClick = function() {
    gradientColorInput.enabled = gradientCheckbox.value;
  };
  accentColorCheckbox.onClick = function() {
    accentColorInput.enabled = accentColorCheckbox.value;
  };

  // Add buttons
  var buttons = dialog.add('group');
  buttons.alignment = 'right';
  buttons.add('button', undefined, 'OK', { name: 'ok' });
  buttons.add('button', undefined, 'Cancel', { name: 'cancel' });

  if (dialog.show() === 1) {
    var tasks = []; // Initialize tasks as an array
    if (gradientCheckbox.value) {
      tasks.push({ layerName: 'gradient', colorHex: gradientColorInput.text });
    }
    if (accentColorCheckbox.value) {
      tasks.push({
        layerName: 'accent colour',
        colorHex: accentColorInput.text
      });
    }
    // Loop through each task and apply settings
    for (var i = 0; i < tasks.length; i++) {
      activateLayersAndApplyAction(tasks[i].layerName, tasks[i].colorHex);
    }
  } else {
    dialog.close();
  }
}

function activateLayersAndApplyAction(layerName, hexColor) {
  var doc = app.activeDocument;
  var hex = hexColor.replace('#', '');
  if (hex.length !== 6 || !/^[\dA-Fa-f]{6}$/.test(hex)) {
    alert(
      'Invalid hex color for ' +
        layerName +
        '. Please enter a 6-digit hex color code.'
    );
    return;
  }
  var rValue = parseInt(hex.substring(0, 2), 16);
  var gValue = parseInt(hex.substring(2, 4), 16);
  var bValue = parseInt(hex.substring(4, 6), 16);
  var colorValues = { r: rValue, g: gValue, b: bValue };
  processLayers(doc, layerName.toLowerCase(), colorValues);
}

function processLayers(layerSet, layerName, colorValues) {
  if (!layerSet || !layerSet.layers) return;
  for (var i = 0; i < layerSet.layers.length; i++) {
    var layer = layerSet.layers[i];
    if (layer.typename === 'LayerSet') {
      if (layer.name.toLowerCase() === layerName) {
        var targetLayer = findLayerInGroup(layer, 'change me');
        if (targetLayer) {
          app.activeDocument.activeLayer = targetLayer;
          interactiveSetColorFill(targetLayer, colorValues);
        }
      }
      processLayers(layer, layerName, colorValues);
    }
  }
}

function findLayerInGroup(layerGroup, layerName) {
  for (var i = 0; i < layerGroup.layers.length; i++) {
    if (layerGroup.layers[i].name.toLowerCase() === layerName.toLowerCase()) {
      return layerGroup.layers[i];
    }
  }
  return null;
}

function interactiveSetColorFill(layer, colorValues) {
  var s2t = function(s) {
    return app.stringIDToTypeID(s);
  };
  var ref = new ActionReference();
  ref.putEnumerated(s2t('contentLayer'), s2t('ordinal'), s2t('targetEnum'));
  var desc = new ActionDescriptor();
  desc.putReference(s2t('null'), ref);

  var colorDesc = new ActionDescriptor();
  colorDesc.putDouble(s2t('red'), colorValues.r);
  colorDesc.putDouble(s2t('green'), colorValues.g);
  colorDesc.putDouble(s2t('blue'), colorValues.b);

  var listDesc = new ActionDescriptor();
  listDesc.putObject(s2t('color'), s2t('RGBColor'), colorDesc);
  desc.putObject(s2t('to'), s2t('solidColorLayer'), listDesc);

  executeAction(s2t('set'), desc, DialogModes.NO);
}

// Call the show dialog function to start the process
showDialog();

 

 

 

TOPICS
Actions and scripting

Views

462

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 1 Correct answer

Community Expert , May 27, 2024 May 27, 2024

Unless you learn UXP then the only other thing that I can think of is to find somebody that can run ScriptingListener and supply the required code.

 

Try to incorporate this into your existing code (you can ignore the first 3 variable lines as they were only there for testing as your code already has these variables):

 

rValue = 128;
gValue = 128;
bValue = 128;

selectLayer("Gradient Fill 1456", false);
var s2t = function (s) {
	return app.stringIDToTypeID(s);
};
var descriptor = new ActionDescr
...

Votes

Translate

Translate
Adobe
Community Expert ,
May 24, 2024 May 24, 2024

Copy link to clipboard

Copied

@Masood.Ahmad 

 

I would use ScriptingListener to record changing the colour on each separate gradient.

Votes

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 Expert ,
May 27, 2024 May 27, 2024

Copy link to clipboard

Copied

@Masood.Ahmad 

 

How did you go with the ScriptingListener plugin?

Votes

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
Participant ,
May 27, 2024 May 27, 2024

Copy link to clipboard

Copied

Thanks for the suggestions, Stephen, but the ScriptListener is outdated and is not supported for Photoshop 2023 on MAC OS 14.4.1 (23E224). Can you suggest some other thing or a script

Votes

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 Expert ,
May 27, 2024 May 27, 2024

Copy link to clipboard

Copied

Unless you learn UXP then the only other thing that I can think of is to find somebody that can run ScriptingListener and supply the required code.

 

Try to incorporate this into your existing code (you can ignore the first 3 variable lines as they were only there for testing as your code already has these variables):

 

rValue = 128;
gValue = 128;
bValue = 128;

selectLayer("Gradient Fill 1456", false);
var s2t = function (s) {
	return app.stringIDToTypeID(s);
};
var descriptor = new ActionDescriptor();
var descriptor2 = new ActionDescriptor();
var descriptor3 = new ActionDescriptor();
var descriptor4 = new ActionDescriptor();
var descriptor5 = new ActionDescriptor();
var descriptor6 = new ActionDescriptor();
var descriptor7 = new ActionDescriptor();
var descriptor8 = new ActionDescriptor();
var list = new ActionList();
var list2 = new ActionList();
var reference = new ActionReference();
reference.putEnumerated( s2t( "contentLayer" ), s2t( "ordinal" ), s2t( "targetEnum" ));
descriptor.putReference( s2t( "null" ), reference );
descriptor2.putUnitDouble( s2t( "angle" ), s2t( "angleUnit" ), 80.000000 );
descriptor2.putEnumerated( s2t( "type" ), s2t( "gradientType" ), s2t( "linear" ));
descriptor2.putUnitDouble( s2t( "scale" ), s2t( "percentUnit" ), 30.000000 );
descriptor3.putUnitDouble( s2t( "horizontal" ), s2t( "percentUnit" ), 3.626562 );
descriptor3.putUnitDouble( s2t( "vertical" ), s2t( "percentUnit" ), 0.334317 );
descriptor2.putObject( s2t( "offset" ), s2t( "paint" ), descriptor3 );
descriptor4.putString( s2t( "name" ), "Custom" );
descriptor4.putEnumerated( s2t( "gradientForm" ), s2t( "gradientForm" ), s2t( "customStops" ));
descriptor4.putDouble(s2t("interfaceIconFrameDimmed"), 4096.000000);
// RGB Values
descriptor6.putDouble( s2t( "red" ), rValue );
descriptor6.putDouble( s2t( "grain" ), gValue );
descriptor6.putDouble(s2t("blue"), bValue);
//
descriptor5.putObject( s2t( "color" ), s2t( "RGBColor" ), descriptor6 );
descriptor5.putEnumerated( s2t( "type" ), s2t( "colorStopType" ), s2t( "userStop" ));
descriptor5.putInteger( s2t( "location" ), 0 );
descriptor5.putInteger( s2t( "midpoint" ), 50 );
list.putObject( s2t( "colorStop" ), descriptor5 );
descriptor4.putList( s2t( "colors" ), list );
descriptor7.putUnitDouble( s2t( "opacity" ), s2t( "percentUnit" ), 100.000000 );
descriptor7.putInteger( s2t( "location" ), 0 );
descriptor7.putInteger( s2t( "midpoint" ), 50 );
list2.putObject( s2t( "transferSpec" ), descriptor7 );
descriptor8.putUnitDouble( s2t( "opacity" ), s2t( "percentUnit" ), 0.000000 );
descriptor8.putInteger( s2t( "location" ), 4096 );
descriptor8.putInteger( s2t( "midpoint" ), 50 );
list2.putObject( s2t( "transferSpec" ), descriptor8 );
descriptor4.putList( s2t( "transparency" ), list2 );
descriptor2.putObject( s2t( "gradient" ), s2t( "gradientClassEvent" ), descriptor4 );
descriptor.putObject( s2t( "to" ), s2t( "gradientLayer" ), descriptor2 );
executeAction(s2t("set"), descriptor, DialogModes.NO);

selectLayer("Gradient Fill 1459", false);
var s2t = function (s) {
	return app.stringIDToTypeID(s);
};
var descriptor = new ActionDescriptor();
var descriptor2 = new ActionDescriptor();
var descriptor3 = new ActionDescriptor();
var descriptor4 = new ActionDescriptor();
var descriptor5 = new ActionDescriptor();
var descriptor6 = new ActionDescriptor();
var descriptor7 = new ActionDescriptor();
var descriptor8 = new ActionDescriptor();
var list = new ActionList();
var list2 = new ActionList();
var reference = new ActionReference();
reference.putEnumerated( s2t( "contentLayer" ), s2t( "ordinal" ), s2t( "targetEnum" ));
descriptor.putReference( s2t( "null" ), reference );
descriptor2.putUnitDouble( s2t( "angle" ), s2t( "angleUnit" ), 90.000000 );
descriptor2.putEnumerated( s2t( "type" ), s2t( "gradientType" ), s2t( "linear" ));
descriptor2.putUnitDouble( s2t( "scale" ), s2t( "percentUnit" ), 25.000000 );
descriptor3.putUnitDouble( s2t( "horizontal" ), s2t( "percentUnit" ), -6.988542 );
descriptor3.putUnitDouble( s2t( "vertical" ), s2t( "percentUnit" ), 19.531250 );
descriptor2.putObject( s2t( "offset" ), s2t( "paint" ), descriptor3 );
descriptor4.putString( s2t( "name" ), "Custom" );
descriptor4.putEnumerated( s2t( "gradientForm" ), s2t( "gradientForm" ), s2t( "customStops" ));
descriptor4.putDouble(s2t("interfaceIconFrameDimmed"), 4096.000000);
// RGB Values
descriptor6.putDouble( s2t( "red" ), rValue );
descriptor6.putDouble( s2t( "grain" ), gValue );
descriptor6.putDouble(s2t("blue"), bValue);
//
descriptor5.putObject( s2t( "color" ), s2t( "RGBColor" ), descriptor6 );
descriptor5.putEnumerated( s2t( "type" ), s2t( "colorStopType" ), s2t( "userStop" ));
descriptor5.putInteger( s2t( "location" ), 614 );
descriptor5.putInteger( s2t( "midpoint" ), 50 );
list.putObject( s2t( "colorStop" ), descriptor5 );
descriptor4.putList( s2t( "colors" ), list );
descriptor7.putUnitDouble( s2t( "opacity" ), s2t( "percentUnit" ), 100.000000 );
descriptor7.putInteger( s2t( "location" ), 614 );
descriptor7.putInteger( s2t( "midpoint" ), 50 );
list2.putObject( s2t( "transferSpec" ), descriptor7 );
descriptor8.putUnitDouble( s2t( "opacity" ), s2t( "percentUnit" ), 0.000000 );
descriptor8.putInteger( s2t( "location" ), 4096 );
descriptor8.putInteger( s2t( "midpoint" ), 50 );
list2.putObject( s2t( "transferSpec" ), descriptor8 );
descriptor4.putList( s2t( "transparency" ), list2 );
descriptor2.putObject( s2t( "gradient" ), s2t( "gradientClassEvent" ), descriptor4 );
descriptor.putObject( s2t( "to" ), s2t( "gradientLayer" ), descriptor2 );
executeAction(s2t("set"), descriptor, DialogModes.NO);


function selectLayer(theName, makeVisible) {
	var s2t = function (s) {
		return app.stringIDToTypeID(s);
	};
	var descriptor = new ActionDescriptor();
	var list = new ActionList();
	var reference = new ActionReference();
	reference.putName( s2t( "layer" ), theName );
	descriptor.putReference( s2t( "null" ), reference );
	descriptor.putBoolean( s2t( "makeVisible" ), makeVisible );
	list.putInteger( 2257 );
	descriptor.putList( s2t( "layerID" ), list );
	executeAction( s2t( "select" ), descriptor, DialogModes.NO );
}

 

Votes

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
Participant ,
May 27, 2024 May 27, 2024

Copy link to clipboard

Copied

Thanks, Stephen for your valuable input. The script is working fine, however, I found that the gradient settings like angle, scale, location etc are hard-coded. Whereas the PSDs I have have varied gradient settings. It would be nice if the script could read the settings and retain them while updating the Color Stop value.

Votes

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 Expert ,
May 27, 2024 May 27, 2024

Copy link to clipboard

Copied

LATEST

@Masood.Ahmad wrote:

Thanks, Stephen for your valuable input. The script is working fine, however, I found that the gradient settings like angle, scale, location etc are hard-coded. Whereas the PSDs I have have varied gradient settings. It would be nice if the script could read the settings and retain them while updating the Color Stop value.


 

You can of course experiment and comment out or remove blocks of code to isolate whether it's possible to change the colour stop without changing anything else.

 

I didn't have the time for that, which is why I used a common function to select each gradient by name, but separate code to capture and change each gradient due to different angles and other parameters.

 

You didn't mention other files so yes this would be a problem if a different file used the same names but different parameters.

Votes

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