Copy link to clipboard
Copied
Hello!
I'm wanting to rotate a number of layers around the center point of a document, not an anchor point of the layer itself. It's easy to do when doing the rotation manually by simply moving the anchor point to the center of the documnet, I can't figure out how to do this in script.
Something along the lines of:
//center of document
var center = [doc.width / 2, doc.height / 2]
//rotate layer around center point
newLyr.rotate(36, center);
Thanks!
Copy link to clipboard
Copied
Use scriptlistner to record a rotation transformation then put in a variable for figuring out the center points and angle of rotation.
var idTrnf = charIDToTypeID( "Trnf" );
var desc5 = new ActionDescriptor();
var idnull = charIDToTypeID( "null" );
var ref2 = new ActionReference();
var idPath = charIDToTypeID( "Path" );
var idOrdn = charIDToTypeID( "Ordn" );
var idTrgt = charIDToTypeID( "Trgt" );
ref2.putEnumerated( idPath, idOrdn, idTrgt );
desc5.putReference( idnull, ref2 );
var idFTcs = charIDToTypeID( "FTcs" );
var idQCSt = charIDToTypeID( "QCSt" );
var idQcsi = charIDToTypeID( "Qcsi" );
desc5.putEnumerated( idFTcs, idQCSt, idQcsi );
var idPstn = charIDToTypeID( "Pstn" );
var desc6 = new ActionDescriptor();
var idHrzn = charIDToTypeID( "Hrzn" );
var idPxl = charIDToTypeID( "#Pxl" );
desc6.putUnitDouble( idHrzn, idPxl, 688.186519 ); //put variable here for axis of rotation - horizontal
var idVrtc = charIDToTypeID( "Vrtc" );
var idPxl = charIDToTypeID( "#Pxl" );
desc6.putUnitDouble( idVrtc, idPxl, 905.398537 ); //put variable here for axis of rotation - vertical
var idPnt = charIDToTypeID( "Pnt " );
desc5.putObject( idPstn, idPnt, desc6 );
var idOfst = charIDToTypeID( "Ofst" );
var desc7 = new ActionDescriptor();
var idHrzn = charIDToTypeID( "Hrzn" );
var idPxl = charIDToTypeID( "#Pxl" );
desc7.putUnitDouble( idHrzn, idPxl, -0.000000 );
var idVrtc = charIDToTypeID( "Vrtc" );
var idPxl = charIDToTypeID( "#Pxl" );
desc7.putUnitDouble( idVrtc, idPxl, 0.000000 );
var idOfst = charIDToTypeID( "Ofst" );
desc5.putObject( idOfst, idOfst, desc7 );
var idAngl = charIDToTypeID( "Angl" );
var idAng = charIDToTypeID( "#Ang" );
desc5.putUnitDouble( idAngl, idAng, -61.516716 ); //Put variable for angle of rotation.
executeAction( idTrnf, desc5, DialogModes.NO );
Copy link to clipboard
Copied
I have only used rotate using one if the 9 anchor points as the rotation point. You may need to use Action manager code for that transform. and need to calculate the rotation point relative to the bounds of the layer and the bounds of the documents canvas. Here I have a document 600x600 px and a red layer 300x300px 1/4 over the top left canvas corner. I used Free Transform moved thy center rotation point from the center of the red layer and positioned it over the canvas center. I set the Transform angle to 180. I captured the transform operation screens. and the Script listener code for the transform. You can see the transform values in the option bar I do not understand the first X and y values when the anchor point is in the center of the red layer for its relative to the canvas 0 0 where the red layer center is.. You can see the X and Y values are the Canvas center when I moved it. In the scriptlistener code I see values near the 299 x and y was expecting to see 180 somewhere but its not there. I back up the document in history and ran the scriptlistener cod and it worked. Older versions of transform nay nit have the interpolation method included.
// =======================================================
var idTrnf = charIDToTypeID( "Trnf" );
var desc17 = new ActionDescriptor();
var idnull = charIDToTypeID( "null" );
var ref10 = new ActionReference();
var idLyr = charIDToTypeID( "Lyr " );
var idOrdn = charIDToTypeID( "Ordn" );
var idTrgt = charIDToTypeID( "Trgt" );
ref10.putEnumerated( idLyr, idOrdn, idTrgt );
desc17.putReference( idnull, ref10 );
var idFTcs = charIDToTypeID( "FTcs" );
var idQCSt = charIDToTypeID( "QCSt" );
var idQcsi = charIDToTypeID( "Qcsi" );
desc17.putEnumerated( idFTcs, idQCSt, idQcsi );
var idPstn = charIDToTypeID( "Pstn" );
var desc18 = new ActionDescriptor();
var idHrzn = charIDToTypeID( "Hrzn" );
var idPxl = charIDToTypeID( "#Pxl" );
desc18.putUnitDouble( idHrzn, idPxl, 299.000000 );
var idVrtc = charIDToTypeID( "Vrtc" );
var idPxl = charIDToTypeID( "#Pxl" );
desc18.putUnitDouble( idVrtc, idPxl, 300.500000 );
var idPnt = charIDToTypeID( "Pnt " );
desc17.putObject( idPstn, idPnt, desc18 );
var idOfst = charIDToTypeID( "Ofst" );
var desc19 = new ActionDescriptor();
var idHrzn = charIDToTypeID( "Hrzn" );
var idPxl = charIDToTypeID( "#Pxl" );
desc19.putUnitDouble( idHrzn, idPxl, -0.000000 );
var idVrtc = charIDToTypeID( "Vrtc" );
var idPxl = charIDToTypeID( "#Pxl" );
desc19.putUnitDouble( idVrtc, idPxl, 0.000000 );
var idOfst = charIDToTypeID( "Ofst" );
desc17.putObject( idOfst, idOfst, desc19 );
var idWdth = charIDToTypeID( "Wdth" );
var idPrc = charIDToTypeID( "#Prc" );
desc17.putUnitDouble( idWdth, idPrc, -100.000000 );
var idHght = charIDToTypeID( "Hght" );
var idPrc = charIDToTypeID( "#Prc" );
desc17.putUnitDouble( idHght, idPrc, -100.000000 );
var idIntr = charIDToTypeID( "Intr" );
var idIntp = charIDToTypeID( "Intp" );
var idbicubicSmoother = stringIDToTypeID( "bicubicSmoother" );
desc17.putEnumerated( idIntr, idIntp, idbicubicSmoother );
executeAction( idTrnf, desc17, DialogModes.NO );
Copy link to clipboard
Copied
rotateAroundDocCenter(35);
function rotateAroundDocCenter(_angle) {
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'), activeDocument.width / 2);
desc2.putUnitDouble(charIDToTypeID('Vrtc'), charIDToTypeID('#Pxl'), activeDocument.height / 2);
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);
}
Copy link to clipboard
Copied
Thank You quite readable for Action manager code.
Added that code to my layer rotating toy that duplicates the targeted layer a request number of times in the range of 2 to 360 rotating the layers about one of its 9 anchor points for a 360 spread. Mot there is a 10th anchor point the Documents center Thanks again.
http://www.mouseprints.net/old/dpr/RotateLayerAbout.jsx
// 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 = [70, 70];
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'];
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)
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) {};
// 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) {
// 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
//var Position = 5;
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; rotateAroundDocCenter(angle * i); break;
default : break;
}
// Add index to new layers
newStem.name = originalStem.name + " " + (i+1);
// Place new layer inside stems group
newStem.move(stemsGroup, ElementPlacement.PLACEATEND);
};
// Add index to the original layer
originalStem.name += " 1";
};
}
function rotateAroundDocCenter(_angle) {
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'), activeDocument.width / 2);
desc2.putUnitDouble(charIDToTypeID('Vrtc'), charIDToTypeID('#Pxl'), activeDocument.height / 2);
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);
}