• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

Rotate layers incremental script

New Here ,
Apr 16, 2019 Apr 16, 2019

Copy link to clipboard

Copied

hello!

I have 8 layers (photos) each one rotated 45º.

I want counter rotate all layers automatically but I don’t know how do a script that rotate each layer incrementally

something like:

layer.index * 45

result

layer0 = 0º

layer1 = 45º

layer2 = 90º

layer3 = 135º

...

layer8 = 315º

it would be nice a menu to indicate angle of rotation and a checkbox for clockwise or counterclockwise

Thanks!

TOPICS
Actions and scripting

Views

2.7K

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe
Community Expert ,
Apr 17, 2019 Apr 17, 2019

Copy link to clipboard

Copied

It is easy to rotate a layer about a point.  You need to know what x,y point  and the angle.  You can use layer bounds to get the anchor points for the layer.  The rotation point can be any x,y point you want to use.  Make the layer the active layer and use a function like this this rotate the layer.  To code your dialog will be much more complex.

function rotateAroundPosition(_angle,x,y) { 

    var desc1 = new ActionDescriptor(); 

    var desc2 = new ActionDescriptor(); 

    var ref1 = new ActionReference(); 

    ref1.putEnumerated(charIDToTypeID('Lyr '), charIDToTypeID('Ordn'), charIDToTypeID('Trgt')); 

    desc1.putReference(charIDToTypeID('null'), ref1); 

    desc1.putEnumerated(charIDToTypeID('FTcs'), charIDToTypeID('QCSt'), stringIDToTypeID("QCSIndependent")); 

    desc2.putUnitDouble(charIDToTypeID('Hrzn'), charIDToTypeID('#Pxl'), x); 

    desc2.putUnitDouble(charIDToTypeID('Vrtc'), charIDToTypeID('#Pxl'), y); 

    desc1.putObject(charIDToTypeID('Pstn'), charIDToTypeID('Pnt '), desc2); 

    desc1.putUnitDouble(charIDToTypeID('Angl'), charIDToTypeID('#Ang'), _angle); 

    desc1.putEnumerated(charIDToTypeID('Intr'), charIDToTypeID('Intp'), charIDToTypeID('Bcbc')); 

    executeAction(charIDToTypeID('Trnf'), desc1, DialogModes.NO); 

}

JJMack

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Apr 17, 2019 Apr 17, 2019

Copy link to clipboard

Copied

Wow thanks for your response and time!

I did not thought that was need too much code only for rotate a layer from center point! Amazing

Your code will rotate all layers selected incrementally automatically? I mean if I selected 7 layers of my 8 layers (layer 0 no need be rotated), each layer will rotate 45º incrementally: layer 1 = 45º, Layer 2 = 90º, Layer 3 = 135º .... Layer 7 = 315º ?

I tried to put your code to a .js file, select a layer and launch but seems that nothing happen. Maybe I need to change something in script to work...

Thanks!

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Apr 17, 2019 Apr 17, 2019

Copy link to clipboard

Copied

You need to pass the function three variables +-Angle the X point position and the y point position. anf the layer yow want toe be rotated need to be the document active layer.

The function is used in my rotate layers about script.  A script the duplicates a layer and rotate it about poins  a number of times to do full 360 rotation.

// 2015  John J. McAssey (JJMack)

// ======================================================= */

// This script is supplied as is. It is provided as freeware.

// The author accepts no liability for any problems arising from its use.

// enable double-clicking from Mac Finder or Windows Explorer

#target photoshop // this command only works in Photoshop CS2 and higher

// bring application forward for double-click events

app.bringToFront();

// ensure at least one document open

if (!documents.length) alert('There are no documents open.', 'No Document');

else {

//Set First Time Defaults here

var dfltCpys = 12; // default number of copies including the original

var dfltPos = 4; // default Middle Center

//End Defaults

var Prefs ={}; //Object to hold preferences.

var prefsFile = File(Folder.temp + "/RotateLayerAboutPreferences.dat");

//If preferences do not exit use Defaults from above

if(!prefsFile.exists){

Prefs.Cpys  = dfltCpys;

Prefs.Pos  = dfltPos;

prefsFile.open('w');

prefsFile.write(Prefs.toSource());

prefsFile.close();

}

else{//Preferences exist so open them

prefsFile.open('r');

Prefs = eval(prefsFile.read());

prefsFile.close();

}

try {

function createDialog(){

// begin dialog layout

var DupRotateDialog = new Window('dialog');

DupRotateDialog.text = 'Duplicate and Rotate Layer';

DupRotateDialog.frameLocation = [78, 100];

DupRotateDialog.alignChildren = 'center';

DupRotateDialog.NumLayerPnl = DupRotateDialog.add('panel', [2, 2, 300, 56], 'Number of Layers and Rotation Anchor Point');

DupRotateDialog.NumLayerPnl.add('statictext', [10, 16, 50, 48], 'Copies ');

DupRotateDialog.NumLayerPnl.imgCpysEdt = DupRotateDialog.NumLayerPnl.add('edittext', [50, 13, 90, 34], Prefs.Cpys, {name:'imgCpys'});

DupRotateDialog.NumLayerPnl.imgCpysEdt.helpTip = 'Number of copies of selected Layer';

DupRotateDialog.NumLayerPnl.add('statictext',[96, 16, 240, 48],'Location');

var position =['Top Left','Top Center','Top Right','Center Left','Center','Center Right','Bottom Left','Bottom Center','Bottom Right','Doc Center','Samples','Path Points'];

DupRotateDialog.NumLayerPnl.dd1 = DupRotateDialog.NumLayerPnl.add('dropdownlist',[150, 13, 260, 34],position);

DupRotateDialog.NumLayerPnl.dd1.selection=Prefs.Pos;

var buttons = DupRotateDialog.add('group');

buttons.orientation = 'row';

var okBtn = buttons.add('button');

okBtn.text = 'OK';

okBtn.properties = {name: 'ok'};

var cancelBtn = buttons.add('button');

cancelBtn.text = 'Cancel';

cancelBtn.properties = {name: 'cancel'};

return DupRotateDialog;

}

dispdlg(createDialog());

function dispdlg(DupRotateDialog){

// display dialog and only continues on OK button press (OK = 1, Cancel = 2)

DupRotateDialog.onShow = function() {

var ww = DupRotateDialog.bounds.width; 

var hh = DupRotateDialog.bounds.height; 

DupRotateDialog.bounds.x  = 78; 

DupRotateDialog.bounds.y  = 100; 

DupRotateDialog.bounds.width  = ww; 

DupRotateDialog.bounds.height  = hh; 

}

if (DupRotateDialog.show() == 1) {

//variables passed from user interface

var copies = String(DupRotateDialog.NumLayerPnl.imgCpys.text); if (copies=="") { copies = Prefs.Cpys;}

if (isNaN(copies)) { alert("Non numeric value entered"); dispdlg(createDialog());}

else {

if (copies<2 || copies>360) { alert("Number of layer allow is 2 to 360"); dispdlg(createDialog());}  // Not in range

else {

var AnchorPoint = Number(DupRotateDialog.NumLayerPnl.dd1.selection.index) + 1;

cTID = function(s) { return app.charIDToTypeID(s); };

sTID = function(s) { return app.stringIDToTypeID(s); };

// Save the current preferences

Prefs.Cpys  = copies;

Prefs.Pos  = Number(DupRotateDialog.NumLayerPnl.dd1.selection.index);

prefsFile.open('w');

prefsFile.write(Prefs.toSource());

prefsFile.close();

var startRulerUnits = app.preferences.rulerUnits;

var startTypeUnits = app.preferences.typeUnits;

var startDisplayDialogs = app.displayDialogs;

// Set Photoshop to use pixels and display no dialogs

app.preferences.rulerUnits = Units.PIXELS;

app.preferences.typeUnits = TypeUnits.PIXELS;

app.displayDialogs = DialogModes.NO;

app.togglePalettes();

try { app.activeDocument.suspendHistory('RotateLayerAbout','main(copies, AnchorPoint)' );}

catch(e) {alert(e + ': on line ' + e.line);}

// Return the app preferences

app.togglePalettes();

app.preferences.rulerUnits = startRulerUnits;

app.preferences.typeUnits = startTypeUnits;

app.displayDialogs = startDisplayDialogs;

}

}

}

else {

//alert('Operation Canceled.');

}

}

}

catch(err){

// Lot's of things can go wrong, Give a generic alert and see if they want the details

if ( confirm("Sorry, something major happened and I can't continue! Would you like to see more info?" ) ) { alert(err + ': on line ' + err.line ); }

}

}

