Skip to main content
dolldivine
Inspiring
July 29, 2024
Answered

Faster way to re-arrange many layers?

  • July 29, 2024
  • 2 replies
  • 1679 views

Hi,

I have layers organized by shape, each in 50 colors.
But I need to re-arrange them by color instead.

So right now I'm dragging layers by hand.  There's 9 shapes and 50 colors, so that's 450 layers.  

And then I'll have to repeat this whole process another 10-20 or so times.

I would record a script but I'm not even sure how I would go about that.

Flash has some cool "distribute to layers" type functions that come to mind but I don't think there's anything like that in Photoshop.

Does anyone know if there's a faster way to do this kind of re-arranging?

 

eg. the #000000 folder has 50 layers inside.  Each one needs to go into a different folder above, ditto for the other folders below.

This topic has been closed for replies.
Correct answer dolldivine

@Stephen Marsh oh good to know, thanks!

 

A note: this only works when the folders of interest are pasted into a blank file.  Otherwise is starts pulling the wrong layers and I didn't have time to fix that error, because it's a workaround I can live with, and this already took forever.  But if anyone wants to improve it, feel free...

 

It took a lot of tweaking but this script maintains relative layer order.

 

 

function main() {
    if (app.documents.length === 0) {
        alert("No document open!");
        return;
    }

    var docRef = app.activeDocument;
    var allLayerSets = getAllLayerSets(docRef);
    var selectedLayerSets = getSelectedLayerSets(allLayerSets);

    if (selectedLayerSets.length === 0) {
        alert("No folders selected!");
        return;
    }

    var maxLayers = 0;
    for (var i = 0; i < selectedLayerSets.length; i++) {
        var layerSet = selectedLayerSets[i];
        var layerCount = getLayerCount(layerSet);
        if (layerCount > maxLayers) {
            maxLayers = layerCount;
        }
    }

    var newFolders = [];
    for (var j = 0; j < maxLayers; j++) {
        var newFolder = docRef.layerSets.add();
        newFolder.name = "New Folder " + (j + 1);
        newFolders.push(newFolder);
    }

    var layerSets = selectedLayerSets.slice(); // Create a copy to preserve original order

    // Iterate over new folders and process layers from the bottom of the old folders
    for (var k = 0; k < newFolders.length; k++) {
        var targetFolder = newFolders[k];
        for (var l = 0; l < layerSets.length; l++) {
            var folder = layerSets[l];
            var layers = getLayerChildren(folder);
            if (layers.length > 0) {
                var layer = layers.pop(); // Get the bottom-most layer and remove it
                try {
                    layer.move(targetFolder, ElementPlacement.PLACEATEND);
                } catch (e) {
                    alert("Error moving layer: " + e.message);
                    return;
                }
                if (layers.length === 0) {
                    layerSets.splice(l, 1); // Remove folder if it is empty
                    l--; // Adjust index after removal
                }
            }
        }
    }

    // Delete empty original folders
    for (var m = 0; m < selectedLayerSets.length; m++) {
        var folderToDelete = selectedLayerSets[m];
        if (getLayerCount(folderToDelete) === 0) {
            try {
                folderToDelete.remove();
            } catch (e) {
                alert("Error deleting folder: " + e.message);
                return;
            }
        }
    }

    alert("Script completed successfully with layers in the correct order!");
}

function getAllLayerSets(docRef) {
    var layerSets = [];
    function recurseLayers(layers) {
        for (var i = 0; i < layers.length; i++) {
            var layer = layers[i];
            if (layer.typename === "LayerSet") {
                layerSets.push(layer);
                recurseLayers(layer.layers);
            }
        }
    }
    recurseLayers(docRef.layers);
    return layerSets;
}

function getSelectedLayerSets(allLayerSets) {
    var selectedLayerSets = [];
    for (var i = 0; i < allLayerSets.length; i++) {
        var layerSet = allLayerSets[i];
        if (layerSet.visible) { // Assume visibility as a proxy for selection
            selectedLayerSets.push(layerSet);
        }
    }
    return selectedLayerSets;
}

function getLayerCount(layerSet) {
    return layerSet.layers.length;
}

function getLayerChildren(layerSet) {
    var layers = [];
    for (var i = 0; i < layerSet.layers.length; i++) {
        layers.push(layerSet.layers[i]); // Push each layer to the array in original order
    }
    return layers;
}

main();

 

2 replies

dolldivine
Inspiring
July 31, 2024

Okay, I used ChatGPT and made a script that can do this. 

I would attach and share it here but the forum doesn't accept the jsx file extension.

Basically it takes all the folders and rearranges them from

 

A, B, C

A, B, C

A, B, C

 

to 

 

A, A, A

B, B, B

C, C, C

 

It took me about six hours of walking chatgpt through the constant errors, and the script takes 10 minutes to execute, so a lot of the time I was just waiting but, I did manage.

Stephen Marsh
Community Expert
Community Expert
July 31, 2024

