Copy link to clipboard
Copied
Hi,
I have some code which can shuffle layer
app.activeDocument.suspendHistory("Randomize Layers", "main ()");
function main () {
if (documents.length > 0)
{
// Count number of layers in document
var nLayers = activeDocument.layers.length;
if (nLayers > 1) { // Needs at least two movable layers to be useful
layersAll = activeDocument.layers;
// I run through twice, because it seems to come out much more random-looking when I do
for (var j=0;j<1;j++) {
for (var i=0;i<nLayers;i++) {
var whichLayer = Math.floor(Math.random()*nLayers);
if (layersAll[whichLayer].isBackgroundLayer==false) {
activeDocument.activeLayer = activeDocument.layers[whichLayer];
app.activeDocument.layers[whichLayer].move(activeDocument,ElementPlacement.PLACEATEND);
}
}
}
alert ("Reordered "+i+" layers");
}
else {
alert ("Not enough layers to randomize");
}
}
else {
alert ( "You must have at least one open document to run this script");
}
}
the problem is cannot selected by layer, so it will shuffle all layer, can someone help to edited the script, so it will shuffle by selected layer, Thankss
Okay, this should keep the layers clipped.
#target photoshop
var doc = activeDocument;
var listA = new Array()
var layList = getLayersIdx ();
if (layList.count < 1) throw("Two or more layers needed");
var listNum = layList.count
for(var i=0;i<listNum;i++){
listA = getLayersIdx ();
var num1 = Math.floor(Math.random()*listNum);
var num2=num1;
while(num2==num1){
var num2 = Math.floor(Math.random()*listNum);
}
selectPair (num1, num2)
}
re
...
Copy link to clipboard
Copied
Are you saying that you want to select several layers and only randomize those selected layers within just the selected layers or randomize them within all the layers?
Copy link to clipboard
Copied
like this chuck, only the selected layer,and when run the script, it will random shuffle
Copy link to clipboard
Copied
You can try this script. It will only shuffle the layers in the layer stack. It will not move the actual position of the layers' contents. Thanks to r-bin for the base structure of this script.
Edit: just noticed that your example layers are clipped. This will remove the clipping.
#target photoshop
var listA = new Array()
var r = new ActionReference();
r.putProperty(stringIDToTypeID("property"), stringIDToTypeID("targetLayersIndexes"));
r.putEnumerated(stringIDToTypeID("document"), stringIDToTypeID("ordinal"), stringIDToTypeID("targetEnum"));
var list = executeActionGet(r).getList(stringIDToTypeID("targetLayersIndexes"));
if (list.count < 1) throw("Two or more layers needed");
var listNum = list.count
for(var i=0;i<listNum;i++){
var r = new ActionReference();
r.putProperty(stringIDToTypeID("property"), stringIDToTypeID("targetLayersIndexes"));
r.putEnumerated(stringIDToTypeID("document"), stringIDToTypeID("ordinal"), stringIDToTypeID("targetEnum"));
listA = executeActionGet(r).getList(stringIDToTypeID("targetLayersIndexes"));
var num1 = Math.floor(Math.random()*listNum);
var num2=num1;
while(num2==num1){
var num2 = Math.floor(Math.random()*listNum);
}
selectPair (num1, num2)
}
function selectPair(lay1,lay2){
var idx0 = listA.getReference(lay1).getIndex();
var idx1 = listA.getReference(lay2).getIndex();
var r = new ActionReference();
r.putProperty(stringIDToTypeID("property"), stringIDToTypeID("targetLayersIDs"));
r.putEnumerated(stringIDToTypeID("document"), stringIDToTypeID("ordinal"), stringIDToTypeID("targetEnum"));
var list2 = executeActionGet(r).getList(stringIDToTypeID("targetLayersIDs"));
var id0 = list2.getReference(lay1).getIdentifier();
var id1 = list2.getReference(lay2).getIdentifier();
set_layer_index(id0, idx1);
set_layer_index(id1, idx0);
}
function set_layer_index(id, idx)
{
try {
var d = new ActionDescriptor();
var r1 = new ActionReference();
r1.putIdentifier(stringIDToTypeID("layer"), id);
d.putReference(stringIDToTypeID("null"), r1);
var r2 = new ActionReference();
r2.putIndex(stringIDToTypeID("layer"), idx);
d.putReference(stringIDToTypeID("to"), r2);
executeAction(stringIDToTypeID("move"), d, DialogModes.NO);
}
catch (e) { throw(e); }
}
Copy link to clipboard
Copied
Thanks Chuck, its works well,
but how to maintain the clipping mask to be still in there,
because I need a clipping mask to be there.
Copy link to clipboard
Copied
I'll have to research that. I could do it way that takes longer, but there might be a shorter method using AM code, which I'm not that good at.
Copy link to clipboard
Copied
is there a script that can make a clipping mask from the selected layer, because after using a script from you the layer is still selected,
Copy link to clipboard
Copied
Okay, this should keep the layers clipped.
#target photoshop
var doc = activeDocument;
var listA = new Array()
var layList = getLayersIdx ();
if (layList.count < 1) throw("Two or more layers needed");
var listNum = layList.count
for(var i=0;i<listNum;i++){
listA = getLayersIdx ();
var num1 = Math.floor(Math.random()*listNum);
var num2=num1;
while(num2==num1){
var num2 = Math.floor(Math.random()*listNum);
}
selectPair (num1, num2)
}
reClip ();
function selectPair(lay1,lay2){
var idx0 = listA.getReference(lay1).getIndex();
var idx1 = listA.getReference(lay2).getIndex();
var layIDs = getLayerId ();
var id0 = layIDs.getReference(lay1).getIdentifier();
var id1 = layIDs.getReference(lay2).getIdentifier();
set_layer_index(id0, idx1);
set_layer_index(id1, idx0);
}
function reClip(){
var cList = getLayerId ();
var idArray = [];
for(var i=0;i<cList.count;i++){
idArray.push(cList.getReference(i).getIdentifier())
makeLayerActiveByLayerID (cList.getReference(i).getIdentifier())
if(!doc.activeLayer.grouped){doc.activeLayer.grouped = true};
};//end loop
multiSelectByIDs (idArray);
}
function getLayerId(){
var r = new ActionReference();
r.putProperty(stringIDToTypeID("property"), stringIDToTypeID("targetLayersIDs"));
r.putEnumerated(stringIDToTypeID("document"), stringIDToTypeID("ordinal"), stringIDToTypeID("targetEnum"));
var list2 = executeActionGet(r).getList(stringIDToTypeID("targetLayersIDs"));
return list2
}
function getLayersIdx(){
var r = new ActionReference();
r.putProperty(stringIDToTypeID("property"), stringIDToTypeID("targetLayersIndexes"));
r.putEnumerated(stringIDToTypeID("document"), stringIDToTypeID("ordinal"), stringIDToTypeID("targetEnum"));
var list = executeActionGet(r).getList(stringIDToTypeID("targetLayersIndexes"));
return list;
}
function set_layer_index(id, idx)
{
try {
var d = new ActionDescriptor();
var r1 = new ActionReference();
r1.putIdentifier(stringIDToTypeID("layer"), id);
d.putReference(stringIDToTypeID("null"), r1);
var r2 = new ActionReference();
r2.putIndex(stringIDToTypeID("layer"), idx);
d.putReference(stringIDToTypeID("to"), r2);
executeAction(stringIDToTypeID("move"), d, DialogModes.NO);
}
catch (e) { throw(e); }
}
function makeLayerActiveByLayerID(id){
var desc = new ActionDescriptor();
var ref = new ActionReference();
ref.putIdentifier( charIDToTypeID( "Lyr " ), id );
desc.putReference( charIDToTypeID( "null" ), ref );
desc.putBoolean( charIDToTypeID( "MkVs" ), false );
executeAction( charIDToTypeID( "slct" ), desc, DialogModes.NO );
};
//used in multiSelectByIDs(ids)
function doesIdExists( id ){// function to check if the id exists
var res = true;
var ref = new ActionReference();
ref.putIdentifier(charIDToTypeID('Lyr '), id);
try{var desc = executeActionGet(ref)}catch(err){res = false};
return res;
}
//uses doesIdExists(id)
function multiSelectByIDs(ids) {
if( ids.constructor != Array ) ids = [ ids ];
var layers = new Array();
var id54 = charIDToTypeID( "slct" );
var desc12 = new ActionDescriptor();
var id55 = charIDToTypeID( "null" );
var ref9 = new ActionReference();
for (var i = 0; i < ids.length; i++) {
if(doesIdExists(ids[i]) == true){// a check to see if the id stil exists
layers[i] = charIDToTypeID( "Lyr " );
ref9.putIdentifier(layers[i], ids[i]);
}
}
desc12.putReference( id55, ref9 );
var id58 = charIDToTypeID( "MkVs" );
desc12.putBoolean( id58, false );
executeAction( id54, desc12, DialogModes.NO );
}
Copy link to clipboard
Copied
Thank You Very Much !!!!