function main(stemsAmount, Position) {

if  (  Position == 11 && app.activeDocument.colorSamplers.length==0 ) {

alert("No Color Sampler set");

return;

}

if  (  Position == 12 ) {

var thePath = selectedPath();

if (thePath == undefined) {

alert("No Path Selected");

return;

}

var myPathInfo = extractSubPathInfo(thePath); 

}

// Save selected layer to variable:

var originalStem = app.activeDocument.activeLayer;

// Run the copying process

if(stemsAmount != null){

// Calculate the rotation angle

var angle = 360 / parseInt(stemsAmount);

// Create a group for stems

var stemsGroup = app.activeDocument.layerSets.add();

stemsGroup.name = originalStem.name + " ("+stemsAmount+" stems)";

// Place original layer in group

originalStem.move(stemsGroup, ElementPlacement.INSIDE);

// Duplicate and rotate layers:

for(var i = 1; i < stemsAmount; i++){

// Duplicate original layer and save it to the variable

var newStem = originalStem.duplicate();

// Rotate new layer

switch (Position){

case 1 : newStem.rotate(angle * i, AnchorPosition.TOPLEFT); break;

case 2 : newStem.rotate(angle * i, AnchorPosition.TOPCENTER); break;

case 3 : newStem.rotate(angle * i, AnchorPosition.TOPRIGHT); break;

case 4 : newStem.rotate(angle * i, AnchorPosition.MIDDLELEFT); break;

case 5 : newStem.rotate(angle * i, AnchorPosition.MIDDLECENTER); break;

case 6 : newStem.rotate(angle * i, AnchorPosition.MIDDLERIGHT); break;

case 7 : newStem.rotate(angle * i, AnchorPosition.BOTTOMLEFT); break;

case 8 : newStem.rotate(angle * i, AnchorPosition.BOTTOMCENTER); break;

case 9 : newStem.rotate(angle * i, AnchorPosition.BOTTOMRIGHT); break;

case 10 : app.activeDocument.activeLayer = newStem; rotateAroundPosition(angle * i,activeDocument.width/2,activeDocument.height/2); break;

case 11 : for (var s=0,len=app.activeDocument.colorSamplers.length;s<len;s++) {

if (s!=0) {

// Duplicate original layer and save it to the variable

var newStem = originalStem.duplicate();

}

newStem.name = originalStem.name + " " + (i+1) + " p" + (s+1) ;

app.activeDocument.activeLayer = newStem;

var colorSamplerRef = app.activeDocument.colorSamplers;

//alert("angle=" + (angle * i) +  " ,x=" + colorSamplerRef.position[0].value + " ,y=" + colorSamplerRef.position[1].value);

rotateAroundPosition(angle * i,colorSamplerRef.position[0].value,colorSamplerRef.position[1].value);

newStem.move(stemsGroup, ElementPlacement.PLACEATEND);

                };

break;

case 12 : for(var k=0;k<myPathInfo.length;k++){ 

for(var j=0;j<myPathInfo.entireSubPath.length;j++){

if (k!=0 || j!=0) {

// Duplicate original layer and save it to the variable

var newStem = originalStem.duplicate();

}

newStem.name = originalStem.name + " " + (i+1) + " p" + (j+1) ;

app.activeDocument.activeLayer = newStem;

rotateAroundPosition(angle * i,myPathInfo.entireSubPath.anchor[0],myPathInfo.entireSubPath.anchor[1]);

newStem.move(stemsGroup, ElementPlacement.PLACEATEND);

}

}

break;

default : break;

}

// Add index to new layers

if (Position!=11) {

newStem.name = originalStem.name + " " + (i+1);

// Place new layer inside stems group

newStem.move(stemsGroup, ElementPlacement.PLACEATEND);

}

};

// Add index to the original layer

if (Position!=11) originalStem.name += " 1";

else originalStem.name += " 1 p1";

};

activeDocument.activeLayer = activeDocument.layers[0]; // Target top

var groupname = app.activeDocument.activeLayer.name // remember name of group 

var idungroupLayersEvent = stringIDToTypeID( "ungroupLayersEvent" ); // this part from  Script Listene -- ungroup group 

var desc14 = new ActionDescriptor(); 

var idnull = charIDToTypeID( "null" ); 

var ref13 = new ActionReference(); 

var idLyr = charIDToTypeID( "Lyr " ); 

var idOrdn = charIDToTypeID( "Ordn" ); 

var idTrgt = charIDToTypeID( "Trgt" ); 

ref13.putEnumerated( idLyr, idOrdn, idTrgt ); 

desc14.putReference( idnull, ref13 ); 

executeAction( idungroupLayersEvent, desc14, DialogModes.NO ); 

var idMk = charIDToTypeID( "Mk  " ); // this part from  Script Listene --  group selected layers 

var desc15 = new ActionDescriptor(); 

var idnull = charIDToTypeID( "null" ); 

var ref14 = new ActionReference(); 

var idlayerSection = stringIDToTypeID( "layerSection" ); 

ref14.putClass( idlayerSection ); 

desc15.putReference( idnull, ref14 ); 

var idFrom = charIDToTypeID( "From" ); 

var ref15 = new ActionReference(); 

var idLyr = charIDToTypeID( "Lyr " ); 

var idOrdn = charIDToTypeID( "Ordn" ); 

var idTrgt = charIDToTypeID( "Trgt" ); 

ref15.putEnumerated( idLyr, idOrdn, idTrgt ); 

desc15.putReference( idFrom, ref15 ); 

executeAction( idMk, desc15, DialogModes.NO ); 

app.activeDocument.activeLayer.name = groupname // recall group name 

}

function rotateAroundPosition(_angle,x,y) { 

    var desc1 = new ActionDescriptor(); 

    var desc2 = new ActionDescriptor(); 

    var ref1 = new ActionReference(); 

    ref1.putEnumerated(charIDToTypeID('Lyr '), charIDToTypeID('Ordn'), charIDToTypeID('Trgt')); 

    desc1.putReference(charIDToTypeID('null'), ref1); 

    desc1.putEnumerated(charIDToTypeID('FTcs'), charIDToTypeID('QCSt'), stringIDToTypeID("QCSIndependent")); 

    desc2.putUnitDouble(charIDToTypeID('Hrzn'), charIDToTypeID('#Pxl'), x); 

    desc2.putUnitDouble(charIDToTypeID('Vrtc'), charIDToTypeID('#Pxl'), y); 

    desc1.putObject(charIDToTypeID('Pstn'), charIDToTypeID('Pnt '), desc2); 

    desc1.putUnitDouble(charIDToTypeID('Angl'), charIDToTypeID('#Ang'), _angle); 

    desc1.putEnumerated(charIDToTypeID('Intr'), charIDToTypeID('Intp'), charIDToTypeID('Bcbc')); 

    executeAction(charIDToTypeID('Trnf'), desc1, DialogModes.NO); 

}

////// determine selected path //////

function selectedPath () {

try {

var ref = new ActionReference();

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

var desc = executeActionGet(ref);

var theName = desc.getString(charIDToTypeID("PthN"));

return app.activeDocument.pathItems.getByName(theName)

}

catch (e) {

return undefined

}

};

////// michael l hale’s code //////