@dolldivine – You can copy/paste the code into the forum reply code box using the </> button. Or attach it renamed as .txt 

dolldivine
dolldivineAuthorCorrect answer
Inspiring
July 31, 2024

@Stephen Marsh oh good to know, thanks!

 

A note: this only works when the folders of interest are pasted into a blank file.  Otherwise is starts pulling the wrong layers and I didn't have time to fix that error, because it's a workaround I can live with, and this already took forever.  But if anyone wants to improve it, feel free...

 

It took a lot of tweaking but this script maintains relative layer order.

 

 

function main() {
    if (app.documents.length === 0) {
        alert("No document open!");
        return;
    }

    var docRef = app.activeDocument;
    var allLayerSets = getAllLayerSets(docRef);
    var selectedLayerSets = getSelectedLayerSets(allLayerSets);

    if (selectedLayerSets.length === 0) {
        alert("No folders selected!");
        return;
    }

    var maxLayers = 0;
    for (var i = 0; i < selectedLayerSets.length; i++) {
        var layerSet = selectedLayerSets[i];
        var layerCount = getLayerCount(layerSet);
        if (layerCount > maxLayers) {
            maxLayers = layerCount;
        }
    }

    var newFolders = [];
    for (var j = 0; j < maxLayers; j++) {
        var newFolder = docRef.layerSets.add();
        newFolder.name = "New Folder " + (j + 1);
        newFolders.push(newFolder);
    }

    var layerSets = selectedLayerSets.slice(); // Create a copy to preserve original order

    // Iterate over new folders and process layers from the bottom of the old folders
    for (var k = 0; k < newFolders.length; k++) {
        var targetFolder = newFolders[k];
        for (var l = 0; l < layerSets.length; l++) {
            var folder = layerSets[l];
            var layers = getLayerChildren(folder);
            if (layers.length > 0) {
                var layer = layers.pop(); // Get the bottom-most layer and remove it
                try {
                    layer.move(targetFolder, ElementPlacement.PLACEATEND);
                } catch (e) {
                    alert("Error moving layer: " + e.message);
                    return;
                }
                if (layers.length === 0) {
                    layerSets.splice(l, 1); // Remove folder if it is empty
                    l--; // Adjust index after removal
                }
            }
        }
    }

    // Delete empty original folders
    for (var m = 0; m < selectedLayerSets.length; m++) {
        var folderToDelete = selectedLayerSets[m];
        if (getLayerCount(folderToDelete) === 0) {
            try {
                folderToDelete.remove();
            } catch (e) {
                alert("Error deleting folder: " + e.message);
                return;
            }
        }
    }

    alert("Script completed successfully with layers in the correct order!");
}

function getAllLayerSets(docRef) {
    var layerSets = [];
    function recurseLayers(layers) {
        for (var i = 0; i < layers.length; i++) {
            var layer = layers[i];
            if (layer.typename === "LayerSet") {
                layerSets.push(layer);
                recurseLayers(layer.layers);
            }
        }
    }
    recurseLayers(docRef.layers);
    return layerSets;
}

function getSelectedLayerSets(allLayerSets) {
    var selectedLayerSets = [];
    for (var i = 0; i < allLayerSets.length; i++) {
        var layerSet = allLayerSets[i];
        if (layerSet.visible) { // Assume visibility as a proxy for selection
            selectedLayerSets.push(layerSet);
        }
    }
    return selectedLayerSets;
}

function getLayerCount(layerSet) {
    return layerSet.layers.length;
}

function getLayerChildren(layerSet) {
    var layers = [];
    for (var i = 0; i < layerSet.layers.length; i++) {
        layers.push(layerSet.layers[i]); // Push each layer to the array in original order
    }
    return layers;
}

main();

 

Legend
July 29, 2024

I don't understand the pattern of what goes where. Is there a SPECIFIC formula to determine that? Any script would need a pattern to follow.

dolldivine
Inspiring
July 29, 2024

I'll try to put it a different way.

 

Right now the folders are arranged like:

 

Folder 1 - layers A, B, C, D, E, F

Folder 2 - layers A, B, C, D, E, F

Folder 3 - layers A, B, C, D, E, F

 

And I want to re-arrange them like this:

 

Folder 1 - A, A, A

Folder 2 - B, B, B

Folder 3 - C, C, C

Folder 4 - D, D, D, etc.

 

To make a script, as far as I understand, all folders and layers would need to be visible and open.  So then I'd be manually moving one layer across hundreds of other layers, hundreds of times.  Theoretically possible but... mind-bogglingly cumbersome.  Is it possible to insert a layer into a folder that's not open?  That could help make it more feasible but I don't think there's a way to do this in a way that can be captured by a script...

Stephen Marsh
Community Expert
Community Expert
July 29, 2024

I think that you mean action, not script.

 

A script is different and that is what you need.

 

But scripts require logic, programming, rules etc.

 

Can you provide a simple before and after file? Perhaps using 3 examples of 3 colours each?