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();
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
...
Copy link to clipboard
Copied
I would use ScriptingListener to record changing the colour on each separate gradient.
Copy link to clipboard
Copied
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
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 );
}
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.
Copy link to clipboard
Copied
@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.