function extractSubPathInfo(pathObj){ 

    var pathArray = new Array();// each element can be used as the second arugment in pathItems.add ie doc.pathItems.add("myPath1", [pathArray[0]]); 

    var pl = pathObj.subPathItems.length; 

    for(var s=0;s<pl;s++){ 

        var pArray = new Array(); 

          for(var i=0;i<pathObj.subPathItems.pathPoints.length;i++){ 

             pArray = new PathPointInfo; 

             pArray.kind = pathObj.subPathItems.pathPoints.kind; 

             pArray.anchor = pathObj.subPathItems.pathPoints.anchor; 

//alert("Anchor " + pathObj.subPathItems.pathPoints.anchor );

             pArray.leftDirection = pathObj.subPathItems.pathPoints.leftDirection; 

             pArray.rightDirection = pathObj.subPathItems.pathPoints.rightDirection; 

          }; 

        pathArray[pathArray.length] = new Array(); 

        pathArray[pathArray.length - 1] = new SubPathInfo(); 

        pathArray[pathArray.length - 1].operation = pathObj.subPathItems.operation; 

        pathArray[pathArray.length - 1].closed = pathObj.subPathItems.closed; 

        pathArray[pathArray.length - 1].entireSubPath = pArray; 

    }; 

    return pathArray; 

};

Higher resolution work better

JJMack

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Apr 17, 2019 Apr 17, 2019

Copy link to clipboard

Copied

Thanks again,

I try to replace _angle by 45

x (in pixels) by canvas size x /2

y (in pixels) by canvas size y /2

Unfortunately I get an error... (error 17, expected variable name)

And seems that I need a loop with some kind of increment to achieve that all layers selected become rotated +45 degrees incrementally. Maybe If we know layer index value to multiply this number by 45...

In After Effects expresions is with layer.index but no idea with script fo Photoshop.

Logic part is something like:

angleIncrement = 45

angle = 0

centerX = (document size X) / 2

centerY = (document size Y) / 2

For each selected layer do:

     rotate layer.index(1) by angle

     angle = layer.index(1) * angleIncrement

end for

Thanks!

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Apr 17, 2019 Apr 17, 2019

Copy link to clipboard

Copied

If you get an error messages and can not figure out why. You neet to post the actual script code you are executind and a screen capture the show your document and Photoshop UI like layers palette etc when the error message showing. For you do not seem to know what is going on and therefore can not state what the problems is.  The Function I gave you rotate the active layer  using the values you pass.

You wrote " I get an error... (error 17, expected variable name)" and  you did  not show the line number of the script code you use or or the script code.

My car will not start why?  Can you give me the correct reason why?   ...

JJMack

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Apr 18, 2019 Apr 18, 2019

Copy link to clipboard

Copied

Sorry, You are right!

function rotateAroundPosition(45,2048,2048) {

    var desc1 = new ActionDescriptor();

    var desc2 = new ActionDescriptor();

    var ref1 = new ActionReference();

    ref1.putEnumerated(charIDToTypeID('Lyr '), charIDToTypeID('Ordn'), charIDToTypeID('Trgt'));

    desc1.putReference(charIDToTypeID('null'), ref1);

    desc1.putEnumerated(charIDToTypeID('FTcs'), charIDToTypeID('QCSt'), stringIDToTypeID("QCSIndependent"));

    desc2.putUnitDouble(charIDToTypeID('Hrzn'), charIDToTypeID('#Pxl'), x);

    desc2.putUnitDouble(charIDToTypeID('Vrtc'), charIDToTypeID('#Pxl'), y);

    desc1.putObject(charIDToTypeID('Pstn'), charIDToTypeID('Pnt '), desc2);

    desc1.putUnitDouble(charIDToTypeID('Angl'), charIDToTypeID('#Ang'), _angle);

    desc1.putEnumerated(charIDToTypeID('Intr'), charIDToTypeID('Intp'), charIDToTypeID('Bcbc'));

    executeAction(charIDToTypeID('Trnf'), desc1, DialogModes.NO);

}

error.png

layers.png

Red numbers point angles of rotation of images that I want to counter-rotate to align with Photomerge.

Thanks agains

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Advocate ,
Apr 18, 2019 Apr 18, 2019

Copy link to clipboard

Copied

Can't you just use something like this?

app.activeDocument.activeLayer.rotate(45, AnchorPosition.MIDDLECENTER)

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Apr 18, 2019 Apr 18, 2019

Copy link to clipboard

Copied

Thanks Tom!

Sorry but I don't know nothing about PS scripting. I dont know if this works, reading this line seems be correct. But

I don't want rotate only one layer. I want to rotate al selected layers at time, but with every layer I want to increment angle by 45º. I need know how to write a "for" loop and know how increment angle by 45 with next layer in each loop...

Thanks!

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Apr 18, 2019 Apr 18, 2019

Copy link to clipboard

Copied

edene8699004  wrote

Sorry but I don't know nothing about PS scripting.

Then you need to learn about scripting languages supported by Adobe Scriptingsupport plug-in and learn how to code in one I would suggest JavaScript.  You also need to learn about Adobe Photoshop Document Object Model.  A Photoshop DOM code.  All of Photoshop features are not covered by  Adobe's Photoshop DOM.  So some of the code posted here is Photoshop Action Manager code to do thins not possible with Adobe DOM  Code.   Action manager code is not very readable.]

The following is DOM code for rotating a layer about one of its 9 anchor points.

"app.activeDocument.activeLayer.rotate(45, AnchorPosition.MIDDLECENTER);" 

The following is a  function created with action manager cod the can do the same thing but the rotations is not limited to rotating about an anchor point.  You can use any point to rotate a layer about. The point does not need to be within the layers bounds even.

function rotateAroundPosition(_angle,x,y) {

    var desc1 = new ActionDescriptor();

    var desc2 = new ActionDescriptor();

    var ref1 = new ActionReference();

    ref1.putEnumerated(charIDToTypeID('Lyr '), charIDToTypeID('Ordn'), charIDToTypeID('Trgt'));

    desc1.putReference(charIDToTypeID('null'), ref1);

    desc1.putEnumerated(charIDToTypeID('FTcs'), charIDToTypeID('QCSt'), stringIDToTypeID("QCSIndependent"));

    desc2.putUnitDouble(charIDToTypeID('Hrzn'), charIDToTypeID('#Pxl'), x);

    desc2.putUnitDouble(charIDToTypeID('Vrtc'), charIDToTypeID('#Pxl'), y);

    desc1.putObject(charIDToTypeID('Pstn'), charIDToTypeID('Pnt '), desc2);

    desc1.putUnitDouble(charIDToTypeID('Angl'), charIDToTypeID('#Ang'), _angle);

    desc1.putEnumerated(charIDToTypeID('Intr'), charIDToTypeID('Intp'), charIDToTypeID('Bcbc'));

    executeAction(charIDToTypeID('Trnf'), desc1, DialogModes.NO);

}

You could heir a programmer of perhaps you know a programmer that can help you learn or create the script you want.  Rotating a layer is only a small part of what you want the script to do.  You want it  to have some kind of Script UI.  You need to design how that UI will function and code it.  That is way more complex then rotating a layer.

There is much you need to learn if you want to Script Photoshop.  Even to hack at it like I do.  I do not know javascript but can hack at javascript using a reference and web searching.  I know quit a bit about how Photoshop works. I been using it foe 20+ years.   I was a Programmer before I retired. So I know something about programming and design  processes.  There is a Adobe Photoshop Plug-in Scriptlisener you can install that is somewhat like an Action Recorder.  However it has no controls and the Action steps are recorded into two log file one your desktop.   The steps are recorded as VSB code and JavaScript coded steps.  The steps are like  Action steps everything is hard coded. No logic just step step like actions.  However you can  modify the recorded code.  Program functions that you pass variable to.  The functions use these variables instead of the hard coded values recorded in the Scriptlisener recorded code.

That is how the above function was created.   _angle, x, y are thee variable name  that will be passed that are use in the step to replace what was hard coded by the plug-in. You should be able to see where the substations was done.  You should see _angle and  x and  y being used within the function

Adobe Photoshop Scripting

Scripting in Photoshop

JJMack

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Apr 18, 2019 Apr 18, 2019

Copy link to clipboard

