9 Replies Latest reply on Jun 16, 2014 6:23 AM by anp12

    adobe script for rotation and position

    anp12

      I am new to adobe script and actions (very new. like starting today, right now).

      First I just want to know if what I'm trying to do it even possible.

       

      Imagine a simple rectangle in photoshop.

      I have a table of angles and coordinates (could be an an excel file or any kind of text file). let's say 10 rows. column A = angles and columns B and C are x and y coordinates, respectively.

      I want to somehow have photoshop read this list, and make 10 layers that have the rectangle at the position and angle specified by each row of the table.

       

      then, I want a timeline with 10 frames, each one having only the appropriate, sequential layer visible.

       

      Is that possible?

       

      If so, does anyone have any suggestions. I've never written script in adobe, but do have some programming experience in other oldschool languages.

      and maybe a link that explain how to use the script once it's written?

       

      thanks

        • 1. Re: adobe script for rotation and position
          anp12 Level 1

          ok, so I've gotten this far. Rotating and moving layers seems easy enough. Soon I'll figure out how to copy layers.

           

          var doc=app.activeDocument

          var rectangleLayer= doc.artLayers.getByName ("rectangle")

          var myAnchor = rectangleLayer.anchor

           

          doc.activeLayer=rectangleLayer

          rectangleLayer.rotate (36, mouseAnchor) /*rotate 36 degrees*/

          MoveLayer(mouseLayer,200,200)         /* move to (200,200), based on the rulers. in my case, pixels */

           

          function MoveLayer(fLayer,fX,fY) {

            var Position = fLayer.bounds;

            Position[0] = fX - Position[0];

            Position[1] = fY - Position[1];

            fLayer.translate(-Position[0],-Position[1]);

          }

           

           

          But, I'm still not sure how to import the values for the positions and the angles

          • 2. Re: adobe script for rotation and position
            c.pfaffenbichler Level 9

            It is not so good to provide the first post in a thread one has started oneself. Edit: At least that’s my opinion on this issue.

            The Forum has been made worse recently in some regards, one of which makes it less easy to notice that the OP has posted a reply and not someone else.

             

            Anyways, maybe this helps.

            It uses and array or arrays of the basis of the transformation of the active layer.

            // 2014, use it at your own risk;

            #target photoshop

            if (app.documents.length > 0) {

            var originalRulerUnits = app.preferences.rulerUnits;

            app.preferences.rulerUnits = Units.PIXELS;

            var myDocument = app.activeDocument;

            var theLayer = smartify2010 (myDocument.activeLayer);

            var theW = theLayer.bounds[2] - theLayer.bounds[0];

            var theH = theLayer.bounds[3] - theLayer.bounds[1];

            var theCenter = [theLayer.bounds[0] + theW/2, theLayer.bounds[1] + theH/2];

            var theValues = [[0, 0, 15], [100, 100, 30], [300, 300, 45]];

            for (var m = 0; m < theValues.length; m++) {

            myDocument.activeLayer = theLayer;

            duplicateMoveRotateScale (theValues[m][0] - Number(theCenter[0]), theValues[m][1] - Number(theCenter[1]), 100, 100, theValues[m][2]);

            };

            app.preferences.rulerUnits = originalRulerUnits;

            };

            ////// duplicate and transform layer //////

            function duplicateMoveRotateScale (theX, theY, theScaleX, theScaleY, theRotation) {

            try{

            // =======================================================

            var idTrnf = charIDToTypeID( "Trnf" );

                var desc10 = new ActionDescriptor();

                var idnull = charIDToTypeID( "null" );

                    var ref6 = new ActionReference();

                    var idLyr = charIDToTypeID( "Lyr " );

                    var idOrdn = charIDToTypeID( "Ordn" );

                    var idTrgt = charIDToTypeID( "Trgt" );

                    ref6.putEnumerated( idLyr, idOrdn, idTrgt );

                desc10.putReference( idnull, ref6 );

                var idFTcs = charIDToTypeID( "FTcs" );

                var idQCSt = charIDToTypeID( "QCSt" );

                var idQcsa = charIDToTypeID( "Qcsa" );

                desc10.putEnumerated( idFTcs, idQCSt, idQcsa );

                var idOfst = charIDToTypeID( "Ofst" );

                    var desc11 = new ActionDescriptor();

                    var idHrzn = charIDToTypeID( "Hrzn" );

                    var idPxl = charIDToTypeID( "#Pxl" );

                    desc11.putUnitDouble( idHrzn, idPxl, theX );

                    var idVrtc = charIDToTypeID( "Vrtc" );

                    var idPxl = charIDToTypeID( "#Pxl" );

                    desc11.putUnitDouble( idVrtc, idPxl, theY );

                var idOfst = charIDToTypeID( "Ofst" );

                desc10.putObject( idOfst, idOfst, desc11 );

                var idWdth = charIDToTypeID( "Wdth" );

                var idPrc = charIDToTypeID( "#Prc" );

                desc10.putUnitDouble( idWdth, idPrc, theScaleX );

                var idHght = charIDToTypeID( "Hght" );

                var idPrc = charIDToTypeID( "#Prc" );

                desc10.putUnitDouble( idHght, idPrc, theScaleY );

                var idAngl = charIDToTypeID( "Angl" );

                var idAng = charIDToTypeID( "#Ang" );

                desc10.putUnitDouble( idAngl, idAng, theRotation );

                var idIntr = charIDToTypeID( "Intr" );

                var idIntp = charIDToTypeID( "Intp" );

                var idbicubicAutomatic = stringIDToTypeID( "bicubicAutomatic" );

                desc10.putEnumerated( idIntr, idIntp, idbicubicAutomatic );

                var idCpy = charIDToTypeID( "Cpy " );

                desc10.putBoolean( idCpy, true );

            executeAction( idTrnf, desc10, DialogModes.NO );

            } catch (e) {}

            };

            ////// function to smartify if not //////

            function smartify2010 (theLayer) {

            // make layers smart objects if they are not already;

              app.activeDocument.activeLayer = theLayer;

            // process pixel-layers and groups;

                  if (theLayer.kind == "LayerKind.GRADIENTFILL" || theLayer.kind == "LayerKind.LAYER3D" || theLayer.kind == "LayerKind.NORMAL" ||

                  theLayer.kind == "LayerKind.PATTERNFILL" || theLayer.kind == "LayerKind.SOLIDFILL" ||

                  theLayer.kind == "LayerKind.TEXT" || theLayer.kind == "LayerKind.VIDEO" || theLayer.typename == "LayerSet") {

              var id557 = charIDToTypeID( "slct" );

              var desc108 = new ActionDescriptor();

              var id558 = charIDToTypeID( "null" );

              var ref77 = new ActionReference();

              var id559 = charIDToTypeID( "Mn  " );

              var id560 = charIDToTypeID( "MnIt" );

              var id561 = stringIDToTypeID( "newPlacedLayer" );

              ref77.putEnumerated( id559, id560, id561 );

              desc108.putReference( id558, ref77 );

              executeAction( id557, desc108, DialogModes.NO )

              return app.activeDocument.activeLayer

              }

              if (theLayer.kind == LayerKind.SMARTOBJECT || theLayer.kind == "LayerKind.VIDEO") {return theLayer};

              };

            • 3. Re: adobe script for rotation and position
              Ghoulfool Level 1

              Reading in a text file is straight forward:

               

               

              var dataPath = "C:\\temp";
              var list = "myTextFile.txt";
              
              // read the master array and put it to an array
              var textArray = readFile(dataPath, list);
              alert(textArray[0]);
              
              function readFile(inPath, inFile)
              {
                  //read in file 
                  var theFile = new File(inPath + "/" + inFile);
              
                  // declare new empty array
                  var myArray = new Array();
              
                  var textFile = new File(theFile);
              
                  // read the file
                  textFile.open('r');
              
                  while(!textFile.eof)
                  {
                    var line = textFile.readln();
                    if (line != null && line.length >0)
                    {
                      myArray.push(line);
                    }
                  }
                  // close the file
                  textFile.close();
                  return myArray
              }
              
              • 4. Re: adobe script for rotation and position
                c.pfaffenbichler Level 9

                What is the content of the text file exactly?

                • 5. Re: adobe script for rotation and position
                  c.pfaffenbichler Level 9
                  Rotating and moving layers seems easy enough. Soon I'll figure out how to copy layers.

                  In ESTK’s Help > Object Model Viewer you can check the Properties and Methods for the various objects and what arguments the Methods take.

                  »duplicate« would be the one you seem to be looking for.

                  estkObjectModelViewerDuplicate.jpg

                   

                  But doing this via the DOM and in three steps (duplicate, translate, rotate) seems likely to take longer than doing it in one operation with Action Manager code.

                  • 6. Re: adobe script for rotation and position
                    anp12 Level 1

                    Thank you for the tips.

                     

                    So far I have been able to do basically what I need to do.

                    I have an xml file that has xy coordinates.

                    I have a layer with a circle.

                    I have successfully made a script that reads the xml file, duplicates the circle layer, names it 'nextcircle' + a number, moves it to the 'circles' group of layers, and then moves it to the correct xy location, loped for the number of coordinates. Right now I'm skipping the rotating because I'm practicing with a circle. After I get this done I'll try an ellipse add rotation angles to each pair of coordinates. I think I can handle that at this point.

                     

                    But, I want to set up a timeline of frames and I can't seem to find any documentation about accessing the timeline in script.

                    Here's what i want to do. make a time line in with each of my layers in sequentially visible. So, in frame 1, only nextcircle1 is visible, in frame 2 only nextcircle2 is visible. etc.

                     

                    Here is my code. There's probably a better way, but this is working mostly (although in reality I have to break it up into 10 coordinates at a time so that my photoshop didn't crash)

                     

                    var doc=app.activeDocument

                    var circleLayer= doc.artLayers.getByName ("circle") //my circle that I will move around

                    var cLayer=[];

                    var baseName= "nextcircle" // the name for each duplicated layer

                    doc.activeLayer=circleLayer 

                    var circleSet = doc.layerSets.getByName ("circles"); I have a layer group called circles in which i will put each new layer

                     

                    var f = new File('C:/Users/[me]/Documents/Adobe Scripts/path.xml')  // my xml file with coordinates for my circle to travel

                    f.open('r')

                    var pathxml = new XML(f.read())

                    f.close()

                     

                    pathLen=pathxml.circlex.length() // gets the number of coordinates (

                     

                    for (var i =1; i <=pathLen; i++){  // loops through the coordinate list

                        var nm= baseName.concat(i.toString()); // name of new layer

                        cLayer[i]=circleLayer.duplicate (doc, ElementPlacement.PLACEATBEGINNING) //duplicates my circle

                            with(cLayer[i]) {

                                name = nm  // names it

                                }

                         cLayer[i].moveToEnd(circleSet)  // moves the new layer to the top of the circles group

                         var posx = Number(pathxml.circlex[i-1])  //extracts the x pos for the ith-1 value

                         var posy = Number(pathxml.circley[i-1])  //extracts the y pos for the ith-1 value

                         MoveLayerTo(cLayer[i],posx,posy)  //moves to the new location (I copied this function from somewhere)

                         }

                     

                     

                    function MoveLayerTo(fLayer,fX,fY) {

                     

                      var Position = fLayer.bounds;

                      Position[0] = fX - Position[0];

                      Position[1] = fY - Position[1];

                     

                      fLayer.translate(-Position[0],-Position[1]);

                    }

                    • 7. Re: adobe script for rotation and position
                      c.pfaffenbichler Level 9

                      But, I want to set up a timeline of frames and I can't seem to find any documentation about accessing the timeline in script.

                      You probably have to use Action Manger code (as recorded with ScriptingListener.plugin).

                      But to make it easy on yourself you might want to abandon the Group and all other non-animation Layers to be able to use »Make Frames From Layers«.

                      • 8. Re: Re: adobe script for rotation and position
                        c.pfaffenbichler Level 9

                        This would create a frame animated based on the Layers inside the topmost LayerSet.

                        It assumes that the file does not have animation yet.

                        // 2014, use it at your own risk;
                        #target photoshop
                        if (app.documents.length > 0) {
                        var myDocument = app.activeDocument;
                        // define the layers;
                        var theLayers = myDocument.layerSets[0].layers;
                        // hide all except topmost layer;
                        hideOthers (theLayers[0], myDocument);
                        // make frame animation;
                        // =======================================================
                        var idmakeFrameAnimation = stringIDToTypeID( "makeFrameAnimation" );
                        executeAction( idmakeFrameAnimation, undefined, DialogModes.NO );
                        // set frame rate;
                        // =======================================================
                        var idsetd = charIDToTypeID( "setd" );
                            var desc10 = new ActionDescriptor();
                            var idnull = charIDToTypeID( "null" );
                                var ref9 = new ActionReference();
                                var idanimationFrameClass = stringIDToTypeID( "animationFrameClass" );
                                var idOrdn = charIDToTypeID( "Ordn" );
                                var idTrgt = charIDToTypeID( "Trgt" );
                                ref9.putEnumerated( idanimationFrameClass, idOrdn, idTrgt );
                            desc10.putReference( idnull, ref9 );
                            var idT = charIDToTypeID( "T  " );
                                var desc11 = new ActionDescriptor();
                                var idanimationFrameDelay = stringIDToTypeID( "animationFrameDelay" );
                                desc11.putDouble( idanimationFrameDelay, 0.100000 );
                            var idanimationFrameClass = stringIDToTypeID( "animationFrameClass" );
                            desc10.putObject( idT, idanimationFrameClass, desc11 );
                        executeAction( idsetd, desc10, DialogModes.NO );
                        // work through layers;
                        for (var m = 1; m < theLayers.length; m++) {
                        // =======================================================
                        var idDplc = charIDToTypeID( "Dplc" );
                            var desc7 = new ActionDescriptor();
                            var idnull = charIDToTypeID( "null" );
                                var ref6 = new ActionReference();
                                var idanimationFrameClass = stringIDToTypeID( "animationFrameClass" );
                                var idOrdn = charIDToTypeID( "Ordn" );
                                var idTrgt = charIDToTypeID( "Trgt" );
                                ref6.putEnumerated( idanimationFrameClass, idOrdn, idTrgt );
                            desc7.putReference( idnull, ref6 );
                        executeAction( idDplc, desc7, DialogModes.NO );
                        // hide others;
                        hideOthers (myDocument.activeLayer, myDocument);
                        hideOthers (theLayers[m], myDocument);
                        };
                        };
                        ////// toggle visibility of others //////
                        function hideOthers (theLayer, myDocument) {
                        theLayer.visible = true;
                        myDocument.activeLayer = theLayer;
                        // =======================================================
                        var idShw = charIDToTypeID( "Shw " );
                            var desc10 = new ActionDescriptor();
                            var idnull = charIDToTypeID( "null" );
                                var list4 = new ActionList();
                                    var ref7 = new ActionReference();
                                    var idLyr = charIDToTypeID( "Lyr " );
                                    var idOrdn = charIDToTypeID( "Ordn" );
                                    var idTrgt = charIDToTypeID( "Trgt" );
                                    ref7.putEnumerated( idLyr, idOrdn, idTrgt );
                                list4.putReference( ref7 );
                            desc10.putList( idnull, list4 );
                            var idTglO = charIDToTypeID( "TglO" );
                            desc10.putBoolean( idTglO, true );
                        executeAction( idShw, desc10, DialogModes.NO );
                        };
                        
                        
                        • 9. Re: Re: adobe script for rotation and position
                          anp12 Level 1

                          thanks. I just did something similar using the scriptlistener,

                          everything is done now. very happy