Skip to main content
Inspiring
May 24, 2024
Answered

JavaScript to change the Gradient color

  • May 24, 2024
  • 2 replies
  • 1137 views

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

 

 

 

This topic has been closed for replies.
Correct answer Stephen Marsh

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

 

2 replies

Stephen Marsh
Community Expert
Community Expert
May 27, 2024

@code_seeeeeker 

 

How did you go with the ScriptingListener plugin?

Inspiring
May 27, 2024

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

Stephen Marsh
Community Expert
Stephen MarshCommunity ExpertCorrect answer
Community Expert
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 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 );
}

 

Stephen Marsh
Community Expert
Community Expert
May 24, 2024

@code_seeeeeker 

 

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