Skip to main content
artistic_Glimmer5E1B
Inspiring
May 25, 2019
Answered

Script for moving layers on the x axis to the widest width out of a series of selected layers

  • May 25, 2019
  • 3 replies
  • 1808 views

Hello glorious scripters! I am in need of help and was hoping one of you fine gentlepeople could help me create a script for my specific need.

Basically, I need a script that separates a series of layers based on the widest width of one of those selected layers. Say I have 4 layers with sprites that have respective widths of 100, 100, 100, 200 pixels. What I need it to do is figure out that the widest width of those 4 layers is 200px and then separate the 4 layers by 200 pixels each for a total image/canvas width of 800 pixels. Why this is complicated is that my sprites have variable widths and aren't all the same so I end up having to do this manually.

This is how I'd imagine the script would work, if it is even possible:

1) Align bottom edges in case the sprites have varying heights.

2) Figure out the largest width out of selected layers.

3) Move the 2/3/4/n sprites to the right n pixels once it determines the largest width of the select layers.

Again, not sure if this is possible but if you guys have websites or this is something I can even throw a few bucks at I would gladly pay to help myself and others that much be in a similar situation in the future.

This topic has been closed for replies.
Correct answer SuperMerlin

It means that I saved and loaded the script, hotkeyed it and it didn't do anything. Not sure how to upload a file here but below is a link to the psd. Sorry, not sure when details are appropriate.

https://ufile.io/t8owthag


Sorry, I added another check but in the wrong place. I am going senile in my old age.

This should now work.

#target photoshop;

if(documents.length) main();

function main(){

var lays = getSelectedLayersIDs();

var details = new Array();

for(var z=0;z<lays.length;z++){

    details.push(getLayerBoundsByIndex(lays));

    }

if(details.length < 2) return;

details.sort(function(a,b){return a[5]-b[5];});

var maxWidth= details.reverse()[0][5];

details.sort(function(a,b){return a[1]-b[1];});

var Y = details[0][4];

selectLayerByID(details[0][0]);

W=details[0][1];

for(var z = 1;z<details.length;z++){

    selectLayerByID(details[0]);

    W+=maxWidth;

    activeDocument.activeLayer.translate(-details[1],-details[4]);

    activeDocument.activeLayer.translate(W,Y);

    }

};

function getLayerBoundsByIndex( ID ) {

    var ref = new ActionReference();

    ref.putProperty( charIDToTypeID("Prpr") , stringIDToTypeID( "bounds" ));

    ref.putIdentifier( charIDToTypeID( "Lyr " ), ID );

    var desc = executeActionGet(ref).getObjectValue(stringIDToTypeID( "bounds" ));

    var bounds = [];

    bounds.push(ID);

    bounds.push(desc.getUnitDoubleValue(stringIDToTypeID("left")));

    bounds.push(desc.getUnitDoubleValue(stringIDToTypeID("top")));

    bounds.push(desc.getUnitDoubleValue(stringIDToTypeID("right")));

    bounds.push(desc.getUnitDoubleValue(stringIDToTypeID("bottom")));

    bounds.push(desc.getUnitDoubleValue(stringIDToTypeID("right"))-desc.getUnitDoubleValue(stringIDToTypeID("left")));

    return bounds;

};

function selectLayerByID(ID, add) { 

add = undefined ? add = false : add 

var ref = new ActionReference(); 

ref.putIdentifier(charIDToTypeID("Lyr "), ID); 

var desc = new ActionDescriptor(); 

desc.putReference(charIDToTypeID("null"), ref); 

if (add) desc.putEnumerated(stringIDToTypeID("selectionModifier"), stringIDToTypeID("selectionModifierType"), stringIDToTypeID("addToSelection")); 

desc.putBoolean(charIDToTypeID("MkVs"), false); 

executeAction(charIDToTypeID("slct"), desc, DialogModes.NO); 

}