Copied

A friend help my with code and this works:

var doc = app.activeDocument;

var angle = 45;

function rotateEachLayer() {

    for ( var i = 0; i < doc.layers.length; i++ ) {

        var item = doc.layers;

        var incrementalAngle = i * angle;

        item.rotate( incrementalAngle );

    }

}

rotateEachLayer();

-------

Only one thing. You know how use only selected layers instead all layers in document?

Thanks!

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Apr 18, 2019 Apr 18, 2019

Copy link to clipboard

Copied

The code you show is using  DOM code to rotate some layers one at a time about its center anchor point and increase the angle or rotation  an  additional 45 degrees for each rotation done.  0, 45, 90, 135,

The some layer will be all layers if your document does not contain layer groups.  It use using  Photoshop layers array.  There is a layers array for each layer group. If you document contains layers groups only the layers document top level will rotate.

If you want to rotate particular layer by name or because they are selected you  need the create an array that contains the layer objects you want to rotate. Then code that for loop for the length of that array.  You would use that array not the documents layers array.

If your document contains layer groups you may need to use recursion to process the layers you want to rotate.

Layers center location can vary.

JJMack

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Apr 19, 2019 Apr 19, 2019

Copy link to clipboard

Copied

You have been quiet for a couple of days now.  How are you doing with your script.

As I wrote I do not know JavaScript but have a programming background.  So I can more or less read JavaScript code to some extent and figure out what it is doing and often can hack at code toe bend it to do what I want to do.  This forum is a great place to find example code. When you want to do something search the forum for code that does something like you want to do, if you can not find a script that does exactly what you want to do.

For example I pretended I was you.  You want to rotate selected layers via a Photoshop script.  That means your script need to know what layers are selected and rotate them.  If it does that the script would need to target each of the selected layers one at a time to rotate each one. The means selection one layer ay a time.  When done rotating the layers the script would need to reselect all the layers that were selected to begin with.  So with those thing in mind  I started to search this forum for JavaScript code.

I found a function that will return an array of the select layers layers ID.  I found a function  the can get a layer by its ID and I found a function that can select  layers by the laye's ID.

So if all you want to do is rotate a layer about it center anchor point to can adapt the code you have to  rotate selected layers. If you want to rotate layers about the document center you would need to use the rotate function I posted where x,y is the canvas center point.

Your RotateSelecedLayers script woul look something like this.

//alert(get_selected_layers_id().toSource())

var selectedLayers = get_selected_layers_id();

var angle = 45;

for ( var i = 0; i < selectedLayers.length; i++ ) {

        var incrementalAngle = i * angle;

        thisLayer = get_layer_by_id(selectedLayers);

        saveVisibility = thisLayer.visible;

        thisLayer.visible = true;

        alert(thisLayer.name + " rotate " + incrementalAngle + " Degrees");

        thisLayer.rotate( incrementalAngle );

        thisLayer.visible = saveVisibility;

}

for ( var i = 0; i < selectedLayers.length; i++ ) { selectLayerByID(selectedLayers,true);}

function get_selected_layers_id() {

        try {

                var r = new ActionReference();

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

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

                var d = executeActionGet(r);

                if (!d.hasKey(stringIDToTypeID("targetLayers"))) {

                        var r = new ActionReference();

                        r.putProperty(charIDToTypeID("Prpr"), stringIDToTypeID("layerID"));

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

                        return [ executeActionGet(r).getInteger(stringIDToTypeID("layerID")) ];

                }

                var list = d.getList(stringIDToTypeID("targetLayers"));

                if (!list) return null;

                var n = 0;

                try { activeDocument.backgroundLayer } catch (e) { n = 1; }

                var len = list.count;

                var selected_layers = new Array();

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

                        try {

                                var r = new ActionReference();

                                r.putProperty(charIDToTypeID("Prpr"), stringIDToTypeID("layerID"));

                                r.putIndex( charIDToTypeID("Lyr "), list.getReference(i).getIndex() + n);

                                selected_layers.push(executeActionGet(r).getInteger(stringIDToTypeID("layerID")));

                        }

                        catch (e) { _alert(e); return null; }

                }

                return selected_layers;

        }

        catch (e) { alert(e); return null; }

}

function get_layer_by_id(id, doc_id) {

        try {

                var doc;

                if (doc_id == undefined) doc = activeDocument;

                else {

                        for (var i = 0; i < documents.length; i++) {

                                if (documents.id == doc_id) {

                                        doc = documents;

                                        break;

                                }

                        }

                }

                if (doc == undefined) { alert("Bad document " + doc_id); return null; }

                var r = new ActionReference();

                r.putProperty(charIDToTypeID("Prpr"), stringIDToTypeID("json"));

                if (doc_id == undefined) r.putEnumerated(charIDToTypeID("Dcmn"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt"));

                else                     r.putIdentifier(charIDToTypeID("Dcmn"), doc_id);

                eval("var json = " + executeActionGet(r).getString(stringIDToTypeID("json")));

                if (json == undefined) return null;

                var set = new Array();

                function search_id(layers, id) {

                        for (var i = 0; i < layers.length; i++) {

                                if (layers.id == id) { set.push(i); return true; }

                        }

                        for (var i = 0; i < layers.length; i++) {

                                if (layers.layers) {

                                        if (search_id(layers.layers, id)) { set.push(i); return true; }

                                }

                        }

                }

                if (search_id(json.layers, id)) {

                        var ret = doc.layers;

                        for (var i = set.length-1; i > 0; i--) { ret = ret[set].layers;}

                        return ret[set[0]];

                }

                return null;

        }

        catch (e) { alert(e); }

}

// based on code by mike hale, via paul riggott;

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 );

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

        catch(e){ alert(e.message); }

};

JJMack

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Apr 20, 2019 Apr 20, 2019

Copy link to clipboard

Copied

Hello again JJMack, thanks for your time and patience.

I have done a search on this forum for "selected layer" function. A friend help me with code and result was:

var doc = app.activeDocument;

var angle = 45;

