Copy link to clipboard
Copied
For example the active layer as a layer ID of 36 in the layer stack.
The active layer moves to the top of the layer stack
Can the initial layer ID be used to return the active layer to its original position?
In other words, after moving the active layer to the top of the layer stack.
How can the active layer return to its initial position using a script?
The question is, can a script move the active layer to a position that is not immediately adjacent to the active layer, bypassing one or more layer positions in the layer stack?
Copy link to clipboard
Copied
I will tag scripters who can help you @c.pfaffenbichler @Stephen_A_Marsh @jazz-y @r-bin
Copy link to clipboard
Copied
@Polycontrast – Layers are fun aren't they?
I know that I have posted code for this before, now I just have to find it!
I think that Index is better than ID for stack position, but Index will often change, it isn't static like the ID is. So ID can be useful for selecting, but Index is used for moving the layer in the stack... I think!
How robust will this need to be? Will layers names change? Will other layers change position in the stack? Will layers be removed or deleted, or will layer groups (or frames or artboards) be added or removed etc.
Copy link to clipboard
Copied
I think that you would first need to save the layer index into a system variable or text file etc.
Then retrieve the layer index to move it.
The following will move the active layer to index position 1:
moveToLayerIndex(1);
function moveToLayerIndex(theIndex) {
function s2t(s) {
return app.stringIDToTypeID(s);
}
var descriptor = new ActionDescriptor();
var list = new ActionList();
var reference = new ActionReference();
var reference2 = new ActionReference();
reference.putEnumerated( s2t( "layer" ), s2t( "ordinal" ), s2t( "targetEnum" ));
descriptor.putReference( s2t( "null" ), reference );
reference2.putIndex( s2t( "layer" ), theIndex );
descriptor.putReference( s2t( "to" ), reference2 );
descriptor.putBoolean( s2t( "adjustment" ), false );
descriptor.putInteger( s2t( "version" ), 5 );
list.putInteger( 2 );
descriptor.putList( s2t( "layerID" ), list );
executeAction( s2t( "move" ), descriptor, DialogModes.NO );
}
Copy link to clipboard
Copied
For example the active layer as a layer ID of 36 in the layer stack.
The active layer moves to the top of the layer stack
Can the initial layer ID be used to return the active layer to its original position?
The Index changes with the move, the ID does not indicate the original position in the Layer stack per se, so unless you can undo or use the History to undo the change the information is just not available.
This would move a Layer, identified by ID, to a position, defined by index.
// 2023, use it at your own risk;
if (app.documents.length > 0) {
var theLayers = collectLayersNamesIndexAndIdentifier();
moveLayerTo (theLayers[1][2], theLayers[3][1])
};
////// based on code by mike hale and paul riggott //////
function selectLayerByID(index,add){
add = undefined ? add = false:add
var ref = new ActionReference();
ref.putIdentifier(charIDToTypeID("Lyr "), index);
var desc = new ActionDescriptor();
desc.putReference(charIDToTypeID("null"), ref );
if(add) desc.putEnumerated( stringIDToTypeID( "selectionModifier" ), stringIDToTypeID( "selectionModifierType" ), stringIDToTypeID( "addToSelection" ) );
desc.putBoolean( charIDToTypeID( "MkVs" ), false );
try{
executeAction(charIDToTypeID("slct"), desc, DialogModes.NO );
}catch(e){
alert(e.message);
}
};
////// move active layer in front of other layer in layer stack //////
function moveLayerTo (thisLayerId, theIndex) {
selectLayerByID(thisLayerId, false);
var idlayer = stringIDToTypeID( "layer" );
var desc58 = new ActionDescriptor();
var ref19 = new ActionReference();
ref19.putEnumerated( idlayer, stringIDToTypeID( "ordinal" ), stringIDToTypeID( "targetEnum" ) );
desc58.putReference( stringIDToTypeID( "null" ), ref19 );
var ref20 = new ActionReference();
ref20.putIndex( idlayer, theIndex );
desc58.putReference( stringIDToTypeID( "to" ), ref20 );
desc58.putBoolean( stringIDToTypeID( "adjustment" ), false );
desc58.putInteger( stringIDToTypeID( "version" ), 5 );
var list11 = new ActionList();
list11.putInteger(thisLayerId);
desc58.putList( stringIDToTypeID( "layerID" ), list11 );
executeAction( stringIDToTypeID( "move" ), desc58, DialogModes.NO );
};
////// collect layers //////
function collectLayersNamesIndexAndIdentifier () {
// the file;
var myDocument = app.activeDocument;
// get number of layers;
var ref = new ActionReference();
ref.putProperty(stringIDToTypeID('property'), stringIDToTypeID('numberOfLayers'));
ref.putEnumerated( charIDToTypeID("Dcmn"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );
var applicationDesc = executeActionGet(ref);
var theNumber = applicationDesc.getInteger(stringIDToTypeID("numberOfLayers"));
// process the layers;
var theLayers = new Array;
for (var m = 0; m <= theNumber; m++) {
try {
var ref = new ActionReference();
ref.putIndex( charIDToTypeID( "Lyr " ), m);
var layerDesc = executeActionGet(ref);
var layerSet = typeIDToStringID(layerDesc.getEnumerationValue(stringIDToTypeID("layerSection")));
var isBackground = layerDesc.getBoolean(stringIDToTypeID("background"));
// if group collect values;
//if (layerSet != "layerSectionEnd" && layerSet != "layerSectionStart" /*&& isBackground != true*/) {
var theName = layerDesc.getString(stringIDToTypeID('name'));
var theID = layerDesc.getInteger(stringIDToTypeID('layerID'));
var theIndex = layerDesc.getInteger(stringIDToTypeID('itemIndex'));
theLayers.push([theName, theIndex, theID, layerSet])
//};
}
catch (e) {};
};
return theLayers
};
Copy link to clipboard
Copied
In my workflow, I have to manually move a layer to the top of the stack, work on the layer, and then manually move it back to its original position. The layer names don’t change, and the number of layers is relatively stable. The layer stack count can fluctuate by one or two layers.
I was thinking of automating the layer movement with two scripts:
Script A
Saves the active layer index/Id to an external file
Moves the layer to the top of the stack.
Script B
Gets the layer index/ID from the external file
Moves the layer based on the index/ID value from the external file.
I did a quick test, and this approach did not work. After reading the comments, I have a better idea of why it is not working. Thank you for providing the sample code. I will test it to learn more about the layer index and ID.
Copy link to clipboard
Copied
I will test it to learn more about the layer index and ID.
By @Polycontrast
I wrote the following to help inspect layers when planning such scripts, it may or may not help in your case:
https://gist.github.com/MarshySwamp/ef345ef3dec60a843465347ee6fcae2f