function getSelectedLayersIDs(){

      var selectedLayers = new Array();

      var backGroundCounter = 1;

            if(activeDocument.artLayers.length > 0){

            backGroundCounter = activeDocument.artLayers[activeDocument.artLayers.length - 1].isBackgroundLayer ? 0 : 1;

            }

      var ref = new ActionReference();

      ref.putProperty(charIDToTypeID("Prpr"), stringIDToTypeID("targetLayers"));

      ref.putEnumerated( charIDToTypeID("Dcmn"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );

      var desc = executeActionGet(ref);

      if( desc.hasKey( stringIDToTypeID( "targetLayers" ) ) ){

         desc = desc.getList( stringIDToTypeID( "targetLayers" ));

          var c = desc.count;

          var selectedLayers = new Array();

          for(var i=0;i<c;i++){

               selectedLayers.push(  desc.getReference( i ).getIndex() +backGroundCounter );

          }

       }else{

         var ref = new ActionReference();

         ref.putProperty( charIDToTypeID("Prpr") , charIDToTypeID( "ItmI" ));

         ref.putEnumerated( charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );

         if(!backGroundCounter){

            selectedLayers.push( executeActionGet(ref).getInteger(charIDToTypeID( "ItmI" )) -1);

            }else{

                selectedLayers.push( executeActionGet(ref).getInteger(charIDToTypeID( "ItmI" )));

                }

     var vis = app.activeDocument.activeLayer.visible;

        if(vis == true) app.activeDocument.activeLayer.visible = false;

        var desc9 = new ActionDescriptor();

    var list9 = new ActionList();

    var ref9 = new ActionReference();

    ref9.putEnumerated( charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );

    list9.putReference( ref9 );

    desc9.putList( charIDToTypeID("null"), list9 );

    executeAction( charIDToTypeID("Shw "), desc9, DialogModes.NO );

    if(app.activeDocument.activeLayer.visible == false) selectedLayers.shift();

        app.activeDocument.activeLayer.visible = vis;

      }

  var IDs=[];

  for(var a in selectedLayers){

      var ref = new ActionReference();

ref.putIndex( charIDToTypeID( "Lyr " ), selectedLayers  );

IDs.push(executeActionGet(ref).getInteger(stringIDToTypeID( "layerID" )));

      }

      return IDs;

};

It should work in most versions CS5 or newer.

Stephen Marsh
Community Expert
Community Expert
May 25, 2019

What would the original canvas size be? 100 x 100 px or 200 x 100 px?

How do the separate sprites come into the layered file?

What order from left to right should the images appear in, and does this perhaps match the layer order from bottom to top etc?

artistic_Glimmer5E1B
Inspiring
May 25, 2019

Currently, the canvas size is huge because there are a few hundred sprites on the sheet. I was thinking if possible we could just move the selected layers to the top left of the canvas and then align their bottom edges in case they have varying heights. After this script ran, I would combine the layers into 1 and export as png.

The separated sprites are in separate layers, I manually used an action to separate them from the sheet. I was thinking about that after I posted this but order would be either layer number (Layer 1 is first Layer 2 is second, etc) or bottom to top, or however is easiest.

JJMack
Community Expert
Community Expert
May 25, 2019

Can you code a javascript?

JJMack
c.pfaffenbichler
Community Expert
Community Expert
May 25, 2019

What I need it to do is figure out that the widest width of those 4 layers is 200px and then separate the 4 layers by 200 pixels each for a total image/canvas width of 800 pixels.

Please post a screenshots/sketch with mark-ups to clarify what you mean.

artistic_Glimmer5E1B
Inspiring
May 25, 2019

NZ9AMQs.png

I hope this image helps. There are 4 sprites in this example but in others it might be more or less. 3 different sizes. 48x48, 43x48, 68x48. The script would see that the widest width is 68px. I'm assuming we'd put all the sprites on top of each other and then move each 68 pixels apart from one another without distorting the size of the sprite/layer itself.

The top image is what the final product would look like. The bottom is just showing that they are all separated by 68 pixels.

SuperMerlin
Inspiring
May 26, 2019

You could try this, tested using CS6. It hopes to align the layers to the left most selected layer.

#target photoshop;

if(documents.length) main();

function main(){

var lays = getSelectedLayersIDs();

var details = new Array();

if(details.length < 2) return;

for(var z=0;z<lays.length;z++){

    details.push(getLayerBoundsByIndex(lays));

    }

details.sort(function(a,b){return a[5]-b[5];});

var maxWidth= details.reverse()[0][5];

details.sort(function(a,b){return a[1]-b[1];});

var Y = details[0][4];

selectLayerByID(details[0][0]);

W=details[0][1];

for(var z = 1;z<details.length;z++){

    selectLayerByID(details[0]);

    W+=maxWidth;

    activeDocument.activeLayer.translate(-details[1],-details[4]);

    activeDocument.activeLayer.translate(W,Y);

    }

};

function getLayerBoundsByIndex( ID ) {

    var ref = new ActionReference();

    ref.putProperty( charIDToTypeID("Prpr") , stringIDToTypeID( "bounds" ));

    ref.putIdentifier( charIDToTypeID( "Lyr " ), ID );

    var desc = executeActionGet(ref).getObjectValue(stringIDToTypeID( "bounds" ));

    var bounds = [];

    bounds.push(ID);

    bounds.push(desc.getUnitDoubleValue(stringIDToTypeID("left")));

    bounds.push(desc.getUnitDoubleValue(stringIDToTypeID("top")));

    bounds.push(desc.getUnitDoubleValue(stringIDToTypeID("right")));

    bounds.push(desc.getUnitDoubleValue(stringIDToTypeID("bottom")));

    bounds.push(desc.getUnitDoubleValue(stringIDToTypeID("right"))-desc.getUnitDoubleValue(stringIDToTypeID("left")));

    return bounds;

};

function selectLayerByID(ID, add) { 

add = undefined ? add = false : add 

var ref = new ActionReference(); 

ref.putIdentifier(charIDToTypeID("Lyr "), ID); 

var desc = new ActionDescriptor(); 

desc.putReference(charIDToTypeID("null"), ref); 

if (add) desc.putEnumerated(stringIDToTypeID("selectionModifier"), stringIDToTypeID("selectionModifierType"), stringIDToTypeID("addToSelection")); 

desc.putBoolean(charIDToTypeID("MkVs"), false); 

executeAction(charIDToTypeID("slct"), desc, DialogModes.NO); 

}

function getSelectedLayersIDs(){

      var selectedLayers = new Array();

      var backGroundCounter = 1;

            if(activeDocument.artLayers.length > 0){

            backGroundCounter = activeDocument.artLayers[activeDocument.artLayers.length - 1].isBackgroundLayer ? 0 : 1;

            }

      var ref = new ActionReference();

      ref.putProperty(charIDToTypeID("Prpr"), stringIDToTypeID("targetLayers"));

      ref.putEnumerated( charIDToTypeID("Dcmn"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );

      var desc = executeActionGet(ref);

      if( desc.hasKey( stringIDToTypeID( "targetLayers" ) ) ){

         desc = desc.getList( stringIDToTypeID( "targetLayers" ));

          var c = desc.count;

          var selectedLayers = new Array();

          for(var i=0;i<c;i++){

               selectedLayers.push(  desc.getReference( i ).getIndex() +backGroundCounter );

          }

       }else{

         var ref = new ActionReference();

         ref.putProperty( charIDToTypeID("Prpr") , charIDToTypeID( "ItmI" ));

         ref.putEnumerated( charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );

         if(!backGroundCounter){

            selectedLayers.push( executeActionGet(ref).getInteger(charIDToTypeID( "ItmI" )) -1);

            }else{

                selectedLayers.push( executeActionGet(ref).getInteger(charIDToTypeID( "ItmI" )));

                }

     var vis = app.activeDocument.activeLayer.visible;

        if(vis == true) app.activeDocument.activeLayer.visible = false;

        var desc9 = new ActionDescriptor();

    var list9 = new ActionList();

    var ref9 = new ActionReference();

    ref9.putEnumerated( charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );

    list9.putReference( ref9 );

    desc9.putList( charIDToTypeID("null"), list9 );

    executeAction( charIDToTypeID("Shw "), desc9, DialogModes.NO );

    if(app.activeDocument.activeLayer.visible == false) selectedLayers.shift();

        app.activeDocument.activeLayer.visible = vis;

      }

  var IDs=[];

  for(var a in selectedLayers){

      var ref = new ActionReference();

ref.putIndex( charIDToTypeID( "Lyr " ), selectedLayers  );

IDs.push(executeActionGet(ref).getInteger(stringIDToTypeID( "layerID" )));

      }

      return IDs;

};