function SelectedLayers(){ 

    try{ 

        var ActLay = app.activeDocument.activeLayer; 

        ActLay.allLocked = true; //lock all selected layers  

        var LayerStack = app.activeDocument.artLayers.length; 

         

        var selLayers = new Array(); 

        for (var i=0; i<=LayerStack-1; i++){ 

        ActLay = app.activeDocument.layers 

            if (ActLay.allLocked == true){selLayers.push(app.activeDocument.layers);} // push all locked layers into an array 

            } 

 

        for (i=0; i<=LayerStack-1; i++){ 

            var LAY = app.activeDocument.layers

            LAY.allLocked = false; // unlock all locked Layers 

        }                          

    return selLayers;  

    } 

    catch(e){/*alert(e);*/} 

var selectedLayers = SelectedLayers();

function rotateLayers() {   

    for ( var i = 0; i < selectedLayers.length; i++ ) {    

        var item = selectedLayers;

        var incrementalAngle = angle + (i * angle);

            item.rotate( incrementalAngle );

    }

}

rotateLayers();

//alert(selectedLayers);

Seems works correctly, I will try your code too.

Thanks!

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Contributor ,
Mar 06, 2020 Mar 06, 2020

Copy link to clipboard

Copied

Hi JJMack .I'm looking for something like this wonderful Script however, the last two items on the list don't seem to work correctly:
['Samples', 'Path Points']
Does it still work for you? Could you show them funciana? Thanks.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Apr 18, 2019 Apr 18, 2019

Copy link to clipboard

Copied

Its your coding is wrong.  You would use the function in you code like this:

rotateAroundPosition(45,2048,2048);

The function itself has  variables

function rotateAroundPosition(_angle,x,y) {

    var desc1 = new ActionDescriptor();

    var desc2 = new ActionDescriptor();

    var ref1 = new ActionReference();

    ref1.putEnumerated(charIDToTypeID('Lyr '), charIDToTypeID('Ordn'), charIDToTypeID('Trgt'));

    desc1.putReference(charIDToTypeID('null'), ref1);

    desc1.putEnumerated(charIDToTypeID('FTcs'), charIDToTypeID('QCSt'), stringIDToTypeID("QCSIndependent"));

    desc2.putUnitDouble(charIDToTypeID('Hrzn'), charIDToTypeID('#Pxl'), x);

    desc2.putUnitDouble(charIDToTypeID('Vrtc'), charIDToTypeID('#Pxl'), y);

    desc1.putObject(charIDToTypeID('Pstn'), charIDToTypeID('Pnt '), desc2);

    desc1.putUnitDouble(charIDToTypeID('Angl'), charIDToTypeID('#Ang'), _angle);

    desc1.putEnumerated(charIDToTypeID('Intr'), charIDToTypeID('Intp'), charIDToTypeID('Bcbc'));

    executeAction(charIDToTypeID('Trnf'), desc1, DialogModes.NO);

}

X and Y can be any point not just anchor points

JJMack

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Contributor ,
Mar 06, 2020 Mar 06, 2020

Copy link to clipboard

Copied

Hi JJMack .I'm looking for something like this wonderful Script however, the last two items on the list don't seem to work correctly:
['Samples', 'Path Points']
Does it still work for you? Could you show them funciana? Thanks.

 

// 2015  John J. McAssey (JJMack) 

// ======================================================= */

// This script is supplied as is. It is provided as freeware. 

// The author accepts no liability for any problems arising from its use.

// enable double-clicking from Mac Finder or Windows Explorer

#target photoshop // this command only works in Photoshop CS2 and higher

// bring application forward for double-click events

app.bringToFront();

// ensure at least one document open

if (!documents.length) alert('There are no documents open.', 'No Document');

else {

//Set First Time Defaults here

var dfltCpys = 12; // default number of copies including the original

var dfltPos = 4; // default Middle Center

//End Defaults

var Prefs ={}; //Object to hold preferences.

var prefsFile = File(Folder.temp + "/RotateLayerAboutPreferences.dat");

//If preferences do not exit use Defaults from above

if(!prefsFile.exists){

Prefs.Cpys  = dfltCpys;

Prefs.Pos  = dfltPos;

prefsFile.open('w');

prefsFile.write(Prefs.toSource());

prefsFile.close();

}

else{//Preferences exist so open them

prefsFile.open('r');

Prefs = eval(prefsFile.read());

prefsFile.close();

}

try {

function createDialog(){

// begin dialog layout

var DupRotateDialog = new Window('dialog');

DupRotateDialog.text = 'Duplicate and Rotate Layer';

DupRotateDialog.frameLocation = [78, 100];

DupRotateDialog.alignChildren = 'center';

DupRotateDialog.NumLayerPnl = DupRotateDialog.add('panel', [2, 2, 300, 56], 'Number of Layers and Rotation Anchor Point');

DupRotateDialog.NumLayerPnl.add('statictext', [10, 16, 50, 48], 'Copies ');

DupRotateDialog.NumLayerPnl.imgCpysEdt = DupRotateDialog.NumLayerPnl.add('edittext', [50, 13, 90, 34], Prefs.Cpys, {name:'imgCpys'});

DupRotateDialog.NumLayerPnl.imgCpysEdt.helpTip = 'Number of copies of selected Layer';

DupRotateDialog.NumLayerPnl.add('statictext',[96, 16, 240, 48],'Location');

var position =['Top Left','Top Center','Top Right','Center Left','Center','Center Right','Bottom Left','Bottom Center','Bottom Right','Doc Center','Samples','Path Points'];

DupRotateDialog.NumLayerPnl.dd1 = DupRotateDialog.NumLayerPnl.add('dropdownlist',[150, 13, 260, 34],position);

DupRotateDialog.NumLayerPnl.dd1.selection=Prefs.Pos;

var buttons = DupRotateDialog.add('group');

buttons.orientation = 'row';

var okBtn = buttons.add('button');

okBtn.text = 'OK';

okBtn.properties = {name: 'ok'};

var cancelBtn = buttons.add('button');

cancelBtn.text = 'Cancel';

cancelBtn.properties = {name: 'cancel'};

return DupRotateDialog;

}

dispdlg(createDialog());

function dispdlg(DupRotateDialog){ 

// display dialog and only continues on OK button press (OK = 1, Cancel = 2)

DupRotateDialog.onShow = function() {

var ww = DupRotateDialog.bounds.width;  

var hh = DupRotateDialog.bounds.height;  

DupRotateDialog.bounds.x  = 78;  

DupRotateDialog.bounds.y  = 100;  

DupRotateDialog.bounds.width  = ww;  

DupRotateDialog.bounds.height  = hh;  

}

if (DupRotateDialog.show() == 1) {

//variables passed from user interface

var copies = String(DupRotateDialog.NumLayerPnl.imgCpys.text); if (copies=="") { copies = Prefs.Cpys;}

if (isNaN(copies)) { alert("Non numeric value entered"); dispdlg(createDialog());}

else {

if (copies<2 || copies>360) { alert("Number of layer allow is 2 to 360"); dispdlg(createDialog());}  // Not in range

else {

var AnchorPoint = Number(DupRotateDialog.NumLayerPnl.dd1.selection.index) + 1;

cTID = function(s) { return app.charIDToTypeID(s); };

sTID = function(s) { return app.stringIDToTypeID(s); };

// Save the current preferences

Prefs.Cpys  = copies;

Prefs.Pos  = Number(DupRotateDialog.NumLayerPnl.dd1.selection.index);

prefsFile.open('w');

prefsFile.write(Prefs.toSource());

prefsFile.close();

var startRulerUnits = app.preferences.rulerUnits;

var startTypeUnits = app.preferences.typeUnits;

var startDisplayDialogs = app.displayDialogs;

// Set Photoshop to use pixels and display no dialogs

app.preferences.rulerUnits = Units.PIXELS;

app.preferences.typeUnits = TypeUnits.PIXELS;

app.displayDialogs = DialogModes.NO;

app.togglePalettes();

try { app.activeDocument.suspendHistory('RotateLayerAbout','main(copies, AnchorPoint)' );} 

catch(e) {alert(e + ': on line ' + e.line);} 

// Return the app preferences

app.togglePalettes();

app.preferences.rulerUnits = startRulerUnits;

app.preferences.typeUnits = startTypeUnits;

app.displayDialogs = startDisplayDialogs;

}

}

}

else {

//alert('Operation Canceled.');

}

}

}

catch(err){

// Lot's of things can go wrong, Give a generic alert and see if they want the details

if ( confirm("Sorry, something major happened and I can't continue! Would you like to see more info?" ) ) { alert(err + ': on line ' + err.line ); }

}

}

function main(stemsAmount, Position) {

if  (  Position == 11 && app.activeDocument.colorSamplers.length==0 ) {

alert("No Color Sampler set");

return;

}

if  (  Position == 12 ) {

var thePath = selectedPath();

if (thePath == undefined) {

alert("No Path Selected");

return;

}

var myPathInfo = extractSubPathInfo(thePath);  

}

// Save selected layer to variable:

var originalStem = app.activeDocument.activeLayer;

// Run the copying process

if(stemsAmount != null){ 

// Calculate the rotation angle

var angle = 360 / parseInt(stemsAmount);

// Create a group for stems

var stemsGroup = app.activeDocument.layerSets.add();

stemsGroup.name = originalStem.name + " ("+stemsAmount+" stems)";

// Place original layer in group

originalStem.move(stemsGroup, ElementPlacement.INSIDE);

// Duplicate and rotate layers:

for(var i = 1; i < stemsAmount; i++){

// Duplicate original layer and save it to the variable

var newStem = originalStem.duplicate();

// Rotate new layer

switch (Position){

case 1 : newStem.rotate(angle * i, AnchorPosition.TOPLEFT); break;

case 2 : newStem.rotate(angle * i, AnchorPosition.TOPCENTER); break;

case 3 : newStem.rotate(angle * i, AnchorPosition.TOPRIGHT); break;

case 4 : newStem.rotate(angle * i, AnchorPosition.MIDDLELEFT); break;

case 5 : newStem.rotate(angle * i, AnchorPosition.MIDDLECENTER); break;

case 6 : newStem.rotate(angle * i, AnchorPosition.MIDDLERIGHT); break;

case 7 : newStem.rotate(angle * i, AnchorPosition.BOTTOMLEFT); break;

case 8 : newStem.rotate(angle * i, AnchorPosition.BOTTOMCENTER); break;

case 9 : newStem.rotate(angle * i, AnchorPosition.BOTTOMRIGHT); break;

case 10 : app.activeDocument.activeLayer = newStem; rotateAroundPosition(angle * i,activeDocument.width/2,activeDocument.height/2); break;

case 11 : for (var s=0,len=app.activeDocument.colorSamplers.length;s<len;s++) {

if (s!=0) {

// Duplicate original layer and save it to the variable

var newStem = originalStem.duplicate();

}

newStem.name = originalStem.name + " " + (i+1) + " p" + (s+1) ;

app.activeDocument.activeLayer = newStem;

var colorSamplerRef = app.activeDocument.colorSamplers;

//alert("angle=" + (angle * i) +  " ,x=" + colorSamplerRef.position[0].value + " ,y=" + colorSamplerRef.position[1].value);

rotateAroundPosition(angle * i,colorSamplerRef.position[0].value,colorSamplerRef.position[1].value);

newStem.move(stemsGroup, ElementPlacement.PLACEATEND);

                }; 

break; 

case 12 : for(var k=0;k<myPathInfo.length;k++){  

for(var j=0;j<myPathInfo.entireSubPath.length;j++){ 

if (k!=0 || j!=0) {

// Duplicate original layer and save it to the variable

var newStem = originalStem.duplicate();

}

newStem.name = originalStem.name + " " + (i+1) + " p" + (j+1) ;

app.activeDocument.activeLayer = newStem;

rotateAroundPosition(angle * i,myPathInfo.entireSubPath.anchor[0],myPathInfo.entireSubPath.anchor[1]);

newStem.move(stemsGroup, ElementPlacement.PLACEATEND);

}

}

break;

default : break;

}

// Add index to new layers

if (Position!=11) {

newStem.name = originalStem.name + " " + (i+1);

// Place new layer inside stems group

newStem.move(stemsGroup, ElementPlacement.PLACEATEND);

}

};

// Add index to the original layer

if (Position!=11) originalStem.name += " 1";

else originalStem.name += " 1 p1";

};

activeDocument.activeLayer = activeDocument.layers[0]; // Target top

var groupname = app.activeDocument.activeLayer.name // remember name of group  

var idungroupLayersEvent = stringIDToTypeID( "ungroupLayersEvent" ); // this part from  Script Listene -- ungroup group  

var desc14 = new ActionDescriptor();  

var idnull = charIDToTypeID( "null" );  

var ref13 = new ActionReference();  

var idLyr = charIDToTypeID( "Lyr " );  

var idOrdn = charIDToTypeID( "Ordn" );  

var idTrgt = charIDToTypeID( "Trgt" );  

ref13.putEnumerated( idLyr, idOrdn, idTrgt );  

desc14.putReference( idnull, ref13 );  

executeAction( idungroupLayersEvent, desc14, DialogModes.NO );  

var idMk = charIDToTypeID( "Mk  " ); // this part from  Script Listene --  group selected layers  

var desc15 = new ActionDescriptor();  

var idnull = charIDToTypeID( "null" );  

var ref14 = new ActionReference();  

var idlayerSection = stringIDToTypeID( "layerSection" );  

ref14.putClass( idlayerSection );  

desc15.putReference( idnull, ref14 );  

var idFrom = charIDToTypeID( "From" );  

var ref15 = new ActionReference();  

var idLyr = charIDToTypeID( "Lyr " );  

var idOrdn = charIDToTypeID( "Ordn" );  

var idTrgt = charIDToTypeID( "Trgt" );  

ref15.putEnumerated( idLyr, idOrdn, idTrgt );  

desc15.putReference( idFrom, ref15 );  

executeAction( idMk, desc15, DialogModes.NO );  

app.activeDocument.activeLayer.name = groupname // recall group name  

}

function rotateAroundPosition(_angle,x,y) {  

    var desc1 = new ActionDescriptor();  

    var desc2 = new ActionDescriptor();  

    var ref1 = new ActionReference();  

    ref1.putEnumerated(charIDToTypeID('Lyr '), charIDToTypeID('Ordn'), charIDToTypeID('Trgt'));  

    desc1.putReference(charIDToTypeID('null'), ref1);  

    desc1.putEnumerated(charIDToTypeID('FTcs'), charIDToTypeID('QCSt'), stringIDToTypeID("QCSIndependent"));  

    desc2.putUnitDouble(charIDToTypeID('Hrzn'), charIDToTypeID('#Pxl'), x);  

    desc2.putUnitDouble(charIDToTypeID('Vrtc'), charIDToTypeID('#Pxl'), y);  

    desc1.putObject(charIDToTypeID('Pstn'), charIDToTypeID('Pnt '), desc2);  

    desc1.putUnitDouble(charIDToTypeID('Angl'), charIDToTypeID('#Ang'), _angle);  

    desc1.putEnumerated(charIDToTypeID('Intr'), charIDToTypeID('Intp'), charIDToTypeID('Bcbc'));  

    executeAction(charIDToTypeID('Trnf'), desc1, DialogModes.NO);  

}

////// determine selected path //////

function selectedPath () {

try {

var ref = new ActionReference(); 

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

var desc = executeActionGet(ref);

var theName = desc.getString(charIDToTypeID("PthN"));

return app.activeDocument.pathItems.getByName(theName)

}

catch (e) {

return undefined

}

};

////// michael l hale’s code //////

function extractSubPathInfo(pathObj){  

    var pathArray = new Array();// each element can be used as the second arugment in pathItems.add ie doc.pathItems.add("myPath1", [pathArray[0]]);  

    var pl = pathObj.subPathItems.length;  

    for(var s=0;s<pl;s++){  

        var pArray = new Array();  

          for(var i=0;i<pathObj.subPathItems.pathPoints.length;i++){  

             pArray = new PathPointInfo;  

             pArray.kind = pathObj.subPathItems.pathPoints.kind;  

             pArray.anchor = pathObj.subPathItems.pathPoints.anchor;  

//alert("Anchor " + pathObj.subPathItems.pathPoints.anchor );

             pArray.leftDirection = pathObj.subPathItems.pathPoints.leftDirection;  

             pArray.rightDirection = pathObj.subPathItems.pathPoints.rightDirection;  

          };  

        pathArray[pathArray.length] = new Array();  

        pathArray[pathArray.length - 1] = new SubPathInfo();  

        pathArray[pathArray.length - 1].operation = pathObj.subPathItems.operation;  

        pathArray[pathArray.length - 1].closed = pathObj.subPathItems.closed;  

        pathArray[pathArray.length - 1].entireSubPath = pArray;  

    };  

    return pathArray;  

}; 

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Mar 06, 2020 Mar 06, 2020

Copy link to clipboard

Copied

That looks like my script. However the formatting and spacing has been messed up broke the script.  I'll post it again.  The old jive site  often broke script the were posted. Perhaps the changed site java script posting will work better.
Capture.jpg

 

// 2015  John J. McAssey (JJMack) 
// ======================================================= */

// This script is supplied as is. It is provided as freeware. 
// The author accepts no liability for any problems arising from its use.
	
// enable double-clicking from Mac Finder or Windows Explorer
#target photoshop // this command only works in Photoshop CS2 and higher

// bring application forward for double-click events
app.bringToFront();
// ensure at least one document open
if (!documents.length) alert('There are no documents open.', 'No Document');
else {
	//Set First Time Defaults here
	var dfltCpys = 12;	// default number of copies including the original
	var dfltPos = 4;	// default Middle Center
	//End Defaults
	
	var Prefs ={}; //Object to hold preferences.
	var prefsFile = File(Folder.temp + "/RotateLayerAboutPreferences.dat");
	//If preferences do not exit use Defaults from above
	if(!prefsFile.exists){
		Prefs.Cpys  = dfltCpys;
		Prefs.Pos  = dfltPos;
		prefsFile.open('w');
		prefsFile.write(Prefs.toSource());
		prefsFile.close();
		}
	else{//Preferences exist so open them
		prefsFile.open('r');
		Prefs = eval(prefsFile.read());
		prefsFile.close();
		}
	
	try {
		
		function createDialog(){
		// begin dialog layout
		var DupRotateDialog = new Window('dialog');
		DupRotateDialog.text = 'Duplicate and Rotate Layer';
		DupRotateDialog.frameLocation = [78, 100];
		DupRotateDialog.alignChildren = 'center';

		DupRotateDialog.NumLayerPnl = DupRotateDialog.add('panel', [2, 2, 300, 56], 'Number of Layers and Rotation Anchor Point');
			DupRotateDialog.NumLayerPnl.add('statictext', [10, 16, 50, 48], 'Copies ');
			DupRotateDialog.NumLayerPnl.imgCpysEdt = DupRotateDialog.NumLayerPnl.add('edittext', [50, 13, 90, 34], Prefs.Cpys, {name:'imgCpys'});
			DupRotateDialog.NumLayerPnl.imgCpysEdt.helpTip = 'Number of copies of selected Layer';
			
			DupRotateDialog.NumLayerPnl.add('statictext',[96, 16, 240, 48],'Location');
			var position =['Top Left','Top Center','Top Right','Center Left','Center','Center Right','Bottom Left','Bottom Center','Bottom Right','Doc Center','Samples','Path Points'];
			DupRotateDialog.NumLayerPnl.dd1 = DupRotateDialog.NumLayerPnl.add('dropdownlist',[150, 13, 260, 34],position);
			DupRotateDialog.NumLayerPnl.dd1.selection=Prefs.Pos;
	
		var buttons = DupRotateDialog.add('group');
			buttons.orientation = 'row';
				var okBtn = buttons.add('button');
			okBtn.text = 'OK';
			okBtn.properties = {name: 'ok'};
				var cancelBtn = buttons.add('button');
			cancelBtn.text = 'Cancel';
			cancelBtn.properties = {name: 'cancel'};
		return DupRotateDialog;
		}
				
		dispdlg(createDialog());
		function dispdlg(DupRotateDialog){ 
			// display dialog and only continues on OK button press (OK = 1, Cancel = 2)
			DupRotateDialog.onShow = function() {
				var ww = DupRotateDialog.bounds.width;  
				var hh = DupRotateDialog.bounds.height;  
				DupRotateDialog.bounds.x  = 78;  
				DupRotateDialog.bounds.y  = 100;  
				DupRotateDialog.bounds.width  = ww;  
				DupRotateDialog.bounds.height  = hh;  
				}
			if (DupRotateDialog.show() == 1) {
				//variables passed from user interface
				var copies	= String(DupRotateDialog.NumLayerPnl.imgCpys.text); if (copies=="") { copies = Prefs.Cpys;}
				if (isNaN(copies)) { alert("Non numeric value entered"); dispdlg(createDialog());}
				else {
					if (copies<2 || copies>360) { alert("Number of layer allow is 2 to 360"); dispdlg(createDialog());}  // Not in range
					else {
						var AnchorPoint = Number(DupRotateDialog.NumLayerPnl.dd1.selection.index) + 1;
						cTID = function(s) { return app.charIDToTypeID(s); };
						sTID = function(s) { return app.stringIDToTypeID(s); };
						// Save the current preferences
						Prefs.Cpys  = copies;
						Prefs.Pos  = Number(DupRotateDialog.NumLayerPnl.dd1.selection.index);
						prefsFile.open('w');
						prefsFile.write(Prefs.toSource());
						prefsFile.close();
						var startRulerUnits = app.preferences.rulerUnits;
						var startTypeUnits = app.preferences.typeUnits;
						var startDisplayDialogs = app.displayDialogs;
						// Set Photoshop to use pixels and display no dialogs
						app.preferences.rulerUnits = Units.PIXELS;
						app.preferences.typeUnits = TypeUnits.PIXELS;
						app.displayDialogs = DialogModes.NO;
						app.togglePalettes();
						try { app.activeDocument.suspendHistory('RotateLayerAbout','main(copies, AnchorPoint)' );} 
						catch(e) {alert(e + ': on line ' + e.line);} 
						// Return the app preferences
						app.togglePalettes();
						app.preferences.rulerUnits = startRulerUnits;
						app.preferences.typeUnits = startTypeUnits;
						app.displayDialogs = startDisplayDialogs;
						}
					}
				}
			else {
				//alert('Operation Canceled.');
				}
			}		
		}
	catch(err){
		// Lot's of things can go wrong, Give a generic alert and see if they want the details
		if ( confirm("Sorry, something major happened and I can't continue! Would you like to see more info?" ) ) { alert(err + ': on line ' + err.line ); }
		}
	}
	
function main(stemsAmount, Position) {
	if  (  Position == 11 && app.activeDocument.colorSamplers.length==0 ) {
		alert("No Color Sampler set");
		return;
		}
	if  (  Position == 12 ) {
		var thePath = selectedPath();
		if (thePath == undefined) {
			alert("No Path Selected");
			return;
		}
		var myPathInfo = extractSubPathInfo(thePath);  
		}
	// Save selected layer to variable:
	var originalStem = app.activeDocument.activeLayer;
	// Run the copying process
	if(stemsAmount != null){ 
		// Calculate the rotation angle
		var angle = 360 / parseInt(stemsAmount);

		// Create a group for stems
		var stemsGroup = app.activeDocument.layerSets.add();
			stemsGroup.name = originalStem.name + " ("+stemsAmount+" stems)";
		// Place original layer in group
		originalStem.move(stemsGroup, ElementPlacement.INSIDE);

		// Duplicate and rotate layers:
		for(var i = 1; i < stemsAmount; i++){
			// Duplicate original layer and save it to the variable
			var newStem = originalStem.duplicate();

			// Rotate new layer				
			switch (Position){
				case 1 : newStem.rotate(angle * i, AnchorPosition.TOPLEFT); break;
				case 2 : newStem.rotate(angle * i, AnchorPosition.TOPCENTER); break;
				case 3 : newStem.rotate(angle * i, AnchorPosition.TOPRIGHT); break;
				case 4 : newStem.rotate(angle * i, AnchorPosition.MIDDLELEFT); break;
				case 5 : newStem.rotate(angle * i, AnchorPosition.MIDDLECENTER); break;
				case 6 : newStem.rotate(angle * i, AnchorPosition.MIDDLERIGHT); break;
				case 7 : newStem.rotate(angle * i, AnchorPosition.BOTTOMLEFT); break;
				case 8 : newStem.rotate(angle * i, AnchorPosition.BOTTOMCENTER); break;
				case 9 : newStem.rotate(angle * i, AnchorPosition.BOTTOMRIGHT); break;
				case 10 : app.activeDocument.activeLayer = newStem; rotateAroundPosition(angle * i,activeDocument.width/2,activeDocument.height/2); break;
				case 11 : for (var s=0,len=app.activeDocument.colorSamplers.length;s<len;s++) {
							if (s!=0) {
								// Duplicate original layer and save it to the variable
								var newStem = originalStem.duplicate();
								}
							newStem.name = originalStem.name + " " + (i+1) + " p" + (s+1) ;
							app.activeDocument.activeLayer = newStem;
							var colorSamplerRef = app.activeDocument.colorSamplers[s];
							//alert("angle=" + (angle * i) +  " ,x=" + colorSamplerRef.position[0].value + " ,y=" + colorSamplerRef.position[1].value);
							rotateAroundPosition(angle * i,colorSamplerRef.position[0].value,colorSamplerRef.position[1].value);
							newStem.move(stemsGroup, ElementPlacement.PLACEATEND);
		               		}; 
							break; 
				case 12 :	for(var k=0;k<myPathInfo.length;k++){  
								for(var j=0;j<myPathInfo[k].entireSubPath.length;j++){ 
									if (k!=0 || j!=0) {
										// Duplicate original layer and save it to the variable
										var newStem = originalStem.duplicate();
										}
									newStem.name = originalStem.name + " " + (i+1) + " p" + (j+1) ;
									app.activeDocument.activeLayer = newStem;
									rotateAroundPosition(angle * i,myPathInfo[k].entireSubPath[j].anchor[0],myPathInfo[k].entireSubPath[j].anchor[1]);
									newStem.move(stemsGroup, ElementPlacement.PLACEATEND);
									}
								}
							break;
				default : break;
				}

			// Add index to new layers
			if (Position!=11) {
				newStem.name = originalStem.name + " " + (i+1);
				// Place new layer inside stems group
				newStem.move(stemsGroup, ElementPlacement.PLACEATEND);
				}
			};

		// Add index to the original layer
		if (Position!=11) originalStem.name += " 1";
		else originalStem.name += " 1 p1";
		};
		activeDocument.activeLayer = activeDocument.layers[0]; // Target top
		var groupname = app.activeDocument.activeLayer.name // remember name of group  
		var idungroupLayersEvent = stringIDToTypeID( "ungroupLayersEvent" ); // this part from  Script Listene -- ungroup group  
		var desc14 = new ActionDescriptor();  
		var idnull = charIDToTypeID( "null" );  
		var ref13 = new ActionReference();  
		var idLyr = charIDToTypeID( "Lyr " );  
		var idOrdn = charIDToTypeID( "Ordn" );  
		var idTrgt = charIDToTypeID( "Trgt" );  
		ref13.putEnumerated( idLyr, idOrdn, idTrgt );  
		desc14.putReference( idnull, ref13 );  
		executeAction( idungroupLayersEvent, desc14, DialogModes.NO );  
		var idMk = charIDToTypeID( "Mk  " ); // this part from  Script Listene --  group selected layers  
		var desc15 = new ActionDescriptor();  
		var idnull = charIDToTypeID( "null" );  
		var ref14 = new ActionReference();  
		var idlayerSection = stringIDToTypeID( "layerSection" );  
		ref14.putClass( idlayerSection );  
		desc15.putReference( idnull, ref14 );  
		var idFrom = charIDToTypeID( "From" );  
		var ref15 = new ActionReference();  
		var idLyr = charIDToTypeID( "Lyr " );  
		var idOrdn = charIDToTypeID( "Ordn" );  
		var idTrgt = charIDToTypeID( "Trgt" );  
		ref15.putEnumerated( idLyr, idOrdn, idTrgt );  
		desc15.putReference( idFrom, ref15 );  
		executeAction( idMk, desc15, DialogModes.NO );  
		app.activeDocument.activeLayer.name = groupname // recall group name  
	}

function rotateAroundPosition(_angle,x,y) {  
    var desc1 = new ActionDescriptor();  
    var desc2 = new ActionDescriptor();  
    var ref1 = new ActionReference();  
    ref1.putEnumerated(charIDToTypeID('Lyr '), charIDToTypeID('Ordn'), charIDToTypeID('Trgt'));  
    desc1.putReference(charIDToTypeID('null'), ref1);  
    desc1.putEnumerated(charIDToTypeID('FTcs'), charIDToTypeID('QCSt'), stringIDToTypeID("QCSIndependent"));  
    desc2.putUnitDouble(charIDToTypeID('Hrzn'), charIDToTypeID('#Pxl'), x);  
    desc2.putUnitDouble(charIDToTypeID('Vrtc'), charIDToTypeID('#Pxl'), y);  
    desc1.putObject(charIDToTypeID('Pstn'), charIDToTypeID('Pnt '), desc2);  
    desc1.putUnitDouble(charIDToTypeID('Angl'), charIDToTypeID('#Ang'), _angle);  
    desc1.putEnumerated(charIDToTypeID('Intr'), charIDToTypeID('Intp'), charIDToTypeID('Bcbc'));  
    executeAction(charIDToTypeID('Trnf'), desc1, DialogModes.NO);  
	}
////// determine selected path //////
function selectedPath () {
	try {
		var ref = new ActionReference(); 
		ref.putEnumerated( charIDToTypeID("Path"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") ); 
		var desc = executeActionGet(ref);
		var theName = desc.getString(charIDToTypeID("PthN"));
		return app.activeDocument.pathItems.getByName(theName)
	}
	catch (e) {
		return undefined
	}
};
////// michael l hale’s code //////
function extractSubPathInfo(pathObj){  
    var pathArray = new Array();// each element can be used as the second arugment in pathItems.add ie doc.pathItems.add("myPath1", [pathArray[0]]);  
    var pl = pathObj.subPathItems.length;  
    for(var s=0;s<pl;s++){  
        var pArray = new Array();  
          for(var i=0;i<pathObj.subPathItems[s].pathPoints.length;i++){  
             pArray[i] = new PathPointInfo;  
             pArray[i].kind = pathObj.subPathItems[s].pathPoints[i].kind;  
             pArray[i].anchor = pathObj.subPathItems[s].pathPoints[i].anchor;  
			 //alert("Anchor " + pathObj.subPathItems[s].pathPoints[i].anchor );
             pArray[i].leftDirection = pathObj.subPathItems[s].pathPoints[i].leftDirection;  
             pArray[i].rightDirection = pathObj.subPathItems[s].pathPoints[i].rightDirection;  
          };  
        pathArray[pathArray.length] = new Array();  
        pathArray[pathArray.length - 1] = new SubPathInfo();  
        pathArray[pathArray.length - 1].operation = pathObj.subPathItems[s].operation;  
        pathArray[pathArray.length - 1].closed = pathObj.subPathItems[s].closed;  
        pathArray[pathArray.length - 1].entireSubPath = pArray;  
    };  
    return pathArray;  
}; 

 

 

 

JJMack

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Contributor ,
Mar 06, 2020 Mar 06, 2020

Copy link to clipboard

Copied

Thanks for the quick response JJMack ! The script is now 100% functional. Congratulations and thank you again

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Mar 07, 2020 Mar 07, 2020

Copy link to clipboard

Copied

There is a Bug in Photoshop Scripting I did not bother to code around in that script.  R-bin and I have reported the bug to Adobe. Adobe has even knowledge the bug. However Adobe support does not seem to want to fix the nasty bug.  I have seen Scripts posted here the fail badly when Adobe bug bite.  This  script will just fail with this message

image.png

The document should still be in  pretty good shape all you need do is back up one history state deselect and rerun the script. It will run correctly then. 

 

My bug report was made and acknowledge 5 years ago I updated it 3 month ago stating it still not fixed

 Nasty script bug 

 

R-bin reported the bug 6 years ago Adobe's  Tom Ruark  official replay was "Interesting"... 

Scripting suspendhistory 

 

Tom was also assign the job of fixing  a bug I report was introduced in CS4.  He never did the bugs are still in all versions of  Photoshop cs4 and newer.    Adobe withdraw my bug report.

 

Adobe Photoshop support is not what it should be IMO.

 

 

 

 

JJMack

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Mar 19, 2021 Mar 19, 2021

Copy link to clipboard

Copied

Hi, I'll hijack this thread a bit. I'm looking for a script that can copy, move and rotate in a spiraling/fractal manner .

Made a very crude illustration of what I mean. Is this existing somewhere? Don't really know how to script myself .

 

Would really appreciate it if someone could help me. ❤️

FractalRepeat.jpg

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Mar 19, 2021 Mar 19, 2021

Copy link to clipboard

Copied

LATEST

Users have posted Scripts to rotate layers and distribute layers along a path. Why not look at these script code and code the script you seem to want.  There are the deco scripts use in fill pattern scripts including a sprial.  If the script you want does not exists.  Code the script you want the posted scripts should help get you going. 

 

image.png

These forums are for helping users with using Adobe Products you may need to code the scipt you want if the one you have found and the one we have pointed you to do not work the way you want. 

JJMack

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines