How do I make an Action Manager Loop script?
Copy link to clipboard
Copied
Hi All,
First off I'm an artist by trade and just like to potter around with code so apologies for any horrible coding!!
I've made a script that loops through all layers and folders in photoshop looking for text layers.
Each text layer has a layer below it (a big blue square). The aim is for the text layer to resize so that it fits inside the boundaries of the blue square.
This video shows an older version of the script:
https://youtu.be/l3SZmS_flPA?t=16m48s
The problem I'm having is that it runs very very slow in big files (Small files are not a problem at all) I've seen 'Action Manager' mentioned but I'm having trouble finding an example that is similar enough for me understand and use from.
How do I change the code to loop using Action Manager?
Thanks!!
// GET STARTING TIME ================================================================================== //
var stDate = new Date () // Get starting date //
var stTime = stDate.getTime () // Get starting time //
// COUNT THE TIME =================================================================================== //
var ndDate = new Date (); // End date //
var ndTime = ndDate.getTime (); // End time //
var elapsed = ndTime - stTime; // Elapsed time //
var tmArray = ["Empty", ] // Time array //
// ================================================================================================== //
// FUNTIONS ========================================================================================= //
// ================================================================================================== //
//---function cntTime
function cntTime (elap){ // Time Calculation - Per Doc - does work but no need //
tmArray = [
"Empty",
[ Math.floor ( (elap/(1000*60*60)) %24) ], // Hours //
[ Math.floor ( (elap/(1000*60)) % 60) ], // Minutes //
[ Math.floor ( (elap/1000) % 60 ) ] // Seconds //
]
for (i=1; i<=3; i++){ // Loop trough the values //
tmArray = (tmArray < 10 ? "0" : "") + tmArray // If the value is less than 10 // Add 0 //
}
}
/*----------Text Resizer Init function------------------------------------------ */
function initTextResize() {
// Linefeed
if ($.os.search(/windows/i) != -1)
fileLineFeed = "windows";
else
fileLineFeed = "macintosh";
// Do we have a document open?
if (app.documents.length === 0) {
alert("Please open at least one file", "drawlikeaprofessional.com - TEXT RESIZER", true);
return;
}
// More than one document open
if (app.documents.length > 1) {
var runMultiple = confirm("TextResize has detected Multiple Files.\nDo you wish to run TextResize on all opened files?", true, "drawlikeaprofessional.com - TEXT RESIZER");
if (runMultiple === true) {
docs = app.documents;
} else {
docs = [app.activeDocument];
}
} else {
runMultiple = false;
docs = [app.activeDocument];
}
// Loop all documents
for (var i = 0; i < docs.length; i++)
{
// useDialog (but not when running multiple
if ( (runMultiple !== true) && (useDialog === true) )
{
}
// Don't use Dialog
else
{
}
// Set active document
app.activeDocument = docs;
// call to the core with the current document
startScriptPurpose(app.activeDocument);
// Give notice that we're done or open the file (only when running 1 file!)
if (runMultiple === false)
{
ndDate = new Date (); // End date //
ndTime = ndDate.getTime (); // End time //
elapsed = ndTime - stTime; // Elapsed time //
cntTime (elapsed) // Count the time //
alert("1 Document Done\n\nTime Elapsed: " + tmArray[2] + " : " + tmArray[3]+"\n\n-drawlikeaprofessional.com","drawlikeaprofessional.com - TEXT RESIZER");
}
}
if (runMultiple === true)
{
ndDate = new Date (); // End date //
ndTime = ndDate.getTime (); // End time //
elapsed = ndTime - stTime; // Elapsed time //
cntTime (elapsed) // Count the time //
alert("All Documents Done\n\nTime Elapsed: " + tmArray[2] + " : " + tmArray[3]+"\n\n-drawlikeaprofessional.com","drawlikeaprofessional.com - TEXT RESIZER");
}
}
//------------------------------------------Align to selection------------------------------------------------
function alignToSelection() {
var idAlgn = charIDToTypeID( "Algn" );
var desc583 = new ActionDescriptor();
var idnull = charIDToTypeID( "null" );
var ref334 = new ActionReference();
var idLyr = charIDToTypeID( "Lyr " );
var idOrdn = charIDToTypeID( "Ordn" );
var idTrgt = charIDToTypeID( "Trgt" );
ref334.putEnumerated( idLyr, idOrdn, idTrgt );
desc583.putReference( idnull, ref334 );
var idUsng = charIDToTypeID( "Usng" );
var idADSt = charIDToTypeID( "ADSt" );
var idAdCH = charIDToTypeID( "AdCH" );
desc583.putEnumerated( idUsng, idADSt, idAdCH );
executeAction( idAlgn, desc583, DialogModes.NO );
var idAlgn = charIDToTypeID( "Algn" );
var desc584 = new ActionDescriptor();
var idnull = charIDToTypeID( "null" );
var ref335 = new ActionReference();
var idLyr = charIDToTypeID( "Lyr " );
var idOrdn = charIDToTypeID( "Ordn" );
var idTrgt = charIDToTypeID( "Trgt" );
ref335.putEnumerated( idLyr, idOrdn, idTrgt );
desc584.putReference( idnull, ref335 );
var idUsng = charIDToTypeID( "Usng" );
var idADSt = charIDToTypeID( "ADSt" );
var idAdCV = charIDToTypeID( "AdCV" );
desc584.putEnumerated( idUsng, idADSt, idAdCV );
executeAction( idAlgn, desc584, DialogModes.NO );
}
//------------------------------------------Align to selection End------------------------------------------------
// ================================================================================================== //
// ========================CORE FUNTION ============================================================= //
// ================================================================================================== //
/*-----------------------startScriptPurpose------------------------------------------------------------- */
function startScriptPurpose() {
// VARIABLES ====================================================================================== //
var docRef = app.activeDocument;
var docLys = docRef.layers.length; // All document's layers //
var allLys = 0; // All layers (counter) //
var allSts = 0; // All sets (counter) //
var actLay; // The active layer is going to be placed here //
var prevLay; // Previous active layer is going to be placed here //
var vis; //Used to hold if layer is visible "true" / "false"
var setArray = []; // Detected sets are goingto be placed here //
var cnt = 0; // Counter for the main layers loop //
var bestHeightFontSize;
var bestWidthFontSize;
// FUNCTIONS ============================================================================================ //
// ============First run this function to select square==================================================================== //
function squareLay (lyr)
{
actLay = lyr
docRef.activeLayer = prevLay // Set the active layer //
var layerName = actLay.name; //replace with function input
var idsetd = charIDToTypeID( "setd" );
var desc3 = new ActionDescriptor();
var idnull = charIDToTypeID( "null" );
var ref1 = new ActionReference();
var idChnl = charIDToTypeID( "Chnl" );
var idfsel = charIDToTypeID( "fsel" );
ref1.putProperty( idChnl, idfsel );
desc3.putReference( idnull, ref1 );
var idT = charIDToTypeID( "T " );
var ref2 = new ActionReference();
var idChnl = charIDToTypeID( "Chnl" );
var idChnl = charIDToTypeID( "Chnl" );
var idTrsp = charIDToTypeID( "Trsp" );
ref2.putEnumerated( idChnl, idChnl, idTrsp );
var idLyr = charIDToTypeID( "Lyr " );
ref2.putName( idLyr, layerName );
desc3.putReference( idT, ref2 );
executeAction( idsetd, desc3, DialogModes.NO );
}
// ==================================================================================================== //
//------------------resizeText function-------------------------
function resizeText (lyr)
{
actLay = lyr // fill variable with the text layer
docRef.activeLayer = prevLay // Set the active layer - i.e. select the square//
resizeLayerName = actLay.name;
app.activeDocument.activeLayer.textItem.kind = TextType.POINTTEXT; // TextType.POINTTEXT /PARAGRAPHTEXT
//Set units to pixels for ease of code
var strtRulerUnits = app.preferences.rulerUnits;
app.preferences.rulerUnits = Units.PIXELS;
UnitValue.baseUnit = UnitValue (1/72, "in");
var bounds = activeDocument.selection.bounds;
var maxWidth = bounds[2] - bounds[0]
var maxHeight = bounds[3]- bounds[1]
//alert("maxWidth =" + maxWidth + "\n"+ "maxHeight = " + maxHeight);
var nameLayer = prevLay; //
var scale = 10;
var direction = -1;
var maxError = 1;
var sizeDiff ;
var resizePercentageWidth ;
var resizePercentageHeight ;
var artLayerRef = activeDocument.activeLayer;
//-----------------Duplicate and raster----------------
var newLayer = artLayerRef.duplicate(); //duplicate active layer
activeDocument.activeLayer = newLayer; //select activelayer
// ----------------Remove LayerStyle----------------
var ref = new ActionReference();
ref.putEnumerated( charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );
if(executeActionGet(ref).hasKey(stringIDToTypeID('layerEffects')))
{
executeAction( stringIDToTypeID('disableLayerStyle'), undefined, DialogModes.NO );
}
// ----------------Remove LayerStyle----------------
newLayer.rasterize(RasterizeType.ENTIRELAYER); //raster active layer
var width = newLayer.bounds[2] - newLayer.bounds[0];
var height = newLayer.bounds[3] - newLayer.bounds[1];
// var width = activeDocument.activeLayer.bounds[2] - activeDocument.activeLayer.bounds[0];
// var height = activeDocument.activeLayer.bounds[3] - activeDocument.activeLayer.bounds[1];
// alert ("width = " + width + "\n"+ "height = " + height);
resizePercentageWidth = maxWidth/width*100;
resizePercentageHeight = maxHeight/height*100;
// alert("maxWidth =" + maxWidth + "\n"+ "maxHeight = " + maxHeight + "\n"+ "textwidth =" +width + "\n"+"textheight ="+ height + "\n"+ "resizePercentageWidth =" + resizePercentageWidth + "\n"+ "resizePercentageHeight = " + resizePercentageHeight );
//Which is smaller
newLayer.remove();
if (resizePercentageHeight > resizePercentageWidth)
{
nameLayer.resize (resizePercentageWidth, resizePercentageWidth);
alignToSelection()
}
else if (resizePercentageHeight < resizePercentageWidth)
{
nameLayer.resize (resizePercentageHeight,resizePercentageHeight);
alignToSelection()
}
}
//---------------------End of resizeText function-------------------------
// ==================================================================================================== //
function hide (hideMe)
{
docRef.activeLayer = hideMe ;
var idHd = charIDToTypeID( "Hd " );
var desc161 = new ActionDescriptor();
var idnull = charIDToTypeID( "null" );
var list25 = new ActionList();
var ref84 = new ActionReference();
var idLyr = charIDToTypeID( "Lyr " );
var idOrdn = charIDToTypeID( "Ordn" );
var idTrgt = charIDToTypeID( "Trgt" );
ref84.putEnumerated( idLyr, idOrdn, idTrgt );
list25.putReference( ref84 );
desc161.putList( idnull, list25 );
executeAction( idHd, desc161, DialogModes.NO );
//----------------Next Release Selection
var idsetd = charIDToTypeID( "setd" );
var desc187 = new ActionDescriptor();
var idnull = charIDToTypeID( "null" );
var ref94 = new ActionReference();
var idChnl = charIDToTypeID( "Chnl" );
var idfsel = charIDToTypeID( "fsel" );
ref94.putProperty( idChnl, idfsel );
desc187.putReference( idnull, ref94 );
var idT = charIDToTypeID( "T " );
var idOrdn = charIDToTypeID( "Ordn" );
var idNone = charIDToTypeID( "None" );
desc187.putEnumerated( idT, idOrdn, idNone );
executeAction( idsetd, desc187, DialogModes.NO );
}
// ==================================================================================================== //
function activeLay (lyr,visible)
{
actLay = lyr
docRef.activeLayer = actLay // Set the active layer //
vis = visible;
var layerName = actLay.name; //replace with function input
var hideLayer ;
if (vis == "true")
{
if ( (actLay.visible) && (actLay.kind == LayerKind.TEXT ) )
{
prevLay = actLay;
}
else if ( (actLay.visible) && (actLay.kind == LayerKind.NORMAL ) ) //Should kick in after a text layer was found previous round
{
if( (prevLay.visible) && (prevLay.kind == LayerKind.TEXT ) )
{
hideLayer =actLay;
squareLay (actLay);
resizeText (prevLay);
hide (hideLayer);
prevLay = 0; // makes sure that only 1 square is used for scalling - clears the buit that make prevLay the last Text layer to be active
}
}
}
else if (vis =="false")
{
app.activeDocument.activeLayer.visible = !app.activeDocument.activeLayer.visible;
}
}
// ==================================================================================================== //
function setInArray (set){
//if (set.typename == 'LayerSet')
if ((set.typename == 'LayerSet') && (set.visible == true))
{
allSts ++
setArray.push (set) // Place the set in the array //
}
else{
allLys ++
}
}
// ==================================================================================================== //
function loopInSets (set){ // Loop trough nested layers //
var length = set.layers.length-1 // All layers in the set //
for (i=0; i<=length; i++)
{
if ((set.layers.visible) && (set.layers.kind == LayerKind.TEXT ))
{
activeLay (set.layers,"true") // Set active layer //
setInArray (actLay) // Place subsets in the array //
}
else if ((set.layers.visible != true ) && (set.layers.kind == LayerKind.TEXT ))
{
activeLay (set.layers,"false") // Set active layer //
setInArray (actLay) // Place subsets in the array //
}
else if (set.layers.visible) // if it's a square it needs to be sent through
{
activeLay (set.layers,"true") // Set active layer //
setInArray (actLay) // Place subsets in the array //
}
else if (set.layers.visible != true )
{
activeLay (set.layers,"false") // Set active layer //
setInArray (actLay) // Place subsets in the array //
}
}
setArray.splice (0,1) // Remove the checked set from the array //
}
// GET STARTING TIME ================================================================================== //
var stDate = new Date () // Get starting date //
var stTime = stDate.getTime () // Get starting time //
// START PROCESS ====================================================================================== //
try{
while ( cnt !== docLys+1)
{
if (docRef.layers[cnt].visible)
{
activeLay (docRef.layers[cnt],"true") // Set active layer //
setInArray (actLay) // Check for set //
cnt ++
}
else if (docRef.layers[cnt].visible != true)
{
// activeLay (docRef.layers[cnt],"false") // Set active layer //
// setInArray (actLay) // Check for set //
cnt ++
}
}
}
catch (e)
{ // Catch error when doument`s layers end // Loop trough sets //
while ( setArray.length !==0 )
{ // Loop until the array is not empty //
loopInSets (setArray[0]) // Always work with the 0 element in the array //
}
}
}
// ================================================================================================== //
/*============================================================================================*/
/*----------- Start Up The script----------------------------*/
initTextResize();
Explore related tutorials & articles
Copy link to clipboard
Copied
This is an example of AM code that evaluates Type Layer (in this case only the text content) – thanks to Paul Riggott and Mike Hale.
Instead of collecting the text one could use the function "selectLayerByIndex" to select the Layer and transform it.
// 2014, use it at your own risk;
#target "photoshop-70.032"
if (app.documents.length > 0) {
main ();
};
////////////////////////////////////
function main () {
// get number of layers;
var ref = new ActionReference();
ref.putEnumerated( charIDToTypeID("Dcmn"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );
var applicationDesc = executeActionGet(ref);
var theNumber = applicationDesc.getInteger(stringIDToTypeID("numberOfLayers"));
//////
var theArray = new Array;
for (var m = 0; m <= theNumber; m++) {
try {
var ref = new ActionReference();
ref.putIndex( charIDToTypeID( "Lyr " ), m);
var layerDesc = executeActionGet(ref);
// if text layer collect values;
if (layerDesc.hasKey(stringIDToTypeID('textKey')) == true) {
var theName = layerDesc.getString(stringIDToTypeID('name'));
var textDesc = layerDesc.getObjectValue(stringIDToTypeID('textKey'));
theArray.push(textDesc.getString(stringIDToTypeID('textKey')));
};
}
catch (e) {};
};
alert (theArray.join("\n"))
};
// by mike hale, via paul riggott;
// http://forums.adobe.com/message/1944754#1944754
function selectLayerByIndex(index,add){
add = undefined ? add = false:add
var ref = new ActionReference();
ref.putIndex(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);
}
};
Copy link to clipboard
Copied
Thanks! I'll let you know if I can get my script working with this, cheers!
Copy link to clipboard
Copied
Took a little while but I managed to get it all working - it's 1000x faster thanks